Skip to content

Commit

Permalink
support publish multiple simulcast track
Browse files Browse the repository at this point in the history
  • Loading branch information
shinyoshiaki committed Dec 22, 2020
1 parent ddcd650 commit 6649750
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 25 deletions.
16 changes: 8 additions & 8 deletions examples/client-demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FC, useContext, useEffect, useRef, useState } from "react";
import { FC, useContext, useEffect, useState } from "react";
import { ClientContext } from ".";
import { MediaInfo, SubscriberType } from "../../../packages/client/src";
import { Box, Button, Flex, Stack, Badge } from "@chakra-ui/react";
import { Box, Stack, Text } from "@chakra-ui/react";
import { Control } from "./containers/control";
import { Medias } from "./containers/remote/medias";
import { Published } from "./containers/local/published";

const App: FC = () => {
const client = useContext(ClientContext);
const [peerId, setPeerId] = useState("");

const init = async () => {
const params = new URLSearchParams(window.location.hash.split("#")[1]);
Expand All @@ -19,6 +19,7 @@ const App: FC = () => {

console.log("roomName", client.roomName);
client.apiJoin();
client.events.onConnect.subscribe(() => setPeerId(client.peerId));
};

useEffect(() => {
Expand All @@ -27,13 +28,12 @@ const App: FC = () => {

return (
<Box>
<Control />
<Box p={2}>
<Text>peerId : {peerId}</Text>
<Stack p={2}>
<Control />
<Published />
</Box>
<Box p={2}>
<Medias />
</Box>
</Stack>
</Box>
);
};
Expand Down
18 changes: 14 additions & 4 deletions examples/client-demo/src/containers/control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,33 @@ import { ClientContext } from "..";
export const Control: FC = () => {
const client = useContext(ClientContext);

const publish = async (
const publishMedia = async (
simulcast: boolean,
constraints: MediaStreamConstraints
) => {
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
await client.publish({ track: mediaStream.getTracks()[0], simulcast });
};

const publishDisplay = async (simulcast: boolean) => {
const mediaStream = await (navigator.mediaDevices as any).getDisplayMedia();
await client.publish({ track: mediaStream.getTracks()[0], simulcast });
};

return (
<Stack direction="row">
<Button onClick={() => publish(true, { video: true })}>
<Button onClick={() => publishMedia(true, { video: true })}>
publish simulcast
</Button>
<Button onClick={() => publish(false, { video: true })}>publish</Button>
<Button onClick={() => publish(false, { audio: true })}>
<Button onClick={() => publishMedia(false, { video: true })}>
publish
</Button>
<Button onClick={() => publishMedia(false, { audio: true })}>
publish audio
</Button>
<Button onClick={() => publishDisplay(true)}>
publish simulcast display
</Button>
</Stack>
);
};
2 changes: 1 addition & 1 deletion examples/client-demo/src/containers/remote/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const Media: FC<{ info: MediaInfo }> = ({ info }) => {
unsubscribe
</Button>
</Stack>
{info.simulcast && (
{stream && info.simulcast && (
<Stack direction="row" p={1}>
<Button onClick={() => changeQuality(info, "low")}>low</Button>
<Button onClick={() => changeQuality(info, "high")}>high</Button>
Expand Down
14 changes: 10 additions & 4 deletions packages/client/src/domain/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@ export class User {

if (request.simulcast) {
const params = transceiver.sender.getParameters();
params.encodings = [
{ maxBitrate: 680000, scaleResolutionDownBy: 1, rid: "high" },
{ maxBitrate: 36000, scaleResolutionDownBy: 4, rid: "low" },
];
params.encodings[0] = {
...params.encodings[0],
maxBitrate: 680000,
scaleResolutionDownBy: 1,
};
params.encodings[1] = {
...params.encodings[1],
maxBitrate: 36000,
scaleResolutionDownBy: 4,
};
transceiver.sender.setParameters(params);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/domains/peer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { RTCPeerConnection } from "../../../werift";

export class PeerConnection extends RTCPeerConnection {
simulcastIndex = 0;
}
13 changes: 7 additions & 6 deletions packages/core/src/domains/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import debug from "debug";
import { v4 } from "uuid";
import {
Kind,
RTCPeerConnection,
RTCRtpTransceiver,
useAbsSendTime,
useSdesMid,
Expand All @@ -11,6 +10,7 @@ import {
import { Connection } from "../responders/connection";
import { MCUManager } from "./mcu/manager";
import { Media, MediaInfo } from "./media/media";
import { PeerConnection } from "./peer";
import { SFUManager } from "./sfu/manager";
import { SFU } from "./sfu/sfu";

Expand All @@ -20,12 +20,12 @@ export class Room {
readonly connection = new Connection(this);
readonly sfuManager = new SFUManager();
readonly mcuManager = new MCUManager();
peers: { [peerId: string]: RTCPeerConnection } = {};
peers: { [peerId: string]: PeerConnection } = {};
medias: { [mediaId: string]: Media } = {};

async join() {
const peerId = "p_" + v4();
const peer = new RTCPeerConnection({
const peer = new PeerConnection({
stunServer: ["stun.l.google.com", 19302],
headerExtensions: {
video: [useSdesMid(1), useAbsSendTime(2), useSdesRTPStreamID(3)],
Expand Down Expand Up @@ -71,11 +71,12 @@ export class Room {
log("publish", publisherId, { simulcast, kind });
const peer = this.peers[publisherId];

const simulcastId = peer.simulcastIndex++;
const transceiver = simulcast
? peer.addTransceiver("video", "recvonly", {
simulcast: [
{ rid: "high", direction: "recv" },
{ rid: "low", direction: "recv" },
{ rid: simulcastId + "high", direction: "recv" },
{ rid: simulcastId + "low", direction: "recv" },
],
})
: peer.addTransceiver(kind, "recvonly");
Expand All @@ -85,7 +86,7 @@ export class Room {
return { media, peer };
}

async publish(media: Media, peer: RTCPeerConnection) {
async publish(media: Media) {
if (media.simulcast) {
await media.transceiver.onTrack.asPromise();
media.transceiver.receiver.tracks.forEach((track) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/domains/sfu/subscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class Subscriber {
const track =
state === "single"
? this.tracks[0].track
: this.tracks.find(({ track }) => track.rid === state).track;
: this.tracks.find(({ track }) => track.rid.includes(state)).track;

const [rtp] = await track.onRtp.asPromise();
this.sender.replaceRtp(rtp.header);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/responders/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class Connection {
const [publisherId, request] = args;

const { media, peer } = this.room.createMedia(publisherId, request);
this.room.publish(media, peer).then(({ peers, info }) => {
this.room.publish(media).then(({ peers, info }) => {
peers.forEach((peer) => {
this.sendRPC<HandlePublish>(
{ type: "handlePublish", payload: [info] },
Expand Down

0 comments on commit 6649750

Please sign in to comment.