android - Exoplayer 为 android 中的大型 mp4 文件抛出解码器初始化异常

标签 android decoder exoplayer

我正在使用 Exoplayer 在 android 中连续播放视频作为播放列表。当我播放低质量的 mp4 视频时它工作正常但是当我在播放列表中播放一个或两个视频后尝试播放更高质量的 mp4 视频时屏幕不显示任何内容并且日志给出以下异常

com.google.android.exoplayer.MediaCodecTrackRenderer$DecoderInitializationException:解码器初始化失败:OMX.amlogic.avc.decoder.awesome,MediaFormat(视频/avc,198826,1920,1080,-1.0,-1,-1, -1, -1, -1)

即使我在第一次播放相同的高质量视频时循环播放,然后第二次抛出此异常。当视频大小超过 80mb 时会抛出此异常。是否存在缓冲区大小问题?有人可以指导我吗?非常感谢你

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adplayertexture);   
    AdplayerTexture=(TextureView)findViewById(R.id.AdPlayerTexture);
    AdplayerTexture.setBackgroundColor(Color.BLACK);
        AdplayerTexture.setSurfaceTextureListener(this);
  }
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
    int height) {

 AdPlayerSurface = new Surface( surface); 
 playMedia(AdPlayerSurface);
}


private void playMedia(Surface surface){
mediaplayer=new ExoPlayer();
mediaplayer.play(this,Videopathlist[CurrentVideoIndex],surface;
 mediaplayer.addListener(this);   
   }

@Override
public void onStateChanged(boolean playWhenReady, int playbackState) {

if (playbackState == ExoPlayer.STATE_ENDED) {
//releasing the resources   
    mediaplayer.DestroyPlayer();
AdPlayerSurface.release();

AdPlayerSurface=new Surface(AdplayerTexture.getSurfaceTexture());
    CurrentVideoIndex++;
playMedia(AdPlayerSurface);
}

这是 root2mediaplayer 类中的函数 play()

public void playMedia(Activity playerActivity,String mediapath,final long Position,Surface mediasurface){
    String Systemroot = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
try{
    File myFile=new File(Systemroot + java.io.File.separator + "Videos"
            + java.io.File.separator
            + mediapath);
    Uri uri = Uri.fromFile(myFile);
    final int numRenderers = 2;

    SampleSource sampleSource = 
            new FrameworkSampleSource(playerActivity, uri, /* headers */ null, numRenderers);

    // Build the track renderers
    TrackRenderer    videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);

    TrackRenderer    audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

    // Build the ExoPlayer and start playback
    MoviePlayer = ExoPlayer.Factory.newInstance(numRenderers);
    MoviePlayer.prepare(videoRenderer, audioRenderer);

    MoviePlayer.addListener(this);
    // Pass the surface to the video renderer.
    MoviePlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, mediasurface);

            MoviePlayer.seekTo(Position);
            MoviePlayer.setPlayWhenReady(true);
}catch(Exception e){

e.printStackTrace();
FileLog("exception in mediaplayer");
}

最佳答案

在不查看您的完整代码并且不知道您看到哪个设备/平台的情况下(尽管从您的问题来看它看起来像是来自 AMLOGIC 的硬件平台),我只能猜测可能是您没有释放 MediaCodec 资源当播放结束和/或您切换播放新视频时,在您的播放器中。

MediaCodec 在 https://github.com/google/ExoPlayer/blob/master/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java 的 releaseCodec() API 中发布.

您可能想检查当您停止播放第一个视频并开始播放播放列表中的下一个视频时是否确实调用了它。

通常,所有高端移动平台都有基于硬件的解码器,这些解码器使用系统上有限的专用视频内存(只能由硬件解码器访问)来解码帧。在某些平台上,如果系统中的某些其他应用程序(或同一应用程序)创建了同一基于硬件的解码器的另一个实例,并且在它进入后台时未释放它(在 Activity 中),则您将无法创建解码器生命周期语言,onStop 等)。

此外,如果解码器被销毁时专用显存没有释放,您将由于泄漏而在几个视频播放 session 中耗尽平台上可用的有限显存。

当您创建和销毁 MediaCodec 实例(或者在您的情况下,停止并开始播放播放列表中的下一个视频)时,请注意完整的平台 adb 日志。这可能会给您一些线索。

希望我的高级建议对您解决问题有所帮助。祝你好运!

关于android - Exoplayer 为 android 中的大型 mp4 文件抛出解码器初始化异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28278019/

相关文章:

minSdkVersion ="10"时Android白图不白

opencv - 使用 ffmpeg、OpenCV 的硬件加速 h264 解码

java - Android MediaCodec 如何创建解码器?

java - Android Exoplayer音频播放异常

android - 不推荐使用 SimpleExoPlayer.Builder(this).build()

android - 窗口已经聚焦 - 忽略 com.android.internal.view 的聚焦增益

java - 如何在 JAVA 中解析 JSONObjects 的 JSONArray?

android - 在 Android 上使用 PayPal SDK 有限制吗?

android - 根据 exoplayer 演示应用程序中视频的纵横比更改表面 View 的纵横比