为啥对方接听电话后会自动播放音频?
Posted
技术标签:
【中文标题】为啥对方接听电话后会自动播放音频?【英文标题】:Why does audio automatically play after a peer accepts the call?为什么对方接听电话后会自动播放音频? 【发布时间】:2022-01-16 15:01:06 【问题描述】:当我有两个使用 peerjs 互相呼叫的对等方时,一旦对等方接受呼叫,即使我没有明确设置自动播放或调用 play(),来自发起呼叫的对等方的音频也会开始播放。这个问题出现在chrome浏览器中。
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>
</head>
<body>
<h1 id='peerid'></h1>
<input type='text' id='in'/>
<button onclick="call()">Call</button>
<button onclick="debug()">debug</button>
<button onclick="printtime()">time</button>
<button onclick="printauto()">auto</button>
</body>
<script type='text/javascript'>
let a = new Audio();
a.onplay = () =>
console.log('play');
;
a.onplaying = () =>
console.log('playing');
;
a.onseeking = () =>
console.log('seeking');
;
a.onseeked = () =>
console.log('seeked');
;
let m = new MediaStream();
a.srcObject = m;
let header = document.getElementById('peerid');
let i = document.getElementById('in');
let peer = new Peer();
peer.on('open', (id) =>
header.innerHTML = id;
);
peer.on('call', (call) =>
call.answer();
call.on('stream', (stream) =>
stream.getAudioTracks().forEach(track => m.addTrack(track));
);
);
let call = () =>
navigator.mediaDevices.getUserMedia( audio: true ).then(mediaStream =>
let call = peer.call(i.value, mediaStream);
call.on('stream', (stream) =>
stream.getAudioTracks().forEach(track => m.addTrack(track));
);
, rejected =>
console.log('rejected');
).catch(e => console.error(e));
;
let debug = () =>
console.log(a.paused);
;
let printtime = () =>
console.log(a.currentTime);
;
let printauto = () =>
console.log(a.autoplay);
;
</script>
</html>
为了复制这个,
-
使用网络服务器提供上述 html 代码(例如:python3 -m http.server)
打开两个为此页面提供服务的标签
将粗体标识符从一个选项卡复制到另一个选项卡,然后单击“调用”
它应该要求访问您的麦克风(这可能需要一段时间,所以请稍等,或者只是向通话按钮发送垃圾邮件)
一旦它可以访问您的麦克风,另一个选项卡应自动播放音频(音频将是您自己的声音),而音频元素的自动播放为 true 或在您可以看到的任何地方调用 play() 李>
我不知道为什么会这样。如果您打印音频是否暂停或自动播放已打开,它们都会打印暂停为真(即使音频仍在播放)和自动播放为假(即使音频仍在播放)。也没有任何事件触发。这是铬错误吗?还是我只是愚蠢? (我假设是后者)
【问题讨论】:
这是一个 Chrome 错误,here is an MCVE。奇怪的是,使用你的代码我无法在稳定的 96 上重现,但可以在最新的 98 上重现,而我的 min-repro 也为我在稳定的 96 上重现(全部在 macOS 上)。我会再调查一下,几个小时后回来。 我的 chrome 版本是 Version 96.0.4664.93 (Official Build) (64-bit) 我在 windows 11 上。 有点奇怪,我的马厩无法重现它,我可以在平分的同时重现更旧的版本,显然在同一台机器上......好吧无论如何,我打开了一个问题并在下面给了你一个解决方法.`` 【参考方案1】:这是一个 Chrome 错误,我打开了https://crbug.com/1279299。
该错误的要点是,在设置为 HTMLAudioElement 的srcObject
的 MediaSource 上添加音轨将强制自动播放该 MediaStream,即使该元素实际上从未告诉它...
因此可以像这样进行较小的复制:
const a = new Audio();
const m = new MediaStream();
a.srcObject = m;
a.volume = 0.1; // volume still works...
onclick = e =>
const ctx = new AudioContext();
const osc = ctx.createOscillator();
const out = ctx.createMediaStreamDestination();
osc.connect(out);
osc.start(0);
out.stream.getAudioTracks().forEach(t => m.addTrack(t));
;
Click to start
知道了这一点,解决方法也很明显:不要将元素的 srcObject
设置为这个空的 MediaStream,直接将其设置为从对等点接收到的一个流:
call.on('stream', (stream) =>
a.srcObject = stream;
);
【讨论】:
以上是关于为啥对方接听电话后会自动播放音频?的主要内容,如果未能解决你的问题,请参考以下文章