Exoplayer - 视频永远达不到 STATE_READY
Exoplayer - video never reaches STATE_READY
我目前使用 exoplayer 只是为了在 surfaceview (http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_50mb.mp4) 上播放示例视频,方法是执行以下设置:
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);
我正在记录 exoplayerstate 的侦听器:
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.i("exoplayerstate","onPlayerStateChanged"+" "+playWhenReady+ " "+playbackState);
}
结果为:
exoplayerstate: onPlayerStateChanged true 1
exoplayerstate: onPlayerStateChanged true 2
exoplayerstate: onPlayerStateChanged true 3
exoplayerstate: onPlayerStateChanged true 3
通过查看 exoplayer 文档,状态代码为:
STATE_IDLE = 1; STATE_PREPARING = 2; STATE_BUFFERING = 3; STATE_READY = 4; STATE_ENDED = 5;
顺便说一下,我不认为相关,但是,我的 xml 观点是:
<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>
谁能告诉我为什么我从来没有达到状态 = 4 (STATE_READY) 以便视频可以开始播放?
两个观察结果:
DefaultAllocator()
的参数是缓冲区中段的大小(以字节为单位)。 片段 指的是您要流式传输的媒体文件的一部分。通过将其设置为 1,您的流式缓冲区将设置为 1 个字节。因此,ExoPlayer 尝试一次一个字节地下载和播放 MP4 文件,因此,需要 long 时间才能达到 READY 状态。
将段大小(参数为 DefaultAllocator()
)设置为较大的值,例如 64*1024,如示例代码中所示。
类似地,ExtractorSampleSource()
的第四个参数决定了下载缓冲区的大小(以字节为单位)。它还需要设置为一个更大的值,比如示例代码中的 256*64*1024。最后,我建议通过省略此函数的第五个参数来使用默认提取器(即不传递 null
)。
我目前使用 exoplayer 只是为了在 surfaceview (http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_50mb.mp4) 上播放示例视频,方法是执行以下设置:
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);
我正在记录 exoplayerstate 的侦听器:
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.i("exoplayerstate","onPlayerStateChanged"+" "+playWhenReady+ " "+playbackState);
}
结果为:
exoplayerstate: onPlayerStateChanged true 1
exoplayerstate: onPlayerStateChanged true 2
exoplayerstate: onPlayerStateChanged true 3
exoplayerstate: onPlayerStateChanged true 3
通过查看 exoplayer 文档,状态代码为:
STATE_IDLE = 1; STATE_PREPARING = 2; STATE_BUFFERING = 3; STATE_READY = 4; STATE_ENDED = 5;
顺便说一下,我不认为相关,但是,我的 xml 观点是:
<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>
谁能告诉我为什么我从来没有达到状态 = 4 (STATE_READY) 以便视频可以开始播放?
两个观察结果:
DefaultAllocator()
的参数是缓冲区中段的大小(以字节为单位)。 片段 指的是您要流式传输的媒体文件的一部分。通过将其设置为 1,您的流式缓冲区将设置为 1 个字节。因此,ExoPlayer 尝试一次一个字节地下载和播放 MP4 文件,因此,需要 long 时间才能达到 READY 状态。 将段大小(参数为DefaultAllocator()
)设置为较大的值,例如 64*1024,如示例代码中所示。类似地,
ExtractorSampleSource()
的第四个参数决定了下载缓冲区的大小(以字节为单位)。它还需要设置为一个更大的值,比如示例代码中的 256*64*1024。最后,我建议通过省略此函数的第五个参数来使用默认提取器(即不传递null
)。