Skip to content

Commit

Permalink
feat: drop in livekit inplace of livepeer (#736)
Browse files Browse the repository at this point in the history
* feat: drop in livekit inplace of livepeer

* feat: added microphone

* feat: added mic

* feat: added access control
  • Loading branch information
arn4b authored Oct 3, 2023
1 parent e536453 commit ddd8122
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 188 deletions.
20 changes: 10 additions & 10 deletions packages/restapi/src/lib/space/acceptPromotionRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ export async function acceptPromotionRequest(
});

// accept the promotion request
this.acceptRequest({
signalData,
senderAddress: this.data.local.address,
recipientAddress: pCAIP10ToWallet(promoteeAddress),
chatId: spaceId,
details: {
type: SPACE_ACCEPT_REQUEST_TYPE.ACCEPT_PROMOTION,
data: {},
},
});
// this.acceptRequest({
// signalData,
// senderAddress: this.data.local.address,
// recipientAddress: pCAIP10ToWallet(promoteeAddress),
// chatId: spaceId,
// details: {
// type: SPACE_ACCEPT_REQUEST_TYPE.ACCEPT_PROMOTION,
// data: {},
// },
// });
}
217 changes: 109 additions & 108 deletions packages/restapi/src/lib/space/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ type StartType = {
livepeerApiKey: string;
};

