You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:57:23