【简单封装】TextureView+MediaPlay播放网络视频及个人问题总结

上半部分为错误记录,下半部分为代码。
目前存在的问题(19/010/28)(平台:Android 5.1.1——内存:1G,存储:8G,CPU:RK3188,GPU:Mali400):
问题一:视频掉帧与触摸卡死

  • TextureView为硬解,使用的是GPU,同时界面加载也使用的GPU,需要考虑mali400算力。
  • VideoView(surfaceView)为软解,使用的是CPU。
  • 爆满的CPU与GPU占用会导致触摸程序卡死,导致触摸屏失效。例如播放视频的同时, 快速连续点击屏幕或在屏幕上拖动等。(可能是这家厂商的问题,不一定是3188的锅,但无论是谁,为什么触摸程序卡死重启的机制都没有!!!)

解决:

  • 优化布局和升级CPU。(上3288吧,哭,实际运行流畅度提升30%-40%)
  • 相比较GPU,CPU播放要流畅不少,使用AndroidVideoCacheVideoView播放进行规避,注意:网络下载的时候也是很占CPU的,所以视频的清晰度和码率要控制好。(传送门)
  • 双视频一个Videoview软解,一个TextureView硬解,降低负载。(有想法没做过,因为这时的我已经升级为3288了,稽)

问题二:解码报错

  • 加载某些网络视频会报如下错误,且视频卡死,可添加监听处理在这里插入图片描述
  • 卡死后疯狂弹出log:E/H264_DEBUG( 478): OutputPicture# no pictures to be displayed
  • 解码器报错与码率无关,播放另一份40M,1080p,1900kps的视频没有出现700报错

解决:

  • 报错不可怕,让他报去,加载完之后就不卡了,预计也是CPU的原因,处理好播放器Error后的处理。

问题三:createGraphicBuffer failed与EGL_BAD_ALLOC——之前出现过一段时间,目前未再出现,可忽略待定

  • 情景再现:两份上述40M的视频同时播放,其中一个视频黑屏未播放,另一份正常无报错。
  • 黑屏视频加载时报错E/BufferQueueProducer: [unnamed-1849-1] dequeueBuffer: createGraphicBuffer failed
  • 关闭视频后报错
    E/libEGL: eglMakeCurrent:786 error 3003 (EGL_BAD_ALLOC)
    A/OpenGLRenderer: Failed to make current on surface 0x42763da0, error=EGL_BAD_ALLOC
public class TextureMedia implements TextureView.SurfaceTextureListener, MediaPlayer.OnErrorListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener {
	
	String url;
	Surface surface;
    TextureView textureView;
    MediaPlayer mediaPlayer;
	
    public TextureMedia(TextureView textureView, MediaPlayer mediaPlayer,String url) {
        this.textureView = textureView;
        this.mediaPlayer = mediaPlayer;
        this.url = url;
        creat();
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
        surface = new Surface(surfaceTexture);
    }

    public void creat(){
        textureView.setSurfaceTextureListener(this);
		
        mediaPlayer.setLooping(true);
        mediaPlayer.setOnErrorListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setScreenOnWhilePlaying(true);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        new PlayerVideoThread().start();
    }

    private class PlayerVideoThread extends Thread{
        @Override
        public void run() {
            try {
                mediaPlayer.setDataSource(url);
                mediaPlayer.setVideoScalingMode(VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
                mediaPlayer.prepareAsync();
            } catch (IllegalStateException ie){
                ie.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.setSurface(surface);
        mp.start();
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.start();
    }

    public void restar(){
        try {
            mediaPlayer.stop();
            mediaPlayer.reset();
            mediaPlayer.setDataSource(url);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        restar();
        return true;
    }

    public void start(){
        mediaPlayer.start();
    }
    public void pause(){
        mediaPlayer.pause();
    }
    public void stop(){
        mediaPlayer.stop();
    }
    public void release(){
       if (mediaPlayer!=null){
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer=null;
        }
    }
    public void setVolume(int volume){
        mediaPlayer.setVolume(volume,volume);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    }
    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    }

}

主线程调用

mediaPlayer1 = new MediaPlayer();
mediaPlayer2 = new MediaPlayer();
     
textureMedia1 = new TextureMedia(textureView1,mediaPlayer1,mp4url1);
textureMedia2 = new TextureMedia(textureView2,mediaPlayer2,mp4url2);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值