Fix missing audio.

This commit is contained in:
aforge
2023-01-23 13:27:50 -08:00
parent b766e827c9
commit 2a653f2299
5 changed files with 75 additions and 47 deletions
+40 -28
View File
@@ -32,6 +32,7 @@ class CallPanel extends React.PureComponent {
this.state = { this.state = {
localStream: undefined, localStream: undefined,
remoteStream: undefined,
pc: undefined, pc: undefined,
dataChannel: undefined, dataChannel: undefined,
@@ -82,6 +83,7 @@ class CallPanel extends React.PureComponent {
this.handleGetUserMediaError = this.handleGetUserMediaError.bind(this); this.handleGetUserMediaError = this.handleGetUserMediaError.bind(this);
this.stopTracks = this.stopTracks.bind(this); this.stopTracks = this.stopTracks.bind(this);
this.disconnectMedia = this.disconnectMedia.bind(this);
this.handleCloseClick = this.handleCloseClick.bind(this); this.handleCloseClick = this.handleCloseClick.bind(this);
this.handleToggleCameraClick = this.handleToggleCameraClick.bind(this); this.handleToggleCameraClick = this.handleToggleCameraClick.bind(this);
@@ -124,9 +126,10 @@ class CallPanel extends React.PureComponent {
stream.getTracks().forEach(track => { stream.getTracks().forEach(track => {
pc.addTrack(track, stream); pc.addTrack(track, stream);
if (track.kind == 'video' && !this.localStreamConstraints.video) { if (track.kind == 'video' && this.state.audioOnly) {
// This is an audio-only call. // This is an audio-only call.
// Remove dummy video track (placeholder remains). // Remove dummy video track (placeholder remains).
track.enabled = false;
track.stop(); track.stop();
stream.removeTrack(track); stream.removeTrack(track);
} }
@@ -211,8 +214,10 @@ class CallPanel extends React.PureComponent {
RING_SOUND.pause(); RING_SOUND.pause();
RING_SOUND.currentTime = 0; RING_SOUND.currentTime = 0;
this.stopTracks(this.localRef.current); this.stopTracks(this.state.localStream);
this.stopTracks(this.remoteRef.current); this.stopTracks(this.state.remoteStream);
this.disconnectMedia(this.localRef.current);
this.disconnectMedia(this.remoteRef.current);
if (this.state.pc) { if (this.state.pc) {
this.state.pc.ontrack = null; this.state.pc.ontrack = null;
this.state.pc.onremovetrack = null; this.state.pc.onremovetrack = null;
@@ -233,11 +238,16 @@ class CallPanel extends React.PureComponent {
this.setState({pc: null, waitingForPeer: false}); this.setState({pc: null, waitingForPeer: false});
} }
stopTracks(el) { disconnectMedia(el) {
if (!el) { if (!el) {
return; return;
} }
let stream = el.srcObject;
el.srcObject = null;
el.src = '';
}
stopTracks(stream) {
if (!stream) { if (!stream) {
return; return;
} }
@@ -249,8 +259,6 @@ class CallPanel extends React.PureComponent {
track.enabled = false; track.enabled = false;
}); });
} }
el.srcObject = null;
el.src = '';
} }
handleDataChannelError(error) { handleDataChannelError(error) {
@@ -260,10 +268,10 @@ class CallPanel extends React.PureComponent {
handleDataChannelMessage(event) { handleDataChannelMessage(event) {
switch (event.data) { switch (event.data) {
case VIDEO_MUTED_EVENT: case VIDEO_MUTED_EVENT:
this.setState({remoteVideoLive: false}); this.setState({remoteVideoLive: false}, _ => { this.remoteRef.current.srcObject = this.state.remoteStream; });
break; break;
case VIDEO_UNMUTED_EVENT: case VIDEO_UNMUTED_EVENT:
this.setState({remoteVideoLive: true}); this.setState({remoteVideoLive: true}, _ => { this.remoteRef.current.srcObject = this.state.remoteStream; });
break; break;
default: default:
break; break;
@@ -386,7 +394,7 @@ class CallPanel extends React.PureComponent {
} }
handleICEConnectionStateChangeEvent(event) { handleICEConnectionStateChangeEvent(event) {
switch (this.state.pc.iceConnectionState) { switch (event.target.iceConnectionState) {
case 'closed': case 'closed':
case 'failed': case 'failed':
this.handleCloseClick(); this.handleCloseClick();
@@ -407,9 +415,7 @@ class CallPanel extends React.PureComponent {
handleTrackEvent(event) { handleTrackEvent(event) {
// Remote video becomes available. // Remote video becomes available.
this.remoteRef.current.srcObject = event.streams[0]; this.remoteRef.current.srcObject = event.streams[0];
this.setState({remoteStream: event.streams[0]});
// Make sure we display the title (peer's name) over the remote video.
this.forceUpdate();
} }
handleGetUserMediaError(e) { handleGetUserMediaError(e) {
@@ -458,6 +464,7 @@ class CallPanel extends React.PureComponent {
}); });
if (dummyVideo) { if (dummyVideo) {
dummyVideo.enabled = false;
dummyVideo.stop(); dummyVideo.stop();
stream.removeTrack(dummyVideo); stream.removeTrack(dummyVideo);
} }
@@ -574,12 +581,12 @@ class CallPanel extends React.PureComponent {
const peerTitle = clipStr(this.props.title, MAX_PEER_TITLE_LENGTH); const peerTitle = clipStr(this.props.title, MAX_PEER_TITLE_LENGTH);
const pulseAnimation = this.state.waitingForPeer ? ' pulse' : ''; const pulseAnimation = this.state.waitingForPeer ? ' pulse' : '';
let removeActive = false; let remoteActive = false;
if (this.remoteRef.current && this.remoteRef.current.srcObject && this.state.remoteVideoLive) { if (this.remoteRef.current && this.remoteRef.current.srcObject && this.state.remoteVideoLive) {
const rstream = this.remoteRef.current.srcObject; const rstream = this.remoteRef.current.srcObject;
if (rstream.getVideoTracks().length > 0) { if (rstream.getVideoTracks().length > 0) {
const t = rstream.getVideoTracks()[0]; const t = rstream.getVideoTracks()[0];
removeActive = t.enabled && t.readyState == 'live'; remoteActive = t.enabled && t.readyState == 'live';
} }
} }
@@ -594,20 +601,25 @@ class CallPanel extends React.PureComponent {
defaultMessage="You" description="Shown over the local video screen" /> defaultMessage="You" description="Shown over the local video screen" />
</div> </div>
</div> </div>
<div className="call-party peer" disabled={!removeActive}> <div className="call-party peer" disabled={!remoteActive}>
<video ref={this.remoteRef} autoPlay playsInline /> {remoteActive ?
{removeActive ? <>
<div className="caller-name inactive">{peerTitle}</div> : <video ref={this.remoteRef} autoPlay playsInline />
<div className={`caller-card${pulseAnimation}`}> <div className="caller-name inactive">{peerTitle}</div>
<div className="avatar-box"> </> :
<LetterTile <>
tinode={this.props.tinode} <audio ref={this.remoteRef} autoPlay />
avatar={this.props.avatar} <div className={`caller-card${pulseAnimation}`}>
topic={this.props.topic} <div className="avatar-box">
title={this.props.title} /> <LetterTile
tinode={this.props.tinode}
avatar={this.props.avatar}
topic={this.props.topic}
title={this.props.title} />
</div>
<div className="caller-name">{peerTitle}</div>
</div> </div>
<div className="caller-name">{peerTitle}</div> </>
</div>
} }
</div> </div>
</div> </div>
+32 -16
View File
@@ -10708,6 +10708,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
super(props); super(props);
this.state = { this.state = {
localStream: undefined, localStream: undefined,
remoteStream: undefined,
pc: undefined, pc: undefined,
dataChannel: undefined, dataChannel: undefined,
previousOnInfo: undefined, previousOnInfo: undefined,
@@ -10745,6 +10746,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
this.reportError = this.reportError.bind(this); this.reportError = this.reportError.bind(this);
this.handleGetUserMediaError = this.handleGetUserMediaError.bind(this); this.handleGetUserMediaError = this.handleGetUserMediaError.bind(this);
this.stopTracks = this.stopTracks.bind(this); this.stopTracks = this.stopTracks.bind(this);
this.disconnectMedia = this.disconnectMedia.bind(this);
this.handleCloseClick = this.handleCloseClick.bind(this); this.handleCloseClick = this.handleCloseClick.bind(this);
this.handleToggleCameraClick = this.handleToggleCameraClick.bind(this); this.handleToggleCameraClick = this.handleToggleCameraClick.bind(this);
this.handleToggleMicClick = this.handleToggleMicClick.bind(this); this.handleToggleMicClick = this.handleToggleMicClick.bind(this);
@@ -10778,7 +10780,8 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
const stream = this.state.localStream; const stream = this.state.localStream;
stream.getTracks().forEach(track => { stream.getTracks().forEach(track => {
pc.addTrack(track, stream); pc.addTrack(track, stream);
if (track.kind == 'video' && !this.localStreamConstraints.video) { if (track.kind == 'video' && this.state.audioOnly) {
track.enabled = false;
track.stop(); track.stop();
stream.removeTrack(track); stream.removeTrack(track);
} }
@@ -10852,8 +10855,10 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
CALL_ENDED_SOUND.currentTime = 0; CALL_ENDED_SOUND.currentTime = 0;
RING_SOUND.pause(); RING_SOUND.pause();
RING_SOUND.currentTime = 0; RING_SOUND.currentTime = 0;
this.stopTracks(this.localRef.current); this.stopTracks(this.state.localStream);
this.stopTracks(this.remoteRef.current); this.stopTracks(this.state.remoteStream);
this.disconnectMedia(this.localRef.current);
this.disconnectMedia(this.remoteRef.current);
if (this.state.pc) { if (this.state.pc) {
this.state.pc.ontrack = null; this.state.pc.ontrack = null;
this.state.pc.onremovetrack = null; this.state.pc.onremovetrack = null;
@@ -10875,11 +10880,14 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
waitingForPeer: false waitingForPeer: false
}); });
} }
stopTracks(el) { disconnectMedia(el) {
if (!el) { if (!el) {
return; return;
} }
let stream = el.srcObject; el.srcObject = null;
el.src = '';
}
stopTracks(stream) {
if (!stream) { if (!stream) {
return; return;
} }
@@ -10890,8 +10898,6 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
track.enabled = false; track.enabled = false;
}); });
} }
el.srcObject = null;
el.src = '';
} }
handleDataChannelError(error) { handleDataChannelError(error) {
console.error('data channel error', error); console.error('data channel error', error);
@@ -10901,11 +10907,15 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
case VIDEO_MUTED_EVENT: case VIDEO_MUTED_EVENT:
this.setState({ this.setState({
remoteVideoLive: false remoteVideoLive: false
}, _ => {
this.remoteRef.current.srcObject = this.state.remoteStream;
}); });
break; break;
case VIDEO_UNMUTED_EVENT: case VIDEO_UNMUTED_EVENT:
this.setState({ this.setState({
remoteVideoLive: true remoteVideoLive: true
}, _ => {
this.remoteRef.current.srcObject = this.state.remoteStream;
}); });
break; break;
default: default:
@@ -11013,7 +11023,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
this.remoteIceCandidatesCache = []; this.remoteIceCandidatesCache = [];
} }
handleICEConnectionStateChangeEvent(event) { handleICEConnectionStateChangeEvent(event) {
switch (this.state.pc.iceConnectionState) { switch (event.target.iceConnectionState) {
case 'closed': case 'closed':
case 'failed': case 'failed':
this.handleCloseClick(); this.handleCloseClick();
@@ -11028,7 +11038,9 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
handleICEGatheringStateChangeEvent(event) {} handleICEGatheringStateChangeEvent(event) {}
handleTrackEvent(event) { handleTrackEvent(event) {
this.remoteRef.current.srcObject = event.streams[0]; this.remoteRef.current.srcObject = event.streams[0];
this.forceUpdate(); this.setState({
remoteStream: event.streams[0]
});
} }
handleGetUserMediaError(e) { handleGetUserMediaError(e) {
console.error("Error opening camera and/or microphone", e); console.error("Error opening camera and/or microphone", e);
@@ -11066,6 +11078,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
pc.addTrack(track, localStream); pc.addTrack(track, localStream);
}); });
if (dummyVideo) { if (dummyVideo) {
dummyVideo.enabled = false;
dummyVideo.stop(); dummyVideo.stop();
stream.removeTrack(dummyVideo); stream.removeTrack(dummyVideo);
} }
@@ -11168,12 +11181,12 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
const videoIcon = videoTracks && videoTracks[0] && videoTracks[0].enabled && videoTracks[0].readyState == 'live' ? 'videocam' : 'videocam_off'; const videoIcon = videoTracks && videoTracks[0] && videoTracks[0].enabled && videoTracks[0].readyState == 'live' ? 'videocam' : 'videocam_off';
const peerTitle = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_5__.clipStr)(this.props.title, _config_js__WEBPACK_IMPORTED_MODULE_3__.MAX_PEER_TITLE_LENGTH); const peerTitle = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_5__.clipStr)(this.props.title, _config_js__WEBPACK_IMPORTED_MODULE_3__.MAX_PEER_TITLE_LENGTH);
const pulseAnimation = this.state.waitingForPeer ? ' pulse' : ''; const pulseAnimation = this.state.waitingForPeer ? ' pulse' : '';
let removeActive = false; let remoteActive = false;
if (this.remoteRef.current && this.remoteRef.current.srcObject && this.state.remoteVideoLive) { if (this.remoteRef.current && this.remoteRef.current.srcObject && this.state.remoteVideoLive) {
const rstream = this.remoteRef.current.srcObject; const rstream = this.remoteRef.current.srcObject;
if (rstream.getVideoTracks().length > 0) { if (rstream.getVideoTracks().length > 0) {
const t = rstream.getVideoTracks()[0]; const t = rstream.getVideoTracks()[0];
removeActive = t.enabled && t.readyState == 'live'; remoteActive = t.enabled && t.readyState == 'live';
} }
} }
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { return react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -11198,14 +11211,17 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
}] }]
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "call-party peer", className: "call-party peer",
disabled: !removeActive disabled: !remoteActive
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("video", { }, remoteActive ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("video", {
ref: this.remoteRef, ref: this.remoteRef,
autoPlay: true, autoPlay: true,
playsInline: true playsInline: true
}), removeActive ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "caller-name inactive" className: "caller-name inactive"
}, peerTitle) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, peerTitle)) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("audio", {
ref: this.remoteRef,
autoPlay: true
}), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: `caller-card${pulseAnimation}` className: `caller-card${pulseAnimation}`
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "avatar-box" className: "avatar-box"
@@ -11216,7 +11232,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
title: this.props.title title: this.props.title
})), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { })), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "caller-name" className: "caller-name"
}, peerTitle)))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, peerTitle))))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "controls" className: "controls"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
className: "danger", className: "danger",
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long