Skip to content

Commit dcb7bb2

Browse files
Audio Channel working beta and toggle fix
Co-authored-by: Isaac Mbambo <isaac.m00101@gmail.com>
1 parent 55418b7 commit dcb7bb2

File tree

4 files changed

+135
-39
lines changed

4 files changed

+135
-39
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
// possibly not the best practice implementation for audio playback ?
3+
interface Props {
4+
streamType: 'localstream' | 'remotestream';
5+
}
6+
const WebRTCAudioBox: React.FC<Props> = (props: Props) => {
7+
const { streamType } = props;
8+
return (
9+
<div className="m-1" style={{ maxWidth: '350px', position: 'relative' }}>
10+
<video
11+
id={`${streamType}`}
12+
autoPlay
13+
playsInline
14+
style={{ width: '0%', height: '0%' }}
15+
></video>
16+
<a
17+
className="is-rest-invert pl-2 pr-2 p-1 mb-2 mr-2"
18+
style={{ position: 'absolute', bottom: '10px', right: '10px' }}
19+
>
20+
{streamType}
21+
</a>
22+
</div>
23+
);
24+
};
25+
26+
export default WebRTCAudioBox;
27+

src/client/components/main/WebRTC-composer/WebRTCComposer.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import NewRequestButton from '../sharedComponents/requestButtons/NewRequestButto
1313
// Import MUI components
1414
import { Box } from '@mui/material';
1515
import WebRTCVideoBox from './WebRTCVideoBox';
16+
import WebRTCAudioBox from './WebRTCAudioBox';
1617
import { RootState } from '../../../toolkit-refactor/store';
1718
import {
1819
useAppDispatch,
@@ -109,12 +110,18 @@ export default function WebRTCComposer() {
109110
<WebRTCServerEntryForm />
110111
<div className="is-3rem-footer is-clickable is-margin-top-auto">
111112
<NewRequestButton onClick={addNewRequest} />
112-
{newRequestWebRTC.webRTCDataChannel === 'Video' && (
113-
<div className="box is-rest-invert">
114-
<WebRTCVideoBox streamType="localstream" />
115-
</div>
116-
)}
117113
</div>
114+
{newRequestWebRTC.webRTCDataChannel === 'Video' && (
115+
<div className="box is-rest-invert">
116+
<WebRTCVideoBox streamType="localstream" />
117+
</div>
118+
)}
119+
120+
{newRequestWebRTC.webRTCDataChannel === 'Audio' && (
121+
<div className="box is-rest-invert">
122+
<WebRTCAudioBox streamType="localstream" />
123+
</div>
124+
)}
118125
</>
119126
)}
120127
</div>

src/client/components/main/WebRTC-composer/WebRTCServerEntryForm.tsx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import { MdRefresh } from 'react-icons/md';
33

44
// import '/Users/katharinehunt/Swell/src/assets/style/WebRtcEntry.css';
@@ -38,15 +38,22 @@ const WebRTCServerEntryForm: React.FC<Props> = () => {
3838
(store: RootState) => store.newRequest.newRequestWebRTC
3939
);
4040
const [isToggled, setIsToggled] = useState(false);
41+
const currentReqRes = useAppSelector(
42+
(store: RootState) => store.reqRes.currentResponse
43+
) as ReqRes;
44+
45+
useEffect(() => {
46+
setIsToggled(newRequestWebRTC.enableAudio as boolean);
47+
}, [newRequestWebRTC.enableAudio]);
4148

4249
const handleToggleChange = () => {
4350
// toggles state os is toggled
4451
const newToggleState = !isToggled;
4552
setIsToggled(newToggleState);
46-
console.log(
47-
'Dispatching newRequestWebRTCSet with enableAudio:',
48-
newToggleState
49-
);
53+
// console.log(
54+
// 'Dispatching newRequestWebRTCSet with enableAudio for handleToggleChange:',
55+
// newToggleState
56+
// );
5057

5158
dispatch(
5259
//sends action to redux store
@@ -57,12 +64,19 @@ const WebRTCServerEntryForm: React.FC<Props> = () => {
5764
enableAudio: newToggleState, //updates Enableaudio property in newRequestWebRTC to match toggle state
5865
}) //enable audio updated every time toggle state changes
5966
);
60-
console.log(
61-
'enableAudio Redux state just after dispatch:',
62-
newRequestWebRTC.enableAudio
67+
68+
// console.log(
69+
// 'enableAudio Redux state just after dispatch:',
70+
// newRequestWebRTC.enableAudio
71+
// );
72+
webrtcPeerController.createPeerConnection(
73+
{
74+
...newRequestWebRTC,
75+
enableAudio: newToggleState,
76+
},
77+
currentReqRes
6378
);
6479
};
65-
6680
return (
6781
<div className="mt-3">
6882
<div className="toggle-refresh-container">
@@ -107,10 +121,10 @@ const WebRTCServerEntryForm: React.FC<Props> = () => {
107121
dispatch(
108122
newRequestWebRTCSet({ ...newRequestWebRTC, webRTCOffer: value })
109123
);
110-
console.log(
111-
'value after dispatch, Im assuming it is the same:',
112-
value
113-
);
124+
// console.log(
125+
// 'value after dispatch, Im assuming it is the same:',
126+
// value
127+
// );
114128
}}
115129
placeholder={'Click "Get Offer" or paste in Offer SDP'}
116130
readOnly={true}

