rename setOutputDevices-> setAvailableOutputDevices

This commit is contained in:
Timo
2025-05-15 17:20:12 +02:00
parent 7fa534d70d
commit 610e792394
3 changed files with 31 additions and 12 deletions

View File

@@ -12,7 +12,8 @@ A few aspects of Element Call's interface can be controlled through a global API
These functions must be used in conjunction with the `controlledOutput` URL parameter in order to have any effect. These functions must be used in conjunction with the `controlledOutput` URL parameter in order to have any effect.
- `controls.setOutputDevices(devices: { id: string, name: string, forEarpiece?: boolean }[]): void` Sets the list of available audio outputs. `forEarpiece` is used on ios only. - `controls.setAvailableOutputDevices(devices: { id: string, name: string, forEarpiece?: boolean }[]): void` Sets the list of available audio outputs. `forEarpiece` is used on ios only.
It flags the device that should be used if the user selects earpice mode. This should be the main (stereo loudspeaker) of the device. It flags the device that should be used if the user selects earpice mode. This should be the main (stereo loudspeaker) of the device.
- `controls.onOutputDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output. - `controls.onOutputDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output.
- `controls.setOutputDevice(id: string): void` Sets the selected audio device in EC menu. This should be used if the os decides to automatically switch to bluetooth.
- `controls.setOutputEnabled(enabled: boolean)` Enables/disables all audio output from the application. This can be useful for temporarily pausing audio while the controlling application is switching output devices. Output is enabled by default. - `controls.setOutputEnabled(enabled: boolean)` Enables/disables all audio output from the application. This can be useful for temporarily pausing audio while the controlling application is switching output devices. Output is enabled by default.

View File

@@ -11,7 +11,8 @@ export interface Controls {
canEnterPip(): boolean; canEnterPip(): boolean;
enablePip(): void; enablePip(): void;
disablePip(): void; disablePip(): void;
setOutputDevices(devices: OutputDevice[]): void; setAvailableOutputDevices(devices: OutputDevice[]): void;
setOutputDevice(id: string): void;
onOutputDeviceSelect?: (id: string) => void; onOutputDeviceSelect?: (id: string) => void;
setOutputEnabled(enabled: boolean): void; setOutputEnabled(enabled: boolean): void;
} }
@@ -23,7 +24,8 @@ export interface OutputDevice {
} }
export const setPipEnabled$ = new Subject<boolean>(); export const setPipEnabled$ = new Subject<boolean>();
export const setOutputDevices$ = new Subject<OutputDevice[]>(); export const setAvailableOutputDevices$ = new Subject<OutputDevice[]>();
export const setOutputDevice$ = new Subject<string>();
export const setOutputEnabled$ = new Subject<boolean>(); export const setOutputEnabled$ = new Subject<boolean>();
window.controls = { window.controls = {
@@ -38,10 +40,15 @@ window.controls = {
if (!setPipEnabled$.observed) throw new Error("No call is running"); if (!setPipEnabled$.observed) throw new Error("No call is running");
setPipEnabled$.next(false); setPipEnabled$.next(false);
}, },
setOutputDevices(devices: OutputDevice[]): void { setAvailableOutputDevices(devices: OutputDevice[]): void {
if (!setOutputDevices$.observed) if (!setAvailableOutputDevices$.observed)
throw new Error("Output controls are disabled"); throw new Error("Output controls are disabled");
setOutputDevices$.next(devices); setAvailableOutputDevices$.next(devices);
},
setOutputDevice(id: string): void {
if (!setOutputDevice$.observed)
throw new Error("Output controls are disabled");
setOutputDevice$.next(id);
}, },
setOutputEnabled(enabled: boolean): void { setOutputEnabled(enabled: boolean): void {
if (!setOutputEnabled$.observed) if (!setOutputEnabled$.observed)

View File

@@ -29,7 +29,11 @@ import {
alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting, alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting,
type Setting, type Setting,
} from "../settings/settings"; } from "../settings/settings";
import { type OutputDevice, setOutputDevices$ } from "../controls"; import {
type OutputDevice,
setAvailableOutputDevices$,
setOutputDevice$,
} from "../controls";
import { useUrlParams } from "../UrlParams"; import { useUrlParams } from "../UrlParams";
export const EARPIECE_CONFIG_ID = "earpiece-id"; export const EARPIECE_CONFIG_ID = "earpiece-id";
@@ -299,7 +303,7 @@ function useControlledOutput(): MediaDeviceHandle {
startWith(alwaysShowIphoneEarpieceSetting.getValue()), startWith(alwaysShowIphoneEarpieceSetting.getValue()),
map((v) => v || navigator.userAgent.includes("iPhone")), map((v) => v || navigator.userAgent.includes("iPhone")),
); );
const outputDeviceData$ = setOutputDevices$.pipe( const outputDeviceData$ = setAvailableOutputDevices$.pipe(
startWith<OutputDevice[]>([]), startWith<OutputDevice[]>([]),
map((devices) => { map((devices) => {
const physicalDeviceForEarpiceMode = devices.find( const physicalDeviceForEarpiceMode = devices.find(
@@ -316,15 +320,22 @@ function useControlledOutput(): MediaDeviceHandle {
return combineLatest([outputDeviceData$, showEarpice$]).pipe( return combineLatest([outputDeviceData$, showEarpice$]).pipe(
map(([{ devicesMap, physicalDeviceForEarpiceMode }, showEarpiece]) => { map(([{ devicesMap, physicalDeviceForEarpiceMode }, showEarpiece]) => {
if (showEarpiece && !!physicalDeviceForEarpiceMode) let available = devicesMap;
devicesMap.set(EARPIECE_CONFIG_ID, { type: "earpiece" }); if (showEarpiece && !!physicalDeviceForEarpiceMode) {
return { available: devicesMap, physicalDeviceForEarpiceMode }; available = new Map([
...devicesMap.entries(),
[EARPIECE_CONFIG_ID, { type: "earpiece" }],
]);
}
return { available, physicalDeviceForEarpiceMode };
}), }),
); );
}), }),
); );
const [preferredId, setPreferredId] = useSetting(audioOutputSetting); const [preferredId, setPreferredId] = useSetting(audioOutputSetting);
useEffect(() => {
setOutputDevice$.subscribe((id) => setPreferredId(id));
}, [setPreferredId]);
const selectedId = useMemo(() => { const selectedId = useMemo(() => {
if (available.size) { if (available.size) {