使用cyndilib转发NDI流时视频正常但音频丢失的问题求助
使用cyndilib v0.0.6转发NDI流时无音频的问题排查
问题描述
在Windows系统上使用cyndilib(v0.0.6)接收NDI源并进行转发(含分辨率调整等场景),当前遇到的问题是:对传入的NDI流进行解码或重编码后重新转发为新NDI流时,无法听到音频。原始NDI源同时包含音频和视频,已通过NDI Studio Monitor验证正常。
当前测试情况
- 原始NDI流 → cyndilib+NDI SDK自定义查看器:可看到视频,但无音频输出
- 原始NDI流 → cyndilib解码+调整分辨率→重编码NDI流:NDI Studio Monitor中可看到视频,但无音频
- 原始NDI流 → NDI Studio Monitor:音视频均正常
测试代码
with Finder() as finder: time.sleep(2) finder.wait_for_sources(1.0) source = next((s for s in finder if s.name == source_name or s.stream_name == source_name), None) if not source: raise Exception(f"Source '{source_name}' not found") recv = Receiver(color_format=RecvColorFormat.BGRX_BGRA.value, bandwidth=RecvBandwidth.highest.value) vf, af = VideoFrameSync(), AudioFrameSync() recv.frame_sync.set_video_frame(vf) recv.frame_sync.set_audio_frame(af) recv.set_source(source) for _ in range(30): if recv.is_connected(): break time.sleep(0.5) else: raise TimeoutError("Connection timed out") while True: recv.frame_sync.capture_video() if vf.get_resolution() != (0, 0) and vf.get_data_size() > 0: break time.sleep(1 / 30) xres, yres = vf.get_resolution() fps = vf.get_frame_rate() sender = Sender(f"NDISDK_{source_name}") vsf = VideoSendFrame() vsf.set_fourcc(vf.get_fourcc()) vsf.set_resolution(xres, yres) vsf.set_frame_rate(fps) sender.set_video_frame(vsf) sender.open() audio_configured = False interval = 1.0 / fps try: while recv.is_connected(): recv.frame_sync.capture_video() arr = vf.get_array() if arr is not None and arr.size > 0: sender.write_video(arr) if recv.frame_sync.capture_available_audio() > 0: if not audio_configured and af.num_samples > 0: asf = AudioSendFrame() asf.set_max_num_samples(af.num_samples) sender.set_audio_frame(asf) audio_configured = True aud = af.get_array() if aud is not None and aud.size > 0: sender.write_audio(aud) time.sleep(interval) except KeyboardInterrupt: pass finally: try: sender.close() except: pass try: recv.disconnect() except: pass
核心疑问
- 使用cyndilib设置音频转发时是否遗漏关键步骤?
- cyndilib v0.0.6或Windows上的NDI SDK 6在音频转发上有已知问题或特性吗?
- 如何调试确认音频帧已被正确捕获和发送?
环境信息
- NDI SDK版本:6
- cyndilib版本:0.0.6
- Windows版本:10 Pro
- NDI流类型:NDI HB
排查与解决方案
1. 音频配置的遗漏点
你的代码仅设置了音频采样数,缺少NDI音频必需的完整参数配置,需补充以下内容:
if not audio_configured and af.num_samples > 0: asf = AudioSendFrame() asf.set_max_num_samples(af.num_samples) # 新增关键音频参数配置 asf.set_sample_rate(af.get_sample_rate()) asf.set_num_channels(af.get_num_channels()) asf.set_fourcc(af.get_fourcc()) # 必须与接收帧的音频格式匹配 sender.set_audio_frame(asf) audio_configured = True
另外,需循环处理所有可用音频帧,避免只处理一次导致帧丢失:
# 替换原音频捕获逻辑 while recv.frame_sync.capture_available_audio() > 0: if not audio_configured and af.num_samples > 0: asf = AudioSendFrame() asf.set_max_num_samples(af.num_samples) asf.set_sample_rate(af.get_sample_rate()) asf.set_num_channels(af.get_num_channels()) asf.set_fourcc(af.get_fourcc()) sender.set_audio_frame(asf) audio_configured = True aud = af.get_array() if aud is not None and aud.size > 0: sender.write_audio(aud)
2. cyndilib v0.0.6的特性说明
- 该版本音频同步依赖
AudioFrameSync的实时捕获,需确保在视频循环中优先处理音频,避免帧堆积 - 部分用户反馈处理高带宽NDI HB流时,
af.get_array()可能返回空,需添加参数校验
3. 调试验证方法
- 捕获阶段验证:添加日志打印关键参数,确认音频帧是否被正确捕获
if recv.frame_sync.capture_available_audio() > 0: print(f"可用音频帧数: {recv.frame_sync.capture_available_audio()}") print(f"采样数: {af.num_samples}, 采样率: {af.get_sample_rate()}, 声道数: {af.get_num_channels()}") aud = af.get_array() print(f"音频数组大小: {aud.size if aud is not None else 0}") - 发送阶段验证:检查
sender.write_audio()的返回值(若有),确认发送状态 - 对比测试:用NDI SDK官方C++示例测试同流,验证是否为cyndilib绑定问题
- 开启NDI日志:设置环境变量
NDI_DEBUG_LEVEL=3,查看音频捕获和发送的详细日志
内容的提问来源于stack exchange,提问作者Yash mandlik
相关产品推荐
相关产品推荐

