Search Results for

    Show / Hide Table of Contents

    Change Media Devices

    In this tutorial, you'll learn how to allow your users to change their media devices, such as changing to a different camera or microphone, in a video conference.

    Prerequisites

    This tutorial requires the SFU connection app or any apps you have built earlier on top of it.

    Change Audio Input Devices

    We'll use LocalMedia.GetAudioSourceInputs to get a list of audio input devices, and then use LocalMedia.ChangeAudioSourceInput to change the audio input devices.

    • CSharp
    • Android
    • iOS
    • TypeScript

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.cs file:

    //Switch audio input device.
    public Future<SourceInput[]> GetAudioInputs()
    {
        return LocalMedia.GetAudioSourceInputs();
    }
    public void SetAudioSourceInput(SourceInput audioInput)
    {
        LocalMedia.ChangeAudioSourceInput(audioInput);
    }
    

    Currently, LiveSwitch doesn't support changing audio input and output on Android. We suggest using AudioManager to change audio output. Audio input as it stands can't be changed separately from the audio output.

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.swift file:

    var _currentAudioInput: FMLiveSwitchSourceInput?
    
    func setAudioSourceInput(sourceInputId: String) {
        self._localMedia?.getAudioSourceInputs().then(resolveActionBlock: {[self] (result: Any!) in
            let newResults = result as! [FMLiveSwitchSourceInput]
            self._currentAudioInput = newResults.filter{input in
                return input.id() == sourceInputId
            }[0]
        });
        // Fall back if no input desired was found
        if (self._currentAudioInput == nil) {
            self._currentAudioInput = self._localMedia?.audioSourceInput()
        }
        
        self._localMedia?.changeAudioSourceInput(self._currentAudioInput!)
    }
    

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.ts file:

    // Switch audio input device.
    public getAudioInputs(): fm.liveswitch.Future<fm.liveswitch.SourceInput[]> {
        return this.localMedia.getAudioInputs();
    }
    
    public setAudioInput(input: fm.liveswitch.SourceInput): void {
        this.localMedia.changeAudioSourceInput(input);
    }
    

    Change Video Input Devices

    We'll use LocalMedia.GetVideoSourceInputs to get a list of video input devices, and then use LocalMedia.ChangeVideoSourceInput to change the video input devices.

    • CSharp
    • Android
    • iOS
    • TypeScript

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.cs file:

    // Get a list of video input devices.
    public Future<SourceInput[]> GetVideoInputs()
    {
        return LocalMedia.GetVideoSourceInputs();
    }
    
    // Switch video input device.
    public void SetVideoSourceInput(SourceInput videoInput)
    {
        LocalMedia.ChangeVideoSourceInput(videoInput);
    }
    

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.java file:

    // To determine whether local media is set or not.
    public LocalMedia<View> getLocalMedia() {
        return localMedia;
    }
    
    // Get a list of video input devices.
    public SourceInput[] getVideoInputs() {
        return localMedia.getVideoSourceInputs().waitForResult();
    }
    
    // Switch video input device.
    public void setVideoSourceInput(SourceInput input) {
        localMedia.changeVideoSourceInput(input);
    }
    

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.swift file:

    var _currentVideoInput: FMLiveSwitchSourceInput?
    
    func setVideoSourceInput(sourceInputId: String) {
        self._localMedia?.getVideoSourceInputs().then(resolveActionBlock: {[self] (result: Any!) in
            let newResults = result as! [FMLiveSwitchSourceInput]
            self._currentVideoInput = newResults.filter{input in
                return input.id() == sourceInputId
            }[0]
        });
        // Fall back if no input desired was found
        if (self._currentVideoInput == nil) {
            self._currentVideoInput = self._localMedia?.videoSourceInput()
        }
        
        self._localMedia?.changeVideoSourceInput(self._currentVideoInput!)
    }
    

    Paste the following code into the HelloWorldLogic class in the HelloWorldLogic.ts file:

    // Get a list of video input devices.
    public getVideoInputs(): fm.liveswitch.Future<fm.liveswitch.SourceInput[]> {
        return this.localMedia.getVideoInputs();
    }
    
    // Switch video input device.
    public setVideoInput(input: fm.liveswitch.SourceInput): void {
        this.localMedia.changeVideoSourceInput(input);
    }
    

    Change Audio Output Devices

    Use RemoteMedia.GetAudioSinkOutputs to get a list of audio output devices, and then use RemoteMedia.ChangeAudioSinkOutput to change the audio output devices.

    • CSharp
    • Android
    • iOS
    • TypeScript

    Paste the following code into the HelloWorldLogic class:

    // Switch audio output device.
    public Future<SinkOutput[]> GetAudioOutputs()
    {
        var remoteMedia = new RemoteMedia(false, false, _AecContext);
        return remoteMedia.GetAudioSinkOutputs();
    }
    
    public void SetAudioSourceOutput(SinkOutput audioOutput)
    {
        // Set the audio output device for each downstream connection.
        foreach (SfuDownstreamConnection connection in _DownStreamConnections.Values)
        {
            connection.AudioStream.RemoteMedia.ChangeAudioSinkOutput(audioOutput);
        }
    }
    

    Currently, LiveSwitch doesn't support changing audio input and output on Android. We suggest using AudioManager. The following is an example of changing devices among Bluetooth speakers, wired speakers, and phone speakers. Note that you can't change audio input separately from the audio output.

    Paste the following code into the HelloWorldLogic class:

    // Available audio outputs.
    final String[] audioOutputs = new String[]{"Bluetooth", "Wired Speaker", "Phone Speaker"};
    
    // Switch audio output device.
    public String[] getAudioOutputs() {
        // Get the audio manager and the available audio devices from the OS.
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        AudioDeviceInfo[] audioDevices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
    
        HashSet<String> availableAudioOutputs = new HashSet<>();
    
        for (AudioDeviceInfo deviceInfo : audioDevices) {
            switch (deviceInfo.getType()) {
                case (AudioDeviceInfo.TYPE_BLUETOOTH_A2DP):
                case (AudioDeviceInfo.TYPE_BLUETOOTH_SCO):
                    // Bluetooth Device
                    availableAudioOutputs.add(audioOutputs[0]);
                    break;
                case (AudioDeviceInfo.TYPE_WIRED_HEADPHONES):
                case (AudioDeviceInfo.TYPE_WIRED_HEADSET):
                    // Wired Speaker
                    availableAudioOutputs.add(audioOutputs[1]);
                    break;
                case (AudioDeviceInfo.TYPE_BUILTIN_SPEAKER):
                    // Phone Speaker
                    availableAudioOutputs.add(audioOutputs[2]);
                    break;
                default:
                    break;
            }
        }
    
        return availableAudioOutputs.toArray(new String[0]);
    }
    
    public void setAudioSourceOutput(String deviceType) {
        // Get the audio manager from the OS.
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    
        if (deviceType.equals(audioOutputs[0])) {
            // Bluetooth Device
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            audioManager.startBluetoothSco();
            audioManager.setBluetoothScoOn(true);
        } else if (deviceType.equals(audioOutputs[1])) {
            // Wired Speaker
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            audioManager.stopBluetoothSco();
            audioManager.setBluetoothScoOn(false);
            audioManager.setSpeakerphoneOn(false);
        } else {
            // Phone Speaker
            audioManager.setMode(AudioManager.MODE_NORMAL);
            audioManager.stopBluetoothSco();
            audioManager.setBluetoothScoOn(false);
            audioManager.setSpeakerphoneOn(true);
        }
    }
    

    Currently, LiveSwitch doesn't support changing audio output on iOS. We suggest using AVAudioSession to handle this. The following is an example of changing devices among Bluetooth speakers, wired speakers, and phone speakers.

    Paste the following code into the HelloWorldLogic class:

    func setAudioToExternal() {
        let audioSession = AVAudioSession.sharedInstance()
        
        do {
            try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
            try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
            try audioSession.setActive(true)
        } catch {
            FMLiveSwitchLog.error(withMessage: "Unable to set audio output to external speaker/ear piece speaker.")
        }
    }
    
    func setAudioToSpeaker() {
        let audioSession = AVAudioSession.sharedInstance()
        
        do {
            try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
            try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
            try audioSession.setActive(true)
        } catch {
            FMLiveSwitchLog.error(withMessage: "Unable to set audio output to speaker.")
        }
    }
    

    Paste the following code into the HelloWorldLogic class:

    // Switch audio output device.
    public getAudioOutputs(): fm.liveswitch.Future<fm.liveswitch.SinkOutput[]> {
        const remoteMedia = new fm.liveswitch.RemoteMedia(true, true);
        return remoteMedia.getAudioSinkOutputs();
    }
    
    public setAudioOutput(output: fm.liveswitch.SinkOutput): void {
        // Set the audio output device for each downstream connection.
        for (const connectionID in this.downstreamConnections) {
            const connection = this.downstreamConnections[connectionID];
            const remoteMedia = connection.getAudioStream().getRemoteMedia();
            remoteMedia.changeAudioSinkOutput(output);
        }
    }
    

    Uncomment UI Components

    Now, go to the files for the UI components and uncomment the code for changing devices.

    • CSharp
    • Android
    • iOS
    • TypeScript

    In the MainWindow.xaml.cs file, there are a few places tagged with <Change Devices> and </Change Devices>. Uncomment the code between these tags.

    In the DeviceSwitchingFragment.java file, uncomment the code that's commented out.

    In the ViewModel.swift file, uncomment all the commented out code between the <DeviceSwitching> and </DeviceSwitching> tags.

    In the DeviceSwitchingUI.swift file, uncomment all the commented out code.

    If the device list for video doesn't show up, simply select the other buttons and reselect Device Switching for refresh.

    In the index.tsfile, uncomment the code between the <Change Devices> and </Change Devices> tags.

    Run Your App

    Tip

    In the mobile app, some buttons are hidden. To show hidden buttons, swipe the button (not the screen) from left to right.

    Run your app in your project IDE. Click Join and then click Device Switching. You should be able to change to a different camera or microphone on your device. Your app UI should look similar to the following.

    • CSharp
    • Android
    • iOS
    • TypeScript

    Congratulations, you've added the changing device feature to your app!

    In This Article
    Back to top Copyright © LiveSwitch Inc. All Rights Reserved.Documentation for LiveSwitch Version 1.6.2