當我有兩個使用 peerjs 互相呼叫的對等點時,一旦一個對等點接受呼叫,即使我沒有明確設定自動播放或呼叫 play(),來自發起呼叫的對等點的音頻也會開始播放。這個問題出現在chrome瀏覽器中。
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]/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()
我不知道為什么會這樣。如果您在音頻暫停或自動播放打開時列印出來,它們都會列印暫停為真(即使音頻仍在播放)和自動播放為假(即使音頻仍在播放)。也沒有事件觸發。這是鉻錯誤嗎?還是我只是愚蠢?(我假設是后者)
uj5u.com熱心網友回復:
這是一個 Chrome 錯誤,我打開了https://crbug.com/1279299。
該錯誤的要點是,在設定為srcObjectHTMLAudioElement的 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;
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/379681.html
標籤:javascript 谷歌浏览器 声音的 网页版 对等点
上一篇:將偽列舉模型重構為列舉
