Search code examples
androidvideo-streamingsurfaceviewandroid-video-playerexoplayer

Exoplayer - video never reaches STATE_READY


I'm currently using exoplayer just to play a sample video on a surfaceview (http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_50mb.mp4) by permorming this settings:

player = (SurfaceView)rootView.findViewById(R.id.player_surface_view);



    Allocator a = new DefaultAllocator(1);
    DataSource ds = new DefaultUriDataSource(getActivity(),"a");
    SampleSource sampleSource = new ExtractorSampleSource(Uri.parse("http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_50mb.mp4"), ds, a,1,null);
    MediaCodecSelector mcs = MediaCodecSelector.DEFAULT;

    //VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING or VIDEO_SCALING_MODE_SCALE_TO_FIT
    TrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(getActivity(),sampleSource,mcs, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
    TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,mcs);

    exoPlayer = ExoPlayer.Factory.newInstance(2,10000,50000);
    exoPlayer.prepare(videoRenderer, audioRenderer);
    exoPlayer.addListener(this);
    exoPlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, player.getHolder().getSurface());
    exoPlayer.setPlayWhenReady(true);

On the listener I'm logging the exoplayerstate:

 @Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    Log.i("exoplayerstate","onPlayerStateChanged"+" "+playWhenReady+ " "+playbackState);
}

Being the result:

exoplayerstate: onPlayerStateChanged true 1

exoplayerstate: onPlayerStateChanged true 2

exoplayerstate: onPlayerStateChanged true 3

exoplayerstate: onPlayerStateChanged true 3

By reviewing the exoplayer doc, the state codes are :

STATE_IDLE = 1; STATE_PREPARING = 2; STATE_BUFFERING = 3; STATE_READY = 4; STATE_ENDED = 5;

By the way, I don't think is related but, my xml for the view is:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.exoplayer.AspectRatioFrameLayout
    android:id="@+id/video_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center">

    <SurfaceView
        android:id="@+id/player_surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"/>

</com.google.android.exoplayer.AspectRatioFrameLayout>

Can anyone tell me why I never reach the state = 4 (STATE_READY) so that the video can start playing?


Solution

  • Two observations:

    • The parameter to DefaultAllocator() is the size of segment in the buffer (in bytes). Segment refers to a portion of the media file you'd like to stream. By setting it to 1, your streaming buffer is set to 1 byte. Therefore, ExoPlayer is trying to download and play the MP4 file one byte at a time and, thus, it will take a long time to reach the READY state. Set the segment size (parameter to DefaultAllocator()) to a larger value, say 64*1024, as in the sample code.

    • Similarly, the fourth parameter to ExtractorSampleSource() determines the download buffer size (in bytes). It also needs to be set to a larger value, say 256*64*1024, as in the sample code. Finally, I suggest to use the default extractor by omitting the fifth parameter to this function (that is, do not pass null).