-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #430 from shinyoshiaki/feature/update-ice
support restart ice
- Loading branch information
Showing
38 changed files
with
3,299 additions
and
4,284 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
Large diffs are not rendered by default.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import type { AcceptFn, Peer } from "protoo-server"; | ||
import { RTCPeerConnection } from "../.."; | ||
import { peerConfig } from "../../fixture"; | ||
|
||
const ice_restart_web_trigger_label = "ice_restart_web_trigger"; | ||
export class ice_restart_web_trigger { | ||
pc!: RTCPeerConnection; | ||
|
||
async exec(type: string, payload: any, accept: AcceptFn, peer: Peer) { | ||
switch (type) { | ||
case "init": | ||
{ | ||
this.pc = new RTCPeerConnection({ | ||
...(await peerConfig), | ||
icePasswordPrefix: "restartw", | ||
}); | ||
this.pc.onIceCandidate.subscribe((candidate) => { | ||
peer | ||
.request(ice_restart_web_trigger_label + "ice", candidate) | ||
.catch((e) => { | ||
console.error(e); | ||
}); | ||
}); | ||
this.pc.iceConnectionStateChange.subscribe((state) => { | ||
console.log(state); | ||
}); | ||
|
||
const transceiver = this.pc.addTransceiver("video"); | ||
transceiver.onTrack.subscribe((track) => { | ||
transceiver.sender.replaceTrack(track); | ||
const interval = setInterval(async () => { | ||
if (this.pc.signalingState === "closed") { | ||
clearInterval(interval); | ||
return; | ||
} | ||
await transceiver.receiver.sendRtcpPLI(track.ssrc); | ||
}, 3000); | ||
}); | ||
|
||
this.pc.setLocalDescription(await this.pc.createOffer()); | ||
accept(this.pc.localDescription); | ||
} | ||
break; | ||
case "candidate": | ||
{ | ||
this.pc.addIceCandidate(payload); | ||
accept({}); | ||
} | ||
break; | ||
case "answer": | ||
{ | ||
await this.pc.setRemoteDescription(payload); | ||
accept({}); | ||
} | ||
break; | ||
case "offer": | ||
{ | ||
await this.pc.setRemoteDescription(payload); | ||
const answer = await this.pc.createAnswer(); | ||
this.pc.setLocalDescription(answer); | ||
accept(this.pc.localDescription); | ||
} | ||
break; | ||
case "fin": | ||
{ | ||
this.pc.close(); | ||
accept({}); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
|
||
const ice_restart_node_trigger_label = "ice_restart_node_trigger"; | ||
export class ice_restart_node_trigger { | ||
pc!: RTCPeerConnection; | ||
|
||
async exec(type: string, payload: any, accept: AcceptFn, peer: Peer) { | ||
switch (type) { | ||
case "init": | ||
{ | ||
this.pc = new RTCPeerConnection(await peerConfig); | ||
this.pc.onIceCandidate.subscribe((candidate) => { | ||
peer | ||
.request(ice_restart_node_trigger_label + "ice", candidate) | ||
.catch((e) => { | ||
console.error(e); | ||
}); | ||
}); | ||
this.pc.iceConnectionStateChange.subscribe((state) => { | ||
console.log(state); | ||
}); | ||
|
||
const transceiver = this.pc.addTransceiver("video"); | ||
transceiver.onTrack.subscribe((track) => { | ||
transceiver.sender.replaceTrack(track); | ||
const interval = setInterval(async () => { | ||
if (this.pc.signalingState === "closed") { | ||
clearInterval(interval); | ||
return; | ||
} | ||
await transceiver.receiver.sendRtcpPLI(track.ssrc); | ||
}, 3000); | ||
}); | ||
|
||
this.pc.setLocalDescription(await this.pc.createOffer()); | ||
accept(this.pc.localDescription); | ||
} | ||
break; | ||
case "candidate": | ||
{ | ||
this.pc.addIceCandidate(payload); | ||
accept({}); | ||
} | ||
break; | ||
case "answer": | ||
{ | ||
await this.pc.setRemoteDescription(payload); | ||
accept({}); | ||
} | ||
break; | ||
case "restart": | ||
{ | ||
await this.pc.setLocalDescription( | ||
await this.pc.createOffer({ iceRestart: true }), | ||
); | ||
accept(this.pc.localDescription); | ||
} | ||
break; | ||
case "fin": | ||
{ | ||
this.pc.close(); | ||
accept({}); | ||
} | ||
break; | ||
} | ||
} | ||
} |
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
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,148 @@ | ||
import { peer, sleep, waitVideoPlay } from "../fixture"; | ||
|
||
const ice_restart_web_trigger_label = "ice_restart_web_trigger"; | ||
const ice_restart_node_trigger_label = "ice_restart_node_trigger"; | ||
|
||
describe("ice/restart", () => { | ||
it(ice_restart_web_trigger_label, async () => { | ||
if (!peer.connected) await new Promise<void>((r) => peer.on("open", r)); | ||
await sleep(100); | ||
|
||
const pc = new RTCPeerConnection({ | ||
iceServers: [{ urls: "stun:stun.l.google.com:19302" }], | ||
}); | ||
// pc.oniceconnectionstatechange = () => { | ||
// console.log("ice connection state change", pc.iceConnectionState); | ||
// }; | ||
pc.onicecandidate = ({ candidate }) => { | ||
if (candidate) { | ||
peer | ||
.request(ice_restart_web_trigger_label, { | ||
type: "candidate", | ||
payload: candidate, | ||
}) | ||
.catch(() => {}); | ||
} | ||
}; | ||
|
||
const [track] = ( | ||
await navigator.mediaDevices.getUserMedia({ video: true }) | ||
).getTracks(); | ||
pc.addTrack(track); | ||
|
||
peer.on("request", async (request, accept) => { | ||
if (request.method !== ice_restart_web_trigger_label + "ice") { | ||
return; | ||
} | ||
const candidate = request.data; | ||
pc.addIceCandidate(candidate); | ||
accept(); | ||
}); | ||
|
||
const offer = await peer.request(ice_restart_web_trigger_label, { | ||
type: "init", | ||
}); | ||
await pc.setRemoteDescription(offer); | ||
await pc.setLocalDescription(await pc.createAnswer()); | ||
|
||
peer | ||
.request(ice_restart_web_trigger_label, { | ||
type: "answer", | ||
payload: pc.localDescription, | ||
}) | ||
.catch(() => {}); | ||
|
||
const remote = pc.getTransceivers().map((t) => t.receiver.track)[0]; | ||
await waitVideoPlay(remote); | ||
|
||
{ | ||
const offer = await pc.createOffer({ iceRestart: true }); | ||
await pc.setLocalDescription(offer); | ||
peer | ||
.request(ice_restart_web_trigger_label, { | ||
type: "offer", | ||
payload: pc.localDescription, | ||
}) | ||
.catch(() => {}); | ||
} | ||
|
||
await waitVideoPlay(remote); | ||
|
||
await peer.request(ice_restart_web_trigger_label, { | ||
type: "fin", | ||
}); | ||
}, 20_000); | ||
|
||
it(ice_restart_node_trigger_label, async () => { | ||
if (!peer.connected) await new Promise<void>((r) => peer.on("open", r)); | ||
await sleep(100); | ||
|
||
const pc = new RTCPeerConnection({ | ||
iceServers: [{ urls: "stun:stun.l.google.com:19302" }], | ||
}); | ||
// pc.oniceconnectionstatechange = () => { | ||
// console.log("ice connection state change", pc.iceConnectionState); | ||
// }; | ||
pc.onicecandidate = ({ candidate }) => { | ||
if (candidate) { | ||
peer | ||
.request(ice_restart_node_trigger_label, { | ||
type: "candidate", | ||
payload: candidate, | ||
}) | ||
.catch(() => {}); | ||
} | ||
}; | ||
|
||
const [track] = ( | ||
await navigator.mediaDevices.getUserMedia({ video: true }) | ||
).getTracks(); | ||
pc.addTrack(track); | ||
|
||
peer.on("request", async (request, accept) => { | ||
if (request.method !== ice_restart_node_trigger_label + "ice") { | ||
return; | ||
} | ||
const candidate = request.data; | ||
pc.addIceCandidate(candidate); | ||
accept(); | ||
}); | ||
|
||
const offer = await peer.request(ice_restart_node_trigger_label, { | ||
type: "init", | ||
}); | ||
await pc.setRemoteDescription(offer); | ||
await pc.setLocalDescription(await pc.createAnswer()); | ||
|
||
peer | ||
.request(ice_restart_node_trigger_label, { | ||
type: "answer", | ||
payload: pc.localDescription, | ||
}) | ||
.catch(() => {}); | ||
|
||
const remote = pc.getTransceivers().map((t) => t.receiver.track)[0]; | ||
await waitVideoPlay(remote); | ||
|
||
{ | ||
const offer = await peer.request(ice_restart_node_trigger_label, { | ||
type: "restart", | ||
}); | ||
await pc.setRemoteDescription(offer); | ||
await pc.setLocalDescription(await pc.createAnswer()); | ||
} | ||
|
||
peer | ||
.request(ice_restart_node_trigger_label, { | ||
type: "answer", | ||
payload: pc.localDescription, | ||
}) | ||
.catch(() => {}); | ||
|
||
await waitVideoPlay(remote); | ||
|
||
await peer.request(ice_restart_node_trigger_label, { | ||
type: "fin", | ||
}); | ||
}, 20_000); | ||
}); |
Oops, something went wrong.