-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix MediaStream remote close by using an aux RTCDataChannel (#963)
### Problem `MediaConnection.close()` doesn't propagate the `close` event to the remote peer. ### Solution The proposed solution uses a similar approach to the `DataConnection`, where an aux data channel is created for the connection. This way, when we `MediaConnection.close()` the data channel will be closed and the `close` signal will be propagated to the remote peer. #### Notes I was not sure if there was another cleaner way of achieving this, without the extra data channel, but this seems to work pretty well (at least until a better solution comes up). This should fix: #636 --------- Co-authored-by: Jonas Gloning <[email protected]> Closes #636, Closes #1089, Closes #1032, Closes #832, Closes #780, Closes #653
- Loading branch information
Showing
8 changed files
with
235 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title></title> | ||
<link rel="stylesheet" href="../style.css" /> | ||
</head> | ||
<body> | ||
<h1>MediaChannel</h1> | ||
<canvas id="sender-stream" width="200" height="100"></canvas> | ||
<video id="receiver-stream" autoplay></video> | ||
<script> | ||
const canvas = document.getElementById("sender-stream"); | ||
const ctx = canvas.getContext("2d"); | ||
|
||
// Set the canvas background color to white | ||
ctx.fillStyle = "white"; | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
|
||
// Draw the text "Alice" in black | ||
ctx.font = "30px sans-serif"; | ||
ctx.fillStyle = "black"; | ||
ctx.fillText(window.location.hash.substring(1), 50, 50); | ||
</script> | ||
<div id="inputs"> | ||
<input type="text" id="receiver-id" placeholder="Receiver ID" /> | ||
<button id="call-btn" disabled>Call</button> | ||
<button id="close-btn">Hang up</button> | ||
</div> | ||
<div id="messages"></div> | ||
<div id="result"></div> | ||
<div id="error-message"></div> | ||
<video></video> | ||
<script src="/dist/peerjs.js"></script> | ||
<script src="close.js" type="module"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* @type {typeof import("../peerjs").Peer} | ||
*/ | ||
const Peer = window.Peer; | ||
|
||
document.getElementsByTagName("title")[0].innerText = | ||
window.location.hash.substring(1); | ||
|
||
const callBtn = document.getElementById("call-btn"); | ||
console.log(callBtn); | ||
const receiverIdInput = document.getElementById("receiver-id"); | ||
const closeBtn = document.getElementById("close-btn"); | ||
const messages = document.getElementById("messages"); | ||
const errorMessage = document.getElementById("error-message"); | ||
|
||
const stream = window["sender-stream"].captureStream(30); | ||
// const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true}) | ||
const peer = new Peer({ debug: 3 }); | ||
/** | ||
* @type {import("peerjs").MediaConnection} | ||
*/ | ||
let mediaConnection; | ||
peer | ||
.once("open", (id) => { | ||
messages.textContent = `Your Peer ID: ${id}`; | ||
}) | ||
.once("error", (error) => { | ||
errorMessage.textContent = JSON.stringify(error); | ||
}) | ||
.once("call", (call) => { | ||
mediaConnection = call; | ||
mediaConnection.on("stream", function (stream) { | ||
console.log("stream", stream); | ||
const video = document.getElementById("receiver-stream"); | ||
console.log("video element", video); | ||
video.srcObject = stream; | ||
video.play(); | ||
}); | ||
mediaConnection.once("close", () => { | ||
messages.textContent = "Closed!"; | ||
}); | ||
call.answer(stream); | ||
messages.innerText = "Connected!"; | ||
}); | ||
|
||
callBtn.addEventListener("click", async () => { | ||
console.log("calling"); | ||
|
||
/** @type {string} */ | ||
const receiverId = receiverIdInput.value; | ||
if (receiverId) { | ||
mediaConnection = peer.call(receiverId, stream); | ||
mediaConnection.on("stream", (stream) => { | ||
console.log("stream", stream); | ||
const video = document.getElementById("receiver-stream"); | ||
console.log("video element", video); | ||
video.srcObject = stream; | ||
video.play(); | ||
messages.innerText = "Connected!"; | ||
}); | ||
mediaConnection.on("close", () => { | ||
messages.textContent = "Closed!"; | ||
}); | ||
} | ||
}); | ||
|
||
closeBtn.addEventListener("click", () => { | ||
mediaConnection.close(); | ||
}); | ||
|
||
callBtn.disabled = false; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { browser, $ } from "@wdio/globals"; | ||
class SerializationPage { | ||
get receiverId() { | ||
return $("input[id='receiver-id']"); | ||
} | ||
get callBtn() { | ||
return $("button[id='call-btn']"); | ||
} | ||
|
||
get messages() { | ||
return $("div[id='messages']"); | ||
} | ||
|
||
get closeBtn() { | ||
return $("button[id='close-btn']"); | ||
} | ||
|
||
get errorMessage() { | ||
return $("div[id='error-message']"); | ||
} | ||
|
||
get result() { | ||
return $("div[id='result']"); | ||
} | ||
|
||
waitForMessage(right: string) { | ||
return browser.waitUntil( | ||
async () => { | ||
const messages = await this.messages.getText(); | ||
return messages.startsWith(right); | ||
}, | ||
{ timeoutMsg: `Expected message to start with ${right}`, timeout: 10000 }, | ||
); | ||
} | ||
|
||
async open() { | ||
await browser.switchWindow("Alice"); | ||
await browser.url(`/e2e/mediachannel/close.html#Alice`); | ||
await this.callBtn.waitForEnabled(); | ||
|
||
await browser.switchWindow("Bob"); | ||
await browser.url(`/e2e/mediachannel/close.html#Bob`); | ||
await this.callBtn.waitForEnabled(); | ||
} | ||
async init() { | ||
await browser.url("/e2e/alice.html"); | ||
await browser.waitUntil(async () => { | ||
const title = await browser.getTitle(); | ||
return title === "Alice"; | ||
}); | ||
await browser.pause(1000); | ||
await browser.newWindow("/e2e/bob.html"); | ||
await browser.waitUntil(async () => { | ||
const title = await browser.getTitle(); | ||
return title === "Bob"; | ||
}); | ||
await browser.pause(1000); | ||
} | ||
} | ||
|
||
export default new SerializationPage(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import P from "./close.page.js"; | ||
import { browser } from "@wdio/globals"; | ||
|
||
fdescribe("MediaStream", () => { | ||
beforeAll(async () => { | ||
await P.init(); | ||
}); | ||
fit("should close the remote stream", async () => { | ||
await P.open(); | ||
await P.waitForMessage("Your Peer ID: "); | ||
const bobId = (await P.messages.getText()).split("Your Peer ID: ")[1]; | ||
await browser.switchWindow("Alice"); | ||
await P.waitForMessage("Your Peer ID: "); | ||
await P.receiverId.setValue(bobId); | ||
await P.callBtn.click(); | ||
await P.waitForMessage("Connected!"); | ||
await browser.switchWindow("Bob"); | ||
await P.waitForMessage("Connected!"); | ||
await P.closeBtn.click(); | ||
await P.waitForMessage("Closed!"); | ||
await browser.switchWindow("Alice"); | ||
await P.waitForMessage("Closed!"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters