
本文详解 webrtc 应用中「仅能接收音频或视频、无法同时播放」问题的根本原因——并非信令或 sdp 配置缺陷,而是 html `
在基于 RTSPtoWeb 等 WebRTC 转发服务实现安防摄像头音视频实时预览时,开发者常遇到一个典型现象:单独请求视频(addTransceiver('video'))可正常显示画面;单独请求音频(addTransceiver('audio'))可正常播放声音;但当同时添加音视频 transceiver 时,却只有其中一种媒体流生效(如仅画面无声音,或仅声音无画面)。许多初学者会误以为是 SDP 协商失败、编解码不兼容或服务端未推送音频轨道,而实际上,问题往往出在前端媒体元素的默认行为上。
关键线索已在你的代码中明确体现:
const video = document.createElement('video')
video.id = 'camera_video'
video.style = 'max-width:100%; max-height:100%'
video.muted = true // ← 这是核心问题!
video.controls = truevideo.muted = true 不仅使音频静音,更会直接禁用浏览器原生控件中的音量调节按钮(呈现为灰色不可点状态),即使 WebRTC 已成功接收并绑定包含音轨的 MediaStream,用户也无法感知音频存在。这是 HTML5
✅ 正确做法是:移除 video.muted = true,并显式启用音频播放控制:
const video = document.createElement('video');
video.id = 'camera_video';
video.style = 'max-width:100%; max-height:100%';
video.controls = true; // 保留 controls,允许用户操作音量
// ✅ 删除 video.muted = true 这一行同时,确保 WebRTC 连接正确声明双向接收能力:
const connection = new RTCPeerConnection({ sdpSemantics: 'unified-plan' });
connection.addTransceiver('video', { direction: 'recvonly' });
connection.addTransceiver('audio', { direction: 'recvonly' }); // ✅ 必须显式添加 audio transceiver⚠️ 注意事项:addTransceiver('audio') 和 addTransceiver('video') 的调用顺序不影响最终效果,现代浏览器会根据 SDP 中的 m= 行顺序自动匹配轨道;若服务端(如 RTSPtoWeb)未实际推送音频流(例如 RTSP 源无音频、或服务配置禁用了音频转封装),即使前端声明了 recvonly 音频 transceiver,ontrack 事件也不会触发音频轨道。可通过 Chrome 浏览器的 chrome://webrtc-internals 页面查看 remoteDescription 中是否包含 m=audio section 及对应 a=recvonly 属性来验证;为增强健壮性,建议在 ontrack 回调中区分处理音视频轨道:
connection.ontrack = (e) => {
console.log(`Received track: ${e.track.kind} (id: ${e.track.id})`);
if (!video.srcObject) {
video.srcObject = new MediaStream();
}
video.srcObject.addTrack(e.track);
video.play().catch(e => console.warn("Autoplay prevented:", e));
};此方式可确保音视频轨道均被添加至同一 MediaStream,避免因 srcObject 被覆盖导致仅显示最后添加的轨道。
总结:WebRTC 同时接收音视频的核心前提有三——服务端支持音频转发、客户端正确声明 audio + video transceiver、前端