export async function start(this: Space, options: StartType): Promise<void> {
const { livepeerApiKey } = options || {};
// export async function start(this: Space, options: StartType): Promise<void> {
export async function start(this: Space): Promise<void> {
// const { livepeerApiKey } = options || {};

try {
// host should have there audio stream
if (!this.data.local.stream) {
throw new Error('Local audio stream not found');
}
// if (!this.data.local.stream) {
// throw new Error('Local audio stream not found');
// }

const space = await get({
spaceId: this.spaceSpecificData.spaceId,
Expand Down Expand Up @@ -115,109 +116,109 @@ export async function start(this: Space, options: StartType): Promise<void> {
});
});

// start the livepeer playback and store the playback URL group meta
// send a notification/meta message to all the added listeners (members) telling the space has started

// create the mergeStream object
const mergedStream = getMergeStreamObject(this.data.local.stream);
// store the mergeStreamObject
this.mergedStream = mergedStream;

const url = 'https://livepeer.studio/api/stream';
const data = {
name: this.spaceSpecificData.spaceName,
record: true,
};

const { data: responseData } = await axios.post(url, data, {
headers: {
Authorization: 'Bearer ' + livepeerApiKey,
},
});

const { streamKey, playbackId } = responseData;

console.log('livepeer details', streamKey, playbackId);

this.update({ meta: playbackId });

let redirectUrl;
try {
console.log('Ignore the following error');

// the redirect URL from the above GET request
await axios.get(`https://livepeer.studio/webrtc/${streamKey}`);
} catch (err: any) {
console.log('redirectUrl error', err);
redirectUrl = err.request.responseURL;
}

// we use the host from the redirect URL in the ICE server configuration
const host = new URL(redirectUrl).host;

const iceServers = [
{
urls: `stun:${host}`,
},
{
urls: `turn:${host}`,
username: 'livepeer',
credential: 'livepeer',
},
];

const peerConnection = new RTCPeerConnection({ iceServers });

const newAudioTrack = mergedStream.result?.getAudioTracks?.()?.[0] ?? null;

if (newAudioTrack) {
peerConnection?.addTransceiver(newAudioTrack, {
direction: 'sendonly',
});
}

/**
* https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer
* We create an SDP offer here which will be shared with the server
*/
const offer = await peerConnection.createOffer();
/** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */
await peerConnection.setLocalDescription(offer);

/** Wait for ICE gathering to complete */
const ofr = await new Promise<RTCSessionDescription | null>((resolve) => {
/** Wait at most five seconds for ICE gathering. */
setTimeout(() => {
resolve(peerConnection.localDescription);
}, 5000);
peerConnection.onicegatheringstatechange = (_ev) => {
if (peerConnection.iceGatheringState === 'complete') {
resolve(peerConnection.localDescription);
}
};
});
if (!ofr) {
throw Error('failed to gather ICE candidates for offer');
}
/**
* This response contains the server's SDP offer.
* This specifies how the client should communicate,
* and what kind of media client and server have negotiated to exchange.
*/
const sdpResponse = await fetch(redirectUrl, {
method: 'POST',
mode: 'cors',
headers: {
'content-type': 'application/sdp',
},
body: ofr.sdp,
});
if (sdpResponse.ok) {
const answerSDP = await sdpResponse.text();
await peerConnection.setRemoteDescription(
new RTCSessionDescription({ type: 'answer', sdp: answerSDP })
);
}
// // start the livepeer playback and store the playback URL group meta
// // send a notification/meta message to all the added listeners (members) telling the space has started

// // create the mergeStream object
// const mergedStream = getMergeStreamObject(this.data.local.stream);
// // store the mergeStreamObject
// this.mergedStream = mergedStream;

// const url = 'https://livepeer.studio/api/stream';
// const data = {
// name: this.spaceSpecificData.spaceName,
// record: true,
// };

// const { data: responseData } = await axios.post(url, data, {
// headers: {
// Authorization: 'Bearer ' + livepeerApiKey,
// },
// });

// const { streamKey, playbackId } = responseData;

// console.log('livepeer details', streamKey, playbackId);

// this.update({ meta: playbackId });

// let redirectUrl;
// try {
// console.log('Ignore the following error');

// // the redirect URL from the above GET request
// await axios.get(`https://livepeer.studio/webrtc/${streamKey}`);
// } catch (err: any) {
// console.log('redirectUrl error', err);
// redirectUrl = err.request.responseURL;
// }

// // we use the host from the redirect URL in the ICE server configuration
// const host = new URL(redirectUrl).host;

// const iceServers = [
// {
// urls: `stun:${host}`,
// },
// {
// urls: `turn:${host}`,
// username: 'livepeer',
// credential: 'livepeer',
// },
// ];

// const peerConnection = new RTCPeerConnection({ iceServers });

// const newAudioTrack = mergedStream.result?.getAudioTracks?.()?.[0] ?? null;

// if (newAudioTrack) {
// peerConnection?.addTransceiver(newAudioTrack, {
// direction: 'sendonly',
// });
// }

// /**
// * https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer
// * We create an SDP offer here which will be shared with the server
// */
// const offer = await peerConnection.createOffer();
// /** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */
// await peerConnection.setLocalDescription(offer);

// /** Wait for ICE gathering to complete */
// const ofr = await new Promise<RTCSessionDescription | null>((resolve) => {
// /** Wait at most five seconds for ICE gathering. */
// setTimeout(() => {
// resolve(peerConnection.localDescription);
// }, 5000);
// peerConnection.onicegatheringstatechange = (_ev) => {
// if (peerConnection.iceGatheringState === 'complete') {
// resolve(peerConnection.localDescription);
// }
// };
// });
// if (!ofr) {
// throw Error('failed to gather ICE candidates for offer');
// }
// /**
// * This response contains the server's SDP offer.
// * This specifies how the client should communicate,
// * and what kind of media client and server have negotiated to exchange.
// */
// const sdpResponse = await fetch(redirectUrl, {
// method: 'POST',
// mode: 'cors',
// headers: {
// 'content-type': 'application/sdp',
// },
// body: ofr.sdp,
// });
// if (sdpResponse.ok) {
// const answerSDP = await sdpResponse.text();
// await peerConnection.setRemoteDescription(
// new RTCSessionDescription({ type: 'answer', sdp: answerSDP })
// );
// }

console.log('Live Stream started');
} catch (err) {
Expand Down
Loading

0 comments on commit ddd8122

Please sign in to comment.