Fix media handler device changes
This commit is contained in:
parent
2c3ebd4c03
commit
42e2041d6f
1 changed files with 73 additions and 13 deletions
|
@ -9,6 +9,32 @@ import React, {
|
||||||
|
|
||||||
const MediaHandlerContext = createContext();
|
const MediaHandlerContext = createContext();
|
||||||
|
|
||||||
|
function getMediaPreferences() {
|
||||||
|
const mediaPreferences = localStorage.getItem("matrix-media-preferences");
|
||||||
|
|
||||||
|
if (mediaPreferences) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(mediaPreferences);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMediaPreferences(newPreferences) {
|
||||||
|
const oldPreferences = getMediaPreferences(newPreferences);
|
||||||
|
|
||||||
|
localStorage.setItem(
|
||||||
|
"matrix-media-preferences",
|
||||||
|
JSON.stringify({
|
||||||
|
...oldPreferences,
|
||||||
|
...newPreferences,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function MediaHandlerProvider({ client, children }) {
|
export function MediaHandlerProvider({ client, children }) {
|
||||||
const [
|
const [
|
||||||
{
|
{
|
||||||
|
@ -21,8 +47,14 @@ export function MediaHandlerProvider({ client, children }) {
|
||||||
},
|
},
|
||||||
setState,
|
setState,
|
||||||
] = useState(() => {
|
] = useState(() => {
|
||||||
|
const mediaPreferences = getMediaPreferences();
|
||||||
const mediaHandler = client.getMediaHandler();
|
const mediaHandler = client.getMediaHandler();
|
||||||
|
|
||||||
|
mediaHandler.restoreMediaSettings(
|
||||||
|
mediaPreferences?.audioInput,
|
||||||
|
mediaPreferences?.videoInput
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
audioInput: mediaHandler.audioInput,
|
audioInput: mediaHandler.audioInput,
|
||||||
videoInput: mediaHandler.videoInput,
|
videoInput: mediaHandler.videoInput,
|
||||||
|
@ -38,42 +70,67 @@ export function MediaHandlerProvider({ client, children }) {
|
||||||
|
|
||||||
function updateDevices() {
|
function updateDevices() {
|
||||||
navigator.mediaDevices.enumerateDevices().then((devices) => {
|
navigator.mediaDevices.enumerateDevices().then((devices) => {
|
||||||
|
const mediaPreferences = getMediaPreferences();
|
||||||
|
|
||||||
const audioInputs = devices.filter(
|
const audioInputs = devices.filter(
|
||||||
(device) => device.kind === "audioinput"
|
(device) => device.kind === "audioinput"
|
||||||
);
|
);
|
||||||
|
const audioConnected = audioInputs.some(
|
||||||
|
(device) => device.deviceId === mediaHandler.audioInput
|
||||||
|
);
|
||||||
|
|
||||||
|
let audioInput = mediaHandler.audioInput;
|
||||||
|
|
||||||
|
if (!audioConnected && audioInputs.length > 0) {
|
||||||
|
audioInput = audioInputs[0].deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
const videoInputs = devices.filter(
|
const videoInputs = devices.filter(
|
||||||
(device) => device.kind === "videoinput"
|
(device) => device.kind === "videoinput"
|
||||||
);
|
);
|
||||||
|
const videoConnected = videoInputs.some(
|
||||||
|
(device) => device.deviceId === mediaHandler.videoInput
|
||||||
|
);
|
||||||
|
|
||||||
|
let videoInput = mediaHandler.videoInput;
|
||||||
|
|
||||||
|
if (!videoConnected && videoInputs.length > 0) {
|
||||||
|
videoInput = videoInputs[0].deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
const audioOutputs = devices.filter(
|
const audioOutputs = devices.filter(
|
||||||
(device) => device.kind === "audiooutput"
|
(device) => device.kind === "audiooutput"
|
||||||
);
|
);
|
||||||
|
|
||||||
let audioOutput = undefined;
|
let audioOutput = undefined;
|
||||||
|
|
||||||
const audioOutputPreference = localStorage.getItem(
|
|
||||||
"matrix-audio-output"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
audioOutputPreference &&
|
mediaPreferences &&
|
||||||
audioOutputs.some(
|
audioOutputs.some(
|
||||||
(device) => device.deviceId === audioOutputPreference
|
(device) => device.deviceId === mediaPreferences.audioOutput
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
audioOutput = audioOutputPreference;
|
audioOutput = mediaPreferences.audioOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
mediaHandler.videoInput !== videoInput ||
|
||||||
|
mediaHandler.audioInput !== audioInput
|
||||||
|
) {
|
||||||
|
mediaHandler.setMediaInputs(audioInput, videoInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMediaPreferences({ audioInput, videoInput, audioOutput });
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
audioInput: mediaHandler.audioInput,
|
audioInput,
|
||||||
videoInput: mediaHandler.videoInput,
|
videoInput,
|
||||||
audioOutput,
|
audioOutput,
|
||||||
audioInputs,
|
audioInputs,
|
||||||
audioOutputs,
|
|
||||||
videoInputs,
|
videoInputs,
|
||||||
|
audioOutputs,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDevices();
|
updateDevices();
|
||||||
|
|
||||||
mediaHandler.on("local_streams_changed", updateDevices);
|
mediaHandler.on("local_streams_changed", updateDevices);
|
||||||
|
@ -82,11 +139,13 @@ export function MediaHandlerProvider({ client, children }) {
|
||||||
return () => {
|
return () => {
|
||||||
mediaHandler.removeListener("local_streams_changed", updateDevices);
|
mediaHandler.removeListener("local_streams_changed", updateDevices);
|
||||||
navigator.mediaDevices.removeEventListener("devicechange", updateDevices);
|
navigator.mediaDevices.removeEventListener("devicechange", updateDevices);
|
||||||
|
mediaHandler.stopAllStreams();
|
||||||
};
|
};
|
||||||
}, [client]);
|
}, [client]);
|
||||||
|
|
||||||
const setAudioInput = useCallback(
|
const setAudioInput = useCallback(
|
||||||
(deviceId) => {
|
(deviceId) => {
|
||||||
|
updateMediaPreferences({ audioInput: deviceId });
|
||||||
setState((prevState) => ({ ...prevState, audioInput: deviceId }));
|
setState((prevState) => ({ ...prevState, audioInput: deviceId }));
|
||||||
client.getMediaHandler().setAudioInput(deviceId);
|
client.getMediaHandler().setAudioInput(deviceId);
|
||||||
},
|
},
|
||||||
|
@ -95,6 +154,7 @@ export function MediaHandlerProvider({ client, children }) {
|
||||||
|
|
||||||
const setVideoInput = useCallback(
|
const setVideoInput = useCallback(
|
||||||
(deviceId) => {
|
(deviceId) => {
|
||||||
|
updateMediaPreferences({ videoInput: deviceId });
|
||||||
setState((prevState) => ({ ...prevState, videoInput: deviceId }));
|
setState((prevState) => ({ ...prevState, videoInput: deviceId }));
|
||||||
client.getMediaHandler().setVideoInput(deviceId);
|
client.getMediaHandler().setVideoInput(deviceId);
|
||||||
},
|
},
|
||||||
|
@ -102,7 +162,7 @@ export function MediaHandlerProvider({ client, children }) {
|
||||||
);
|
);
|
||||||
|
|
||||||
const setAudioOutput = useCallback((deviceId) => {
|
const setAudioOutput = useCallback((deviceId) => {
|
||||||
localStorage.setItem("matrix-audio-output", deviceId);
|
updateMediaPreferences({ audioOutput: deviceId });
|
||||||
setState((prevState) => ({ ...prevState, audioOutput: deviceId }));
|
setState((prevState) => ({ ...prevState, audioOutput: deviceId }));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue