ExoPlayer not playing anymore, stuck on Player.STATE_BUFFERING

ぐ巨炮叔叔 提交于 2020-01-16 18:11:52

问题


I'm currently creating an app that gets a list of video from an API then plays them sequentially using ExoPlayer. Yesterday, everything is working fine but now I can't play the videos. The player tries to play the video but gets stuck in buffering state.

To make sure that the videos on our server is not the reason that my app is not working, I looked for a sample mp4 video online and found this. It still didn't play. The answers on the other SO questions didn't work either.

This are the codes I use for initializing ExoPlayer. I'm using PlayerView if you guys need that info.

private void initializePlayer() {
    if (exoPlayer == null) {
        mainHandler = new Handler();
        bandwidthMeter = new DefaultBandwidthMeter();
        trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        LoadControl loadControl = new DefaultLoadControl();

        exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
        playerView.setPlayer(exoPlayer);

        exoPlayer.addListener(exoPlayEventListener);
    }
}

This is the code for EventListener.

Player.EventListener exoPlayEventListener = new Player.EventListener() {
    @Override
    public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        switch (playbackState){
            case Player.DISCONTINUITY_REASON_PERIOD_TRANSITION:
                Log.d(TAG, "eventListen onPlayerStateChanged DISCONTINUITY_REASON_PERIOD_TRANSITION");
                break;
            case Player.STATE_BUFFERING:
                Log.d(TAG, "Buffering . . . .");
                break;
            case Player.STATE_READY:
                Log.d(TAG, "Ready!!!");
                break;
            case Player.STATE_ENDED:
                Log.d(TAG, "player ended");
                playLoopVideo();
                break;

        }
    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        switch (error.type) {
            case ExoPlaybackException.TYPE_SOURCE:
                Log.d(TAG, "ERR TYPE_SOURCE: " + error.getSourceException().getMessage());
                playLoopVideo();
                break;

            case ExoPlaybackException.TYPE_RENDERER:
                Log.d(TAG, "ERR TYPE_RENDERER: " + error.getRendererException().getMessage());
                playLoopVideo();
                break;

            case ExoPlaybackException.TYPE_UNEXPECTED:
                Log.d(TAG, "ERR TYPE_UNEXPECTED: " + error.getUnexpectedException().getMessage());
                playLoopVideo();
                break;
        }
    }

    @Override
    public void onPositionDiscontinuity(int reason) {
        if (reason == Player.DISCONTINUITY_REASON_PERIOD_TRANSITION) {

        }
    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }
};

This is the code I use for changing the video to play. I call this after I get my video list from the API.

private void playLoopVideo() {
    toPlayVidIndex = playedVidIndex;
    String toPlayVidURL = "";

    if(playedVidIndex == 7 && !isDefaultPlayed){
        toPlayVidURL = defaultUrl;
        playedVidIndex--;
        isDefaultPlayed = true;
    }else{
        if (playedVidIndex >= vidArrLst.size()){
            playedVidIndex = 0;
            toPlayVidIndex = playedVidIndex;
        }

        toPlayVidURL = vidArrLst.get(toPlayVidIndex).getUrl();
        isDefaultPlayed = false;
    }

    startStream(toPlayVidURL);
    playedVidIndex++;
}

This is the code for playing the video stream.

private void startStream(String streamLink){
    Uri mediaUri = Uri.parse(streamLink);

    DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(ctx.getApplicationContext(),
            Util.getUserAgent(ctx.getApplicationContext(),
                    "Streamer"), defaultBandwidthMeter);
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
    MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(mediaUri);

    exoPlayer.setPlayWhenReady(true);
    exoPlayer.prepare(mediaSource, true, false);

    currentStreamMediaSource = mediaSource;

}

In onStop() and onDestroy(), I call this code for releasing the player.

private void releasePlayer() {
    if (exoPlayer != null) {
        playbackPosition = exoPlayer.getCurrentPosition();
        currentWindow = exoPlayer.getCurrentWindowIndex();
        playWhenReady = exoPlayer.getPlayWhenReady();
        exoPlayer.release();
        exoPlayer = null;
    }
}

This is my build.gradle(app) if you need it.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "biz.net.com.streamer"
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
    implementation 'com.android.volley:volley:1.1.1'
}

UPDATE:

Today, I tried to directly play a video using my startStream method and it played the sample mp4 video and a video from our server.

This the code I use for getting our local video API. For some reason, if I play the videos inside that method it won't play but directly using startStream() plays the videos.

public void getVideoAds(String serverURL){
    String url = "http://"+serverURL+"/video/";

    StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d(TAG, "getVidAds res: "+response);
            try {
                JSONObject jsonObj = new JSONObject(response);
                JSONObject defaultObj = jsonObj.getJSONObject("default");
                JSONArray videoObj = jsonObj.getJSONArray("videos");

                defaultUrl = defaultObj.getString("url");

                for (int i = 0; i < videoObj.length(); i++){
                    JSONObject video = videoObj.getJSONObject(i);

                    VideoAd v = new VideoAd();
                    v.setName(getVideoNameFromLink(video.getString("url")));
                    v.setUrl(video.getString("url"));
                    v.setVideoId(video.getInt("id"));
                    v.setVersion(video.getInt("version"));
                    v.setLocalPath("");

                    vidArrLst.add(v);
                }

                playLoopVideo();
            } catch (Exception e) {

            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d(TAG, "getVidAds err: " + error.getMessage());
        }
    });

    queue.add(stringRequest);
}

UPDATE:

Hi, I made another SO question here about how Volley sometimes doesn't work properly and [a bit weird] affects ExoPlayer to be stuck on a BUFFERING state. If you want to know more, please look at the other question because I don't want to repeat everything I posted there here.

来源:https://stackoverflow.com/questions/55277277/exoplayer-not-playing-anymore-stuck-on-player-state-buffering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!