ExoPlayer不再播放,停留在Player.STATE_BUFFERING

时间:2019-03-21 09:31:12

标签: android video exoplayer2.x

我当前正在创建一个应用程序,该应用程序从API获取视频列表,然后使用ExoPlayer顺序播放。昨天,一切正常,但现在我无法播放视频。播放器尝试播放视频,但卡在缓冲状态。

为了确保我们服务器上的视频不是我的应用无法正常运行的原因,我在线查找了一个mp4视频示例,并发现this。它仍然没有播放。其他SO问题的答案也不起作用。

这是我用于初始化ExoPlayer的代码。如果您需要这些信息,我正在使用PlayerView

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);
    }
}

这是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) {

    }
};

这是我用来更改视频播放的代码。从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++;
}

这是播放视频流的代码。

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;

}

onStop()onDestroy()中,我将此代码称为释放播放器。

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

如果需要,这是我的build.gradle(app)。

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'
}

更新:

今天,我尝试使用startStream方法直接播放视频,并且播放了示例mp4视频和来自我们服务器的视频。

这是我用于获取本地视频API的代码。由于某些原因,如果我使用该方法播放视频,它将无法播放,但直接使用startStream()可以播放视频。

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);
}

更新:

您好,我又问了一个here问题,关于Volley有时如何无法正常工作,[有点怪异]影响ExoPlayer停留在BUFFERING状态。如果您想了解更多信息,请查看另一个问题,因为我不想重复我在此处发布的所有内容。

0 个答案:

没有答案