场景

开发者因为场景需要,希望能获取到视频画面的原始数据(YUV 数据),然后再进行处理或渲染。

解决方案

1、实现 TXLivePushListener 接口,然后在onPlayEvent(int event, Bundle param) 方法中,监听TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION 事件

mLivePusher.setPushListener(this);

public void onPlayEvent(int event, Bundle param) {
    //...
    if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) {
        //获取视频的宽高
        int width = param.getInt(TXLiveConstants.EVT_PARAM1, 0);
        int height = param.getInt(TXLiveConstants.EVT_PARAM2, 0);
        if (width != 0 && height != 0 && !mHWDecode) {
            //创建存储 yuv 数据的 buffer,目前输出的 yuv 格式为 I420
            byte[] buf = new byte[width * height * 3 / 2];
            //将 buffer 设置进 mLivePlaye
            mLivePlayer.addVideoRawData(buf);
        }
    }
}

2、通过 VideoRawDataListener 获取 YUV 数据

mLivePlayer.setVideoRawDataListener(rawDataListener);

TXVideoRawDataObserver.ITXVideoRawDataListener rawDataListener = new
TXVideoRawDataObserver.ITXVideoRawDataListener() {
    @Override
    public void onVideoRawDataAvailable(byte[] buf, int width, int height, int timestamp) {
        //解码一帧后的数据回调,buf 中存放了 yuv 数据,格式为 I420
        if (!mHWDecode) {
            // 如果需要继续获取yuv数据,需要重新调用addVideoRawData方法
            // yuvBuffer大小应该等于视频width*height*3/2
            mLivePlayer.addVideoRawData(buf);
        }
    }
};

原理

软件解码是由CPU负责解码,然后进行播放。这种方式解码出来的画面数据格式是 YUV 数据。而硬件解码是使用显卡进行解码,需要使用 OpenGL进行解码,所以解码出来的画面数据格式 Texture。

注意事项

1、setVideoRawDataListener只支持软件解码。

2、只能获取直播场景下的 YUV 数据,不支持点播场景。

文章来源于腾讯云开发者社区,点击查看原文