forked from react-native-webrtc/react-native-webrtc
-
Notifications
You must be signed in to change notification settings - Fork 30
[WIP] Add configurable audio device ID for WebRTC on Android #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
jonathanphilippou
wants to merge
5
commits into
livekit:master
from
jonathanphilippou:feature/configurable-audio-device-id
Closed
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
b7b62a1
feat: make audio device ID configurable
jonathanphilippou 98c1e6d
fix: handling of complex deviceId constraint objects
jonathanphilippou 2fd120d
Added distinctive log message
jonathanphilippou 3bef58c
add fork version number
jonathanphilippou 0a6ba92
Improved deviceId handling to fix type casting errors and incremented…
jonathanphilippou File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { NativeModules } from 'react-native' | ||
const { WebRTCModule } = NativeModules | ||
|
||
/** | ||
* Set the default audio device ID to use when no specific device is requested. | ||
* This allows applications to control which audio device is used by default. | ||
* | ||
* @param deviceId - The device ID to use as default (e.g., "audio-1", "expo-av-audio", etc.) | ||
*/ | ||
export function setDefaultAudioDeviceId(deviceId: string): void { | ||
if (typeof deviceId !== 'string' || !deviceId.trim()) { | ||
throw new TypeError('deviceId must be a non-empty string') | ||
Check failure on line 12 in src/AudioDeviceModule.ts
|
||
} | ||
|
||
WebRTCModule.setDefaultAudioDeviceId(deviceId) | ||
Check failure on line 15 in src/AudioDeviceModule.ts
|
||
} | ||
|
||
/** | ||
* Get the current default audio device ID. | ||
* | ||
* @returns A promise that resolves to the current default audio device ID | ||
*/ | ||
export function getDefaultAudioDeviceId(): Promise<string> { | ||
return WebRTCModule.getDefaultAudioDeviceId() | ||
Check failure on line 24 in src/AudioDeviceModule.ts
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,115 @@ | ||
import { NativeModules, Platform } from 'react-native'; | ||
const { WebRTCModule } = NativeModules; | ||
import { NativeModules, Platform } from 'react-native' | ||
const { WebRTCModule } = NativeModules | ||
|
||
if (WebRTCModule === null) { | ||
throw new Error(`WebRTC native module not found.\n${Platform.OS === 'ios' ? | ||
'Try executing the "pod install" command inside your projects ios folder.' : | ||
'Try executing the "npm install" command inside your projects folder.' | ||
}`); | ||
throw new Error( | ||
`WebRTC native module not found.\n${ | ||
Platform.OS === 'ios' | ||
? 'Try executing the "pod install" command inside your projects ios folder.' | ||
: 'Try executing the "npm install" command inside your projects folder.' | ||
}`, | ||
) | ||
} | ||
|
||
import { setupNativeEvents } from './EventEmitter'; | ||
import Logger from './Logger'; | ||
import mediaDevices from './MediaDevices'; | ||
import MediaStream from './MediaStream'; | ||
import MediaStreamTrack, { type MediaTrackSettings } from './MediaStreamTrack'; | ||
import MediaStreamTrackEvent from './MediaStreamTrackEvent'; | ||
import permissions from './Permissions'; | ||
import RTCAudioSession from './RTCAudioSession'; | ||
import RTCErrorEvent from './RTCErrorEvent'; | ||
import RTCFrameCryptor, { RTCFrameCryptorState } from './RTCFrameCryptor'; | ||
import RTCFrameCryptorFactory, { RTCFrameCryptorAlgorithm, RTCKeyProviderOptions } from './RTCFrameCryptorFactory'; | ||
import RTCIceCandidate from './RTCIceCandidate'; | ||
import RTCKeyProvider from './RTCKeyProvider'; | ||
import RTCPIPView, { startIOSPIP, stopIOSPIP } from './RTCPIPView'; | ||
import RTCPeerConnection from './RTCPeerConnection'; | ||
import RTCRtpReceiver from './RTCRtpReceiver'; | ||
import RTCRtpSender from './RTCRtpSender'; | ||
import RTCRtpTransceiver from './RTCRtpTransceiver'; | ||
import RTCSessionDescription from './RTCSessionDescription'; | ||
import RTCView, { type RTCVideoViewProps, type RTCIOSPIPOptions } from './RTCView'; | ||
import ScreenCapturePickerView from './ScreenCapturePickerView'; | ||
import { | ||
getDefaultAudioDeviceId, | ||
setDefaultAudioDeviceId, | ||
} from './AudioDeviceModule' | ||
import { setupNativeEvents } from './EventEmitter' | ||
import Logger from './Logger' | ||
import mediaDevices from './MediaDevices' | ||
import MediaStream from './MediaStream' | ||
import MediaStreamTrack, { type MediaTrackSettings } from './MediaStreamTrack' | ||
import MediaStreamTrackEvent from './MediaStreamTrackEvent' | ||
import permissions from './Permissions' | ||
import RTCAudioSession from './RTCAudioSession' | ||
import RTCErrorEvent from './RTCErrorEvent' | ||
import RTCFrameCryptor, { RTCFrameCryptorState } from './RTCFrameCryptor' | ||
import RTCFrameCryptorFactory, { | ||
RTCFrameCryptorAlgorithm, | ||
RTCKeyProviderOptions, | ||
} from './RTCFrameCryptorFactory' | ||
import RTCIceCandidate from './RTCIceCandidate' | ||
import RTCKeyProvider from './RTCKeyProvider' | ||
import RTCPIPView, { startIOSPIP, stopIOSPIP } from './RTCPIPView' | ||
import RTCPeerConnection from './RTCPeerConnection' | ||
import RTCRtpReceiver from './RTCRtpReceiver' | ||
import RTCRtpSender from './RTCRtpSender' | ||
import RTCRtpTransceiver from './RTCRtpTransceiver' | ||
import RTCSessionDescription from './RTCSessionDescription' | ||
import RTCView, { | ||
type RTCIOSPIPOptions, | ||
type RTCVideoViewProps, | ||
} from './RTCView' | ||
import ScreenCapturePickerView from './ScreenCapturePickerView' | ||
|
||
Logger.enable(`${Logger.ROOT_PREFIX}:*`); | ||
Logger.enable(`${Logger.ROOT_PREFIX}:*`) | ||
|
||
// Add listeners for the native events early, since they are added asynchronously. | ||
setupNativeEvents(); | ||
setupNativeEvents() | ||
|
||
export { | ||
RTCIceCandidate, | ||
RTCPeerConnection, | ||
RTCSessionDescription, | ||
RTCView, | ||
RTCPIPView, | ||
ScreenCapturePickerView, | ||
RTCRtpTransceiver, | ||
RTCRtpReceiver, | ||
RTCRtpSender, | ||
RTCErrorEvent, | ||
RTCAudioSession, | ||
RTCFrameCryptor, | ||
RTCFrameCryptorAlgorithm, | ||
RTCFrameCryptorState, | ||
RTCFrameCryptorFactory, | ||
RTCKeyProvider, | ||
RTCKeyProviderOptions, | ||
MediaStream, | ||
MediaStreamTrack, | ||
type MediaTrackSettings, | ||
type RTCVideoViewProps, | ||
type RTCIOSPIPOptions, | ||
mediaDevices, | ||
permissions, | ||
registerGlobals, | ||
startIOSPIP, | ||
stopIOSPIP, | ||
}; | ||
// Audio device management | ||
getDefaultAudioDeviceId, | ||
mediaDevices, | ||
MediaStream, | ||
MediaStreamTrack, | ||
permissions, | ||
registerGlobals, | ||
RTCAudioSession, | ||
RTCErrorEvent, | ||
RTCFrameCryptor, | ||
RTCFrameCryptorAlgorithm, | ||
RTCFrameCryptorFactory, | ||
RTCFrameCryptorState, | ||
RTCIceCandidate, | ||
RTCKeyProvider, | ||
RTCKeyProviderOptions, | ||
RTCPeerConnection, | ||
RTCPIPView, | ||
RTCRtpReceiver, | ||
RTCRtpSender, | ||
RTCRtpTransceiver, | ||
RTCSessionDescription, | ||
RTCView, | ||
ScreenCapturePickerView, | ||
setDefaultAudioDeviceId, | ||
startIOSPIP, | ||
stopIOSPIP, | ||
type MediaTrackSettings, | ||
type RTCIOSPIPOptions, | ||
type RTCVideoViewProps, | ||
} | ||
|
||
declare const global: any; | ||
declare const global: any | ||
|
||
function registerGlobals(): void { | ||
// Should not happen. React Native has a global navigator object. | ||
if (typeof global.navigator !== 'object') { | ||
throw new Error('navigator is not an object'); | ||
} | ||
// Should not happen. React Native has a global navigator object. | ||
if (typeof global.navigator !== 'object') { | ||
throw new Error('navigator is not an object') | ||
} | ||
|
||
if (!global.navigator.mediaDevices) { | ||
global.navigator.mediaDevices = {}; | ||
} | ||
if (!global.navigator.mediaDevices) { | ||
global.navigator.mediaDevices = {} | ||
} | ||
|
||
global.navigator.mediaDevices.getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices); | ||
global.navigator.mediaDevices.getDisplayMedia = mediaDevices.getDisplayMedia.bind(mediaDevices); | ||
global.navigator.mediaDevices.enumerateDevices = mediaDevices.enumerateDevices.bind(mediaDevices); | ||
global.navigator.mediaDevices.getUserMedia = | ||
mediaDevices.getUserMedia.bind(mediaDevices) | ||
global.navigator.mediaDevices.getDisplayMedia = | ||
mediaDevices.getDisplayMedia.bind(mediaDevices) | ||
global.navigator.mediaDevices.enumerateDevices = | ||
mediaDevices.enumerateDevices.bind(mediaDevices) | ||
|
||
global.RTCIceCandidate = RTCIceCandidate; | ||
global.RTCPeerConnection = RTCPeerConnection; | ||
global.RTCRtpReceiver = RTCRtpReceiver; | ||
global.RTCRtpSender = RTCRtpReceiver; | ||
global.RTCSessionDescription = RTCSessionDescription; | ||
global.MediaStream = MediaStream; | ||
global.MediaStreamTrack = MediaStreamTrack; | ||
global.MediaStreamTrackEvent = MediaStreamTrackEvent; | ||
global.RTCRtpTransceiver = RTCRtpTransceiver; | ||
global.RTCRtpReceiver = RTCRtpReceiver; | ||
global.RTCRtpSender = RTCRtpSender; | ||
global.RTCErrorEvent = RTCErrorEvent; | ||
global.RTCIceCandidate = RTCIceCandidate | ||
global.RTCPeerConnection = RTCPeerConnection | ||
global.RTCRtpReceiver = RTCRtpReceiver | ||
global.RTCRtpSender = RTCRtpReceiver | ||
global.RTCSessionDescription = RTCSessionDescription | ||
global.MediaStream = MediaStream | ||
global.MediaStreamTrack = MediaStreamTrack | ||
global.MediaStreamTrackEvent = MediaStreamTrackEvent | ||
global.RTCRtpTransceiver = RTCRtpTransceiver | ||
global.RTCRtpReceiver = RTCRtpReceiver | ||
global.RTCRtpSender = RTCRtpSender | ||
global.RTCErrorEvent = RTCErrorEvent | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll undo all of the reformatting changes from my editor. sorry about that 😅