7

Exoplayer を使用して、android でビデオをプレイリストとして継続的に再生しています。低品質の mp4 ビデオを再生すると正常に動作しますが、プレイリストで 1 つまたは 2 つのビデオを再生した後に高品質の 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)

同じ高品質のビデオを最初に再生してから2回目にループしても、この例外がスローされます。ビデオ サイズが 80 MB を超えると、この例外がスローされます。バッファ サイズの問題ですか? 誰か私を案内してくれませんか。どうもありがとうございます

@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");
}
4

2 に答える 2

7

完全なコードを見ずに、この問題が発生しているデバイス/プラットフォームを知らなくても (ただし、質問からは 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 ログを探します。それはあなたにいくつかの手がかりを与えるかもしれません。

私の高レベルのアドバイスが、問題を突き止めるのに役立つことを願っています. 幸運を!!!。

于 2015-04-18T20:41:45.447 に答える
0

ExoPlayer と Surface を完全に破棄する代わりに、同じ ExoPlayer と Surface インスタンスを再利用できるはずです。

ExoPlayer を停止し、新しい FrameworkSampleSource/MediaCodec{Audio,Video}TrackRender オブジェクトを作成してから、prepare再度呼び出します。

新しいコードは次のようになります。

  • MoviePlayer.stop()
  • MoviePlayer.seekTo(0)
  • 新しい FrameworkSampleSource と MediaCodec{Audio,Video}TrackRenders
  • MoviePlayer.prepare(newVideoRenderer, newAudioRenderer)

stop メソッドのコメントを参照してください。

/** * 再生を停止します。* 意図が再生の一時停止である場合は、このメソッドではなく {@code setPlayWhenReady(false)} を使用してください。*

* このメソッドを呼び出すと、再生状態が * {@link ExoPlayer#STATE_IDLE} に遷移します。プレーヤー インスタンスは引き続き使用できます。 * {@link ExoPlayer#release()} が不要になった場合は、プレーヤーで呼び出す必要があります。*

※このメソッドを呼び出しても再生位置はリセットされません。* このプレーヤ インスタンスを使用して別のビデオを最初から再生する場合、{@code seekTo(0)} は * プレーヤを停止した後、次のビデオの準備をする前に呼び出す必要があります。*/

于 2015-04-25T07:24:33.433 に答える