如何从team-recording-bot获取Teams会议视频录制文件
Teams会议录制机器人视频采集与本地ZIP存储实现
背景说明
- 开发目标:研发Teams会议录制机器人,支持会议结束后导出包含视频内容的录制文件
- 当前状态:基于Azure Kubernetes部署官方Teams录制机器人示例,已实现机器人自动入会、启动录制能力,目前仅能获取ZIP封装的WAV格式音频,无法输出视频文件
- 现有进展:已完成IVideoSocket接入,但未实现视频采集、存储、打包入ZIP的逻辑,当前
OnVideoMediaReceived回调仅完成日志打印与缓冲区释放,相关代码如下:
private void OnVideoMediaReceived(object sender, VideoMediaReceivedEventArgs e) { this.GraphLogger.Info($"[{e.SocketId}]: Received Video: [VideoMediaReceivedEventArgs(Data=<{e.Buffer.Data.ToString()}>, Length={e.Buffer.Length}, Timestamp={e.Buffer.Timestamp}, Width={e.Buffer.VideoFormat.Width}, Height={e.Buffer.VideoFormat.Height}, ColorFormat={e.Buffer.VideoFormat.VideoColorFormat}, FrameRate={e.Buffer.VideoFormat.FrameRate})]"); // TBD: Compliance Recording bots can record the Video here e.Buffer.Dispose(); }
具体实现逻辑
1. 视频帧接收与异步缓存
OnVideoMediaReceived属于媒体实时回调线程,禁止在回调内执行编码、写文件等耗时操作,否则会引发帧丢失、媒体连接中断问题,仅做轻量帧拷贝入队操作:
- 初始化线程安全的帧队列,设置合理容量上限避免内存溢出
- 回调触发时,将当前缓冲区的原始视频帧(默认NV12格式)拷贝到独立内存块,附带时间戳、分辨率、帧率元信息存入队列
- 完成数据拷贝后立即释放原缓冲区,不阻塞回调线程
参考实现片段:
// 自定义原始视频帧结构 public class RawVideoFrame { public long Timestamp { get; set; } public int Width { get; set; } public int Height { get; set; } public int FrameRate { get; set; } public VideoColorFormat ColorFormat { get; set; } public byte[] Data { get; set; } } // 线程安全帧队列 private readonly ConcurrentQueue<RawVideoFrame> _videoFrameQueue = new(); private void OnVideoMediaReceived(object sender, VideoMediaReceivedEventArgs e) { var buffer = e.Buffer; var frame = new RawVideoFrame { Timestamp = buffer.Timestamp, Width = buffer.VideoFormat.Width, Height = buffer.VideoFormat.Height, FrameRate = buffer.VideoFormat.FrameRate, ColorFormat = buffer.VideoFormat.VideoColorFormat, Data = new byte[buffer.Length] }; // 拷贝帧数据,避免缓冲区释放后数据失效 Marshal.Copy(buffer.Data, frame.Data, 0, buffer.Length); _videoFrameQueue.Enqueue(frame); // 立即释放缓冲区 e.Buffer.Dispose(); }
2. 原始帧编码为可播放视频文件
单独启动后台消费线程处理帧队列数据,完成视频编码:
- 从队列中按时间戳顺序取原始帧,送入视频编码器,编码为H.264格式的MP4通用视频文件
- 编码参数匹配接收帧的分辨率、帧率,通过时间戳对齐现有采集的音频流,完成音视频混流,输出完整的会议录制MP4文件
- 容器部署场景推荐使用带硬件加速的编码库,降低CPU占用,1080P 30fps的录制场景建议为单实例配置至少2vCPU、4GB内存
- 多参会人视频场景下,需根据
SocketId区分不同用户的视频流,分别编码存储,避免多人流数据混叠
3. 录制文件打包为本地ZIP
会议结束、录制停止后执行打包流程:
- 等待帧队列所有数据消费完成,关闭编码器、释放视频文件流,确认MP4文件写入完整
- 调用
System.IO.Compression.ZipArchive创建本地ZIP包,将生成的MP4视频文件、需要保留的WAV音频文件写入压缩包 - 校验ZIP包完整性后,清理临时缓存的原始帧数据、临时视频文件,释放占用资源
内容的提问来源于stack exchange,提问作者Aimeeting
相关产品推荐
相关产品推荐

