Android视频与音频复用一个MediaPlayer注意点

在使用SurfaceView+MediaPlayer播放视频,会使用到SurfaceHolder.Callback 并通过SurfaceHolder.addCallback添加到SurfaceView.getHolder()对象当中,其中SurfaceCallback为SurfaceHolder.Callback 的实例。

if (mSurfaceCallback == null) {
SurfaceHolder holder = mSurfaceView.getHolder();
mSurfaceCallback = new SurfaceCallback();
holder.addCallback(mSurfaceCallback);
}

SurfaceCallback具体实现如下,其在SurfaceView变为可见状态(VISIBLE)时,会调用surfaceCreated方法,在改方法里面调用 mMediaPlayer.setDisplay(surfaceHolder)进行跟MediaPlayer的绑定,在SurfaceView变为不可见状态(INVISIBLE&GONE),会调用surfaceDestoryed方法,注意在surfaceDestoryed中,需要对应的解除绑定,这样在后续复用MediaPlayer播放纯音频文件时才不会报错。

private class SurfaceCallback implements SurfaceHolder.Callback {
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        Log.d(TAG, "surfaceCreated");
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(surfaceHolder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        Log.d(TAG, "surfaceChanged");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        Log.d(TAG, "surfaceDestroyed");
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(null);
        }
    }
}

同时在播放纯音频的方法中时,也注意手动置null,mMediaPlayer.setDisplay(null);

public final void playAudio() {
        Log.d(TAG, "playAudio");
        stopAudio();
        if (mMediaPlayer == null) {
            initMediaPlayer();
        }

        try {
            mMediaPlayer.setDisplay(null);
            mMediaPlayer.reset();
            mMediaPlayer.setOnCompletionListener(null);
            AssetFileDescriptor openFd = getAssets().openFd("xxx.mp3");
            mMediaPlayer.setDataSource(openFd.getFileDescriptor(), openFd.getStartOffset(), openFd.getLength());
            mMediaPlayer.setLooping(true);
            mMediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
            stopAudio();
        }
    }

否则会报如下错误:

2022-08-28 01:06:13.468 458-522/? D/SurfaceUtils: connecting to surface 0xb4a9a008, reason setVideoSurfaceTexture
2022-08-28 01:06:13.469 362-1171/? E/BufferQueueProducer: SurfaceView - com.example.test/com.example.test.autotest.AutoTestActivity#1 connect: BufferQueue has been abandoned
2022-08-28 01:06:13.469 458-522/? E/SurfaceUtils: Failed to connect to surface 0xb4a9a008, err -19
2022-08-28 01:06:13.469 458-522/? E/MediaPlayerService: setVideoSurfaceTexture failed: -19
2022-08-28 01:06:13.469 458-522/? D/NuPlayerDriver: reset(0xb4ff70e0) at state 2
2022-08-28 01:06:13.469 458-971/? D/NuPlayerDriver: notifyResetComplete(0xb4ff70e0)
2022-08-28 01:06:13.470 653-653/com.example.text W/System.err: java.lang.IllegalStateException
2022-08-28 01:06:13.471 653-653/com.example.test W/System.err:     at android.media.MediaPlayer.prepareAsync(Native Method)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值