2.26.0
2.26.0 (December 14, 2022)
New Features
-
The
LocalAudioTrack
and
LocalVideoTrack
classes now provide a
new boolean property calledisMuted
, which lets you know if the audio or video source is currently providing raw media
samples. The classes also emitmuted
andunmuted
events if the value ofisMuted
toggles. The application can use
these APIs to detect temporary loss of microphone or camera to other applications (ex: an incoming phone call on an iOS device),
and update the user interface accordingly. (VIDEO-11360) -
The
Room
class provides a new method called refreshInactiveMedia,
which restarts any muted local media Tracks, and plays any inadvertently paused HTMLMediaElements that are attached to
local and remote media Tracks. This is useful especially on iOS devices, where sometimes your application's media may
not recover after an incoming phone call. You can use this method in conjunction with the local media Track'sisMuted
property described previously to recover local and remote media after an incoming phone call as shown below. (VIDEO-11360)Vanilla JS
html
<button id="refresh-inactive-media" disabled>Refresh Inactive Media</button>
js
const { connect } = require('twilio-video'); const room = await connect('token', { name: 'my-cool-room' }); const $refreshInactiveMedia = document.getElementById('refresh-inactive-media'); $refreshInactiveMedia.onclick = () => room.refreshInactiveMedia(); const [{ track: localAudioTrack }] = [...room.localParticipant.audioTracks.values()]; const [{ track: localVideoTrack }] = [...room.localParticipant.videoTracks.values()]; const isLocalAudioOrVideoMuted = () => { return localAudioTrack.isMuted || localVideoTrack.isMuted; } const onLocalMediaMutedChanged = () => { $refreshInactiveMedia.disabled = !isLocalAudioOrVideoMuted(); }; [localAudioTrack, localVideoTrack].forEach(localMediaTrack => { ['muted', 'unmuted'].forEach(event => { localMediaTrack.on(event, onLocalMediaMutedChanged); }); });
React
src/hooks/useLocalMediaMuted.js
import { useEffect, useState } from 'react'; export default function useLocalMediaMuted(localMediaTrack) { const [isMuted, setIsMuted] = useState(localMediaTrack?.isMuted ?? false); useEffect(() => { const updateMuted = () => setIsMuted(localMediaTrack?.isMuted ?? false); updateMuted(); localMediaTrack?.on('muted', updateMuted); localMediaTrack?.on('unmuted', updateMuted); return () => { localMediaTrack?.off('muted', updateMuted); localMediaTrack?.off('unmuted', updateMuted); }; }, [localMediaTrack]); return isMuted; }
src/components/room.js
import useLocalMediaMuted from '../hooks/useLocalMediaMuted'; export default function Room({ room }) { const [{ track: localAudioTrack }] = [...room.localParticipant.audioTracks.values()]; const [{ track: localVideoTrack }] = [...room.localParticipant.videoTracks.values()]; const isLocalAudioMuted = useLocalMediaMuted(localAudioTrack); const isLocalVideoMuted = useLocalMediaMuted(localVideoTrack); const isLocalMediaMuted = isLocalAudioMuted || isLocalVideoMuted; const refreshInactiveMedia = () => { room.refreshInactiveMedia(); }; return ( <> ... {isLocalMediaMuted && <Button onClick={refreshInactiveMedia}> Refresh Inactive Media </Button>} ... </> ); }