Add video/mic mute
This commit is contained in:
parent
cde692f10d
commit
5851d738f8
5 changed files with 269 additions and 174 deletions
|
@ -9287,7 +9287,7 @@ module.exports={
|
|||
"𝐴": "A",
|
||||
"𝑨": "A",
|
||||
"𝒜": "A",
|
||||
"𝓐": "A",
|
||||
"<EFBFBD><EFBFBD><EFBFBD>": "A",
|
||||
"𝔄": "A",
|
||||
"𝔸": "A",
|
||||
"𝕬": "A",
|
||||
|
@ -13735,7 +13735,7 @@ module.exports={
|
|||
"⽒": "氏",
|
||||
"⺠": "民",
|
||||
"⽓": "气",
|
||||
"<EFBFBD><EFBFBD><EFBFBD>": "水",
|
||||
"⽔": "水",
|
||||
"⺡": "氵",
|
||||
"⺢": "氺",
|
||||
"汎": "汎",
|
||||
|
@ -58557,7 +58557,6 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
}
|
||||
this.pushLocalFeed(stream, callEventTypes_1.SDPStreamMetadataPurpose.Usermedia);
|
||||
this.setState(CallState.CreateOffer);
|
||||
logger_1.logger.info("Got local AV stream with id " + this.localUsermediaStream.id);
|
||||
logger_1.logger.debug("gotUserMediaForInvite -> " + this.type);
|
||||
// Now we wait for the negotiationneeded event
|
||||
});
|
||||
|
@ -58566,7 +58565,6 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
return;
|
||||
}
|
||||
this.pushLocalFeed(stream, callEventTypes_1.SDPStreamMetadataPurpose.Usermedia);
|
||||
logger_1.logger.info("Got local AV stream with id " + this.localUsermediaStream.id);
|
||||
this.setState(CallState.CreateAnswer);
|
||||
let myAnswer;
|
||||
try {
|
||||
|
@ -59007,6 +59005,7 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
this.feeds.push(new callFeed_1.CallFeed(stream, userId, purpose, this.client, this.roomId, false, false));
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
}
|
||||
// TODO: Find out what is going on here
|
||||
// why do we enable audio (and only audio) tracks here? -- matthew
|
||||
setTracksEnabled(stream.getAudioTracks(), true);
|
||||
if (addToPeerConnection) {
|
||||
|
@ -59169,9 +59168,6 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (this.localUsermediaStream) {
|
||||
this.gotUserMediaForAnswer(this.localUsermediaStream);
|
||||
}
|
||||
else if (this.waitForLocalAVStream) {
|
||||
this.setState(CallState.WaitLocalMedia);
|
||||
}
|
||||
|
@ -59183,16 +59179,11 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
* @param {MatrixCall} newCall The new call.
|
||||
*/
|
||||
replacedBy(newCall) {
|
||||
logger_1.logger.debug(this.callId + " being replaced by " + newCall.callId);
|
||||
if (this.state === CallState.WaitLocalMedia) {
|
||||
logger_1.logger.debug("Telling new call to wait for local media");
|
||||
newCall.waitForLocalAVStream = true;
|
||||
}
|
||||
else if (this.state === CallState.CreateOffer) {
|
||||
logger_1.logger.debug("Handing local stream to new call");
|
||||
newCall.gotUserMediaForAnswer(this.localUsermediaStream);
|
||||
}
|
||||
else if (this.state === CallState.InviteSent) {
|
||||
else if ([CallState.CreateOffer, CallState.InviteSent].includes(this.state)) {
|
||||
logger_1.logger.debug("Handing local stream to new call");
|
||||
newCall.gotUserMediaForAnswer(this.localUsermediaStream);
|
||||
}
|
||||
|
@ -59841,13 +59832,11 @@ class MatrixCall extends events_1.EventEmitter {
|
|||
stopAllMedia() {
|
||||
logger_1.logger.debug(`stopAllMedia (stream=${this.localUsermediaStream})`);
|
||||
for (const feed of this.feeds) {
|
||||
if (!feed.isLocal()) {
|
||||
for (const track of feed.stream.getTracks()) {
|
||||
track.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkForErrorListener() {
|
||||
if (this.listeners("error").length === 0) {
|
||||
throw new Error("You MUST attach an error listener using call.on('error', function() {})");
|
||||
|
@ -60287,6 +60276,7 @@ class CallEventHandler {
|
|||
return type.startsWith("m.call.") || type.startsWith("org.matrix.call.");
|
||||
}
|
||||
handleCallEvent(event) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const content = event.getContent();
|
||||
const type = event.getType();
|
||||
const weSentTheEvent = event.getSender() === this.client.credentials.userId;
|
||||
|
@ -60321,7 +60311,7 @@ class CallEventHandler {
|
|||
return;
|
||||
}
|
||||
call.callId = content.call_id;
|
||||
const invitePromise = call.initWithInvite(event);
|
||||
const initWithInvitePromise = call.initWithInvite(event);
|
||||
this.calls.set(call.callId, call);
|
||||
// if we stashed candidate events for that call ID, play them back now
|
||||
if (this.candidateEventsByCall.get(call.callId)) {
|
||||
|
@ -60351,6 +60341,8 @@ class CallEventHandler {
|
|||
existingCall.callId > call.callId) {
|
||||
logger_1.logger.log("Glare detected: answering incoming call " + call.callId +
|
||||
" and canceling outgoing call " + existingCall.callId);
|
||||
// Await init with invite as we need a peerConn for the following methods
|
||||
yield initWithInvitePromise;
|
||||
existingCall.replacedBy(call);
|
||||
call.answer();
|
||||
}
|
||||
|
@ -60361,7 +60353,7 @@ class CallEventHandler {
|
|||
}
|
||||
}
|
||||
else {
|
||||
invitePromise.then(() => {
|
||||
initWithInvitePromise.then(() => {
|
||||
this.client.emit("Call.incoming", call);
|
||||
});
|
||||
}
|
||||
|
@ -60438,6 +60430,7 @@ class CallEventHandler {
|
|||
call.onSDPStreamMetadataChangedReceived(event);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.CallEventHandler = CallEventHandler;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -171,6 +171,9 @@ export class ConferenceCallManager extends EventEmitter {
|
|||
|
||||
this.localParticipant = null;
|
||||
|
||||
this.micMuted = false;
|
||||
this.videoMuted = false;
|
||||
|
||||
this.client.on("RoomState.members", this._onRoomStateMembers);
|
||||
this.client.on("Call.incoming", this._onIncomingCall);
|
||||
this.callDebugger = new ConferenceCallDebugger(this);
|
||||
|
@ -307,12 +310,66 @@ export class ConferenceCallManager extends EventEmitter {
|
|||
this.participants = [];
|
||||
this.localParticipant.stream = null;
|
||||
this.localParticipant.call = null;
|
||||
this.micMuted = false;
|
||||
this.videoMuted = false;
|
||||
clearTimeout(this._memberParticipantStateTimeout);
|
||||
|
||||
this.emit("participants_changed");
|
||||
this.emit("left");
|
||||
}
|
||||
|
||||
setMicMuted(muted) {
|
||||
this.micMuted = muted;
|
||||
|
||||
const localStream = this.client.localAVStream;
|
||||
|
||||
if (localStream) {
|
||||
for (const track of localStream.getTracks()) {
|
||||
if (track.kind === "audio") {
|
||||
track.enabled = !this.micMuted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let participant of this.participants) {
|
||||
const call = participant.call;
|
||||
|
||||
if (
|
||||
call &&
|
||||
call.localUsermediaStream &&
|
||||
call.isMicrophoneMuted() !== this.micMuted
|
||||
) {
|
||||
call.setMicrophoneMuted(this.micMuted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setVideoMuted(muted) {
|
||||
this.videoMuted = muted;
|
||||
|
||||
const localStream = this.client.localAVStream;
|
||||
|
||||
if (localStream) {
|
||||
for (const track of localStream.getTracks()) {
|
||||
if (track.kind === "video") {
|
||||
track.enabled = !this.videoMuted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let participant of this.participants) {
|
||||
const call = participant.call;
|
||||
|
||||
if (
|
||||
call &&
|
||||
call.localUsermediaStream &&
|
||||
call.isLocalVideoMuted() !== this.videoMuted
|
||||
) {
|
||||
call.setLocalVideoMuted(this.videoMuted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem("matrix-auth-store");
|
||||
}
|
||||
|
@ -557,6 +614,20 @@ export class ConferenceCallManager extends EventEmitter {
|
|||
*/
|
||||
|
||||
_onCallStateChanged = (participant, call, state) => {
|
||||
if (
|
||||
call.localUsermediaStream &&
|
||||
call.isMicrophoneMuted() !== this.micMuted
|
||||
) {
|
||||
call.setMicrophoneMuted(this.micMuted);
|
||||
}
|
||||
|
||||
if (
|
||||
call.localUsermediaStream &&
|
||||
call.isLocalVideoMuted() !== this.videoMuted
|
||||
) {
|
||||
call.setLocalVideoMuted(this.videoMuted);
|
||||
}
|
||||
|
||||
this.emit("debugstate", participant.userId, call.callId, state);
|
||||
};
|
||||
|
||||
|
|
|
@ -139,14 +139,27 @@ export function useConferenceCallManager(homeserverUrl) {
|
|||
}
|
||||
|
||||
export function useVideoRoom(manager, roomId, timeout = 5000) {
|
||||
const [{ loading, joined, joining, room, participants, error }, setState] =
|
||||
useState({
|
||||
const [
|
||||
{
|
||||
loading,
|
||||
joined,
|
||||
joining,
|
||||
room,
|
||||
participants,
|
||||
error,
|
||||
videoMuted,
|
||||
micMuted,
|
||||
},
|
||||
setState,
|
||||
] = useState({
|
||||
loading: true,
|
||||
joining: false,
|
||||
joined: false,
|
||||
room: undefined,
|
||||
participants: [],
|
||||
error: undefined,
|
||||
videoMuted: false,
|
||||
micMuted: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -305,6 +318,16 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
|
|||
};
|
||||
}, [manager]);
|
||||
|
||||
const toggleMuteMic = useCallback(() => {
|
||||
manager.setMicMuted(!manager.micMuted);
|
||||
setState((prevState) => ({ ...prevState, micMuted: manager.micMuted }));
|
||||
}, [manager]);
|
||||
|
||||
const toggleMuteVideo = useCallback(() => {
|
||||
manager.setVideoMuted(!manager.videoMuted);
|
||||
setState((prevState) => ({ ...prevState, videoMuted: manager.videoMuted }));
|
||||
}, [manager]);
|
||||
|
||||
return {
|
||||
loading,
|
||||
joined,
|
||||
|
@ -314,6 +337,10 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
|
|||
error,
|
||||
joinCall,
|
||||
leaveCall,
|
||||
toggleMuteVideo,
|
||||
toggleMuteMic,
|
||||
videoMuted,
|
||||
micMuted,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ export function Room({ manager }) {
|
|||
error,
|
||||
joinCall,
|
||||
leaveCall,
|
||||
toggleMuteVideo,
|
||||
toggleMuteMic,
|
||||
videoMuted,
|
||||
micMuted,
|
||||
} = useVideoRoom(manager, roomId);
|
||||
const debugStr = query.get("debug");
|
||||
const [debug, setDebug] = useState(debugStr === "" || debugStr === "true");
|
||||
|
@ -113,8 +117,8 @@ export function Room({ manager }) {
|
|||
)}
|
||||
{!loading && room && joined && (
|
||||
<div className={styles.footer}>
|
||||
<MicButton />
|
||||
<VideoButton />
|
||||
<MicButton muted={micMuted} onClick={toggleMuteMic} />
|
||||
<VideoButton enabled={videoMuted} onClick={toggleMuteVideo} />
|
||||
<HangupButton onClick={leaveCall} />
|
||||
</div>
|
||||
)}
|
||||
|
|
Loading…
Reference in a new issue