src/client/controllers/webrtcPeerController.ts

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const webrtcPeerController = {
1919
newRequestWebRTC: RequestWebRTC,
2020
currentReqRes: ReqRes
2121
) => {
22+
// const enableAudio =
23+
// store.getState().newRequest.newRequestWebRTC.enableAudio ?? false;
2224
const enableAudio = newRequestWebRTC.enableAudio ?? false; //if null set to false
2325

2426
let servers = {
@@ -35,7 +37,7 @@ const webrtcPeerController = {
3537
// request access to user camera
3638
video: true, // request access to video
3739
audio: enableAudio, //if enable audio is true request access to audio //not if false
38-
}); // from
40+
});
3941

4042
if (document.getElementById('localstream')) {
4143
(<HTMLVideoElement>document.getElementById('localstream')).srcObject =
@@ -62,44 +64,90 @@ const webrtcPeerController = {
6264
enableAudio,
6365
})
6466
);
65-
}
66-
if (newRequestWebRTC.webRTCDataChannel === 'Audio') {
67+
peerConnection.onicecandidate = async (
68+
event: RTCPeerConnectionIceEvent
69+
): Promise<void> => {
70+
if (
71+
event.candidate &&
72+
peerConnection.localDescription!.type === 'offer'
73+
) {
74+
appDispatch(
75+
newRequestWebRTCOfferSet(
76+
JSON.stringify(peerConnection.localDescription)
77+
)
78+
);
79+
} else if (
80+
event.candidate &&
81+
peerConnection.localDescription!.type === 'answer'
82+
) {
83+
appDispatch(
84+
newRequestWebRTCAnswerSet(
85+
JSON.stringify(peerConnection.localDescription)
86+
)
87+
);
88+
}
89+
};
90+
} else if (newRequestWebRTC.webRTCDataChannel === 'Audio') {
6791
let localStream = await navigator.mediaDevices.getUserMedia({
68-
// accesses user audio
69-
video: false,
70-
audio: true,
71-
});
92+
// request access to user camera
93+
video: false, // request access to video
94+
audio: true, //if enable audio is true request access to audio //not if false
95+
}); // from
96+
97+
if (document.getElementById('localstream')) {
98+
(<HTMLVideoElement>document.getElementById('localstream')).srcObject =
99+
localStream;
100+
}
72101

73-
console.log('Local Audio Tracks Captured:', localStream.getTracks());
74102
localStream.getTracks().forEach((track) => {
75103
// iterates over tracks in local stream
76-
console.log(`adding track: ${track.kind}`);
77-
peerConnection.addTrack(track, localStream); // adds them to the peer connection using add track
78-
});
104+
peerConnection.addTrack(track, localStream);
105+
}); // adds them to the peer connection using add track
79106

80-
let remoteStream = new MediaStream(); // initialize new media stream object
81-
//to hold audio tracks from remote peer
107+
let remoteStream = new MediaStream(); //initialize new media stream object
82108
peerConnection.ontrack = async (event) => {
83-
// sets up an event handler fro on track event of peer connection object
84-
console.log(`recieved remote track: ${event.track.kind}`);
109+
// adds them to the peer connection using add track
85110
event.streams[0].getTracks().forEach((track) => {
86-
// iterates over each track recieved to the remote stream object// returns array of tracks
111+
// sets up an event handler for on track event of peer connection object
112+
// returns array of tracks
87113
remoteStream.addTrack(track);
88114
});
89115
};
90116

91117
appDispatch(
92118
// update redux state
93119
newRequestWebRTCSet({
94-
// new state object is created to update redux state
95-
...newRequestWebRTC, //copy properties from existing state object
120+
//new state object is created to update redux object
121+
...newRequestWebRTC, // copy properties from existing object
96122
webRTCpeerConnection: peerConnection,
97123
webRTCLocalStream: localStream,
98-
webRTCRemoteStream: remoteStream, //remote stream overwritten
124+
webRTCRemoteStream: remoteStream, // remote stream overwritten
99125
})
100126
);
101-
}
102-
if (newRequestWebRTC.webRTCDataChannel === 'Text') {
127+
peerConnection.onicecandidate = async (
128+
event: RTCPeerConnectionIceEvent
129+
): Promise<void> => {
130+
if (
131+
event.candidate &&
132+
peerConnection.localDescription!.type === 'offer'
133+
) {
134+
appDispatch(
135+
newRequestWebRTCOfferSet(
136+
JSON.stringify(peerConnection.localDescription)
137+
)
138+
);
139+
} else if (
140+
event.candidate &&
141+
peerConnection.localDescription!.type === 'answer'
142+
) {
143+
appDispatch(
144+
newRequestWebRTCAnswerSet(
145+
JSON.stringify(peerConnection.localDescription)
146+
)
147+
);
148+
}
149+
};
150+
} else if (newRequestWebRTC.webRTCDataChannel === 'Text') {
103151
// const { request, response } = currentReqRes as {
104152
// request: RequestWebRTCText;
105153
// response: ResponseWebRTCText;

0 commit comments

Comments
 (0)