您当前的位置: 首页 >  音视频

命运之手

暂无认证

  • 1浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android音视频开发】【007】SurfaceView实现H264播放器

命运之手 发布时间:2019-12-25 16:49:28 ,浏览量:1

在前面,我们已经通过MediaCodec实现了一个AvcDecoder,可以播放H264码流数据 但是AvcDecoder需要手动和Surface绑定,仍然不太方便 这篇文章我们进一步封装,将MediaCodec和SurfaceView集合,实现一个带H264解码功能的控件

AvcPlayer源码


	//集成了AvcDecoder解码功能的SurfaceView
	//使用AvcDecoder,则需要手动绑定一个SurfaceView
	public class AvcPlayer extends SurfaceView {
	
	    MediaCodec mediaCodec;
	
	    Callback callback;
	
	    int width;
	    int height;
	
	    @Getter
	    boolean playing = false;
	
	    public AvcPlayer(Context context, AttributeSet attrs) {
	        super(context, attrs);
	    }
	
	    public void init(int width, int height, Callback callback) {
	        this.callback = callback;
	        this.width = width;
	        this.height = height;
	    }
	
	    @SneakyThrows
	    private void configureMediaCodec() {
	        mediaCodec = MediaCodec.createDecoderByType("video/avc");
	        MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
	        mediaCodec.configure(mediaFormat, getHolder().getSurface(), null, 0);
	        mediaCodec.start();
	    }
	
	    public void decodeNalu(byte[] nalu) {
	        if (!playing) return;
	
	        ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
	        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
	        if (inputBufferIndex = 0) {
	            mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
	            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
	        }
	
	        if (callback != null)
	            callback.onFrameUpdate(nalu);
	    }
	
	    public void startPreview() {
	        configureMediaCodec();
	        playing = true;
	    }
	
	    public void stopPreview() {
	        playing = false;
	        mediaCodec.stop();
	        mediaCodec.release();
	        mediaCodec = null;
	    }
	
	    public interface Callback {
	
	        void onFrameUpdate(byte[] frame);
	    }
	}

AvcPlayer使用方法


	AvcPlayer player;

	//开始播放,建议在onResume中延时2秒执行,等待SurfaceView初始化完成
	player.init(width, height, callback);
	player.startPreview();

	//解码并播放H264流数据,视频源可以来自文件、网络、设备取流等任何方式,只要字节集是由若干Nalu数据组成即可
	player.decodeNalu(byte[] nalu);

	//停止播放,在onPause中执行
	player.stopPreview();

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0393s