2024/09/19 14:52:02
原始视频数据
本文介绍如何对采集到的原始视频数据进行前处理和后处理。
技术原理
视频传输过程中,你可以对采集到的视频数据进行前处理和后处理,获取想要的播放效果。 对于有自行处理视频数据需求的场景,声网提供原始数据功能。你可以在将数据发送给编码器前进行前处理,对捕捉到的视频帧进行修改;也可以在将数据发送给解码器后进行后处理,对接收到的视频帧进行修改。
前提条件
在进行操作之前,请确保你已经在项目中实现了基本的实时音视频功能。详见实现音视频互动。
实现方法
参考如下步骤,在你的项目中实现原始视频数据功能:
-
加入频道前,创建一个
IVideoFrameObserver
对象,并调用RegisterVideoFrameObserver
方法注册视频观测器。如果想要预处理的视频数据生效,需要把formatPreference
设为FRAME_TYPE_YUV420
,把mode
设为INTPTR
。C#// 注册视频观测器
RtcEngine.RegisterVideoFrameObserver(new VideoFrameObserver(this),
VIDEO_OBSERVER_FRAME_TYPE.FRAME_TYPE_YUV420,
VIDEO_MODULE_POSITION.POSITION_POST_CAPTURER |
VIDEO_MODULE_POSITION.POSITION_PRE_RENDERER |
VIDEO_MODULE_POSITION.POSITION_PRE_ENCODER,
OBSERVER_MODE.INTPTR); -
通过
OnCaptureVideoFrame
和OnRenderVideoFrame
回调获取视频数据后,你可以根据场景需要自行进行处理。注意建议你在修改
videoFrame
中的参数时,需确保修改后的参数跟视频帧缓冲区中的视频帧实际情况保持一致,否则可能导致本地预览画面和对端的视频画面出现非预期的旋转、失真等问题。C#class VideoFrameObserver : IVideoFrameObserver
{ // 通过 OnCaptureVideoFrame 回调获取本地摄像头采集的原始视频数据
public override bool OnCaptureVideoFrame(VIDEO_SOURCE_TYPE sourceType, VideoFrame videoFrame)
{
ProcessVideoFrame(videoFrame);
return true;
}
// 通过 OnRenderVideoFrame 回调获取获取远端发送的视频数据
public override bool OnRenderVideoFrame(string channelId, uint remoteUid, VideoFrame videoFrame)
{
ProcessVideoFrame(videoFrame);
return true;
}
public void ProcessVideoFrame(VideoFrame videoFrame)
{
int yBufferLength = videoFrame.yStride * videoFrame.height;
int uBufferLength = videoFrame.uStride * videoFrame.height / 2;
int vBufferLength = videoFrame.vStride * videoFrame.height / 2;
byte[] bytes = new byte[uBufferLength];
for (int i = 0; i < uBufferLength; i++)
{
bytes[i] = 128;
}
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, videoFrame.uBufferPtr, uBufferLength);
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, videoFrame.vBufferPtr, vBufferLength);
}
}
参考信息
示例项目
声网提供了开源的原始视频数据示例项目,你可以前往下载或查看其中的源代码。