Exoplayer引发Android中大型mp4文件的解码器初始化异常

use*_*215 6 android decoder exoplayer

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

com.google.android.exoplayer.MediaCodecTrackRenderer $ DecoderInitializationException:解码器初始化失败:OMX.amlogic.avc.decoder.awesome,MediaFormat(video / 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);
}
Run Code Online (Sandbox Code Playgroud)

这是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");
}
Run Code Online (Sandbox Code Playgroud)

小智 6

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

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

您可能要检查在停止播放第一个视频并开始播放列表中下一个视频时是否确实调用了该方法。

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

此外,如果在销毁解码器时未释放专用视频内存,由​​于泄漏,您将在几个视频播放会话中耗尽平台上可用的有限视频内存。

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

希望我的高级建议对您找出问题有用。祝好运!!!。