Skip to content
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

Cannot show "agora-video calling" as remote device on WEB from FLUTTER app #1748

Closed
2 of 5 tasks
egamorft opened this issue May 7, 2024 · 3 comments
Closed
2 of 5 tasks
Labels
triage agora support waiting for customer response waiting for customer response, or closed by no-reponse bot

Comments

@egamorft
Copy link

egamorft commented May 7, 2024

Version of the agora_rtc_engine

6.3.0

Platforms affected

  • Android
  • iOS
  • macOS
  • Windows
  • Web

Steps to reproduce

  1. Web create room
  2. App (Flutter) joined
  3. App can get the device from Web but Web can't get the device from App (Only local video)

Expected results

Load both local devices and remote devices on Web

Actual results

Only show local devices

Code sample

Code sample
<script>
        let leaveConfirmation = false;
        var startCounting = false;
        let username = document.getElementById('username');

        username.value = '{{ Auth::user()->name ?? 'default name' }}';

        //#1
        let client = AgoraRTC.createClient({
            mode: 'rtc',
            codec: "h264",
            role: 'host'
        })

        //LOG
        client.on('exception', function(event) {
            console.log("exception", event);
        })

        client.on('connection-state-change', function(event) {
            console.log("connection-state-change", event);
        })

        client.on('user-joined', function(event) {
            console.log("user-joined", event);
        })

        client.on('user-left', function(event) {
            console.log("user-left", event);
        })

        client.on('user-published', function(event) {
            console.log("user-published", event);
        })

        client.on('user-unpublished', function(event) {
            console.log("user-unpublished", event);
        })

        client.on('user-info-updated', function(event) {
            console.log("user-info-updated", event);
        })

        client.on('token-privilege-will-exprire', function(event) {
            console.log("token-privilege-will-exprire", event);
        })

        client.on('token-privilege-did-expire', function(event) {
            console.log("token-privilege-did-expire", event);
        })

        //#2
        let config = {
            appid: '{{ $agora_chat->appid }}',
            token: '{{ $agora_chat->token }}',
            uid: '{{ $agora_chat->uid }}',
            channel: '{{ $agora_chat->channel }}',
        }

        //#3 - Setting tracks for when user joins
        let localTracks = {
            audioTrack: null,
            videoTrack: null
        }

        //#4 - Want to hold state for users audio and video so user can mute and hide
        let localTrackState = {
            audioTrackMuted: false,
            videoTrackMuted: false
        }

        //#5 - Set remote tracks to store other users
        let remoteTracks = {}
        document.getElementById('join-btn').addEventListener('click', async () => {
            config.uid = document.getElementById('username').value
            await joinStreams()
            document.getElementById('join-wrapper').style.display = 'none'
            document.getElementById('footer').style.display = 'flex'
        })

        document.getElementById('mic-btn').addEventListener('click', async () => {
            //Check if what the state of muted currently is
            //Disable button
            if (!localTrackState.audioTrackMuted) {
                //Mute your audio
                await localTracks.audioTrack.setMuted(true);
                localTrackState.audioTrackMuted = true
                document.getElementById('mic-btn').style.backgroundColor = 'rgb(255, 80, 80, 0.7)'
            } else {
                await localTracks.audioTrack.setMuted(false)
                localTrackState.audioTrackMuted = false
                document.getElementById('mic-btn').style.backgroundColor = '#1f1f1f8e'
            }
        })

        document.getElementById('camera-btn').addEventListener('click', async () => {
            //Check if what the state of muted currently is
            //Disable button
            if (!localTrackState.videoTrackMuted) {
                //Mute your audio
                await localTracks.videoTrack.setMuted(true);
                localTrackState.videoTrackMuted = true
                document.getElementById('camera-btn').style.backgroundColor = 'rgb(255, 80, 80, 0.7)'
            } else {
                await localTracks.videoTrack.setMuted(false)
                localTrackState.videoTrackMuted = false
                document.getElementById('camera-btn').style.backgroundColor = '#1f1f1f8e'
            }
        })

        async function leaveCall() {
            //Loop threw local tracks and stop them so unpublish event gets triggered, then set to undefined
            //Hide footer
            for (trackName in localTracks) {
                let track = localTracks[trackName]
                if (track) {
                    track.stop()
                    track.close()
                    localTracks[trackName] = null
                }
            }

            //Leave the channel
            await client.leave()
            document.getElementById('footer').style.display = 'none'
            document.getElementById('user-streams').innerHTML = ''
            document.getElementById('join-wrapper').style.display = 'flex'

            stopCounter();
            fromUser = $('#patient').val();
            toUser = `{{ Auth::user()->id ?? 0 }}`;

            //Người gọi tắt
            if (fromUser == toUser) {
                let formData = new FormData();

                formData.append('id', fromUser);

                formData.append('counter', $('#counter').text());

                let accessToken = `Bearer ` + token;
                let headers = {
                    'Authorization': accessToken,
                };
                try {
                    await $.ajax({
                        url: `{{ route('api.backend.call.history') }}`,
                        method: 'POST',
                        headers: headers,
                        contentType: false,
                        cache: false,
                        processData: false,
                        data: formData,
                        success: function(response) {
                            //
                        },
                        error: function(error) {
                            alert(error.responseJSON.message);
                        }
                    });
                } catch (e) {
                    alert(e);
                }
            }
        }

        //Method will take all my info and set user stream in frame
        let joinStreams = async () => {
            //Is this place hear strategicly or can I add to end of method?
            console.log('Start join stream!')
            client.on("user-published", handleUserJoined);

            client.on("user-joined", function(event) {
                console.log("user-joined", event)
            });

            client.on("user-left", handleUserLeft);

            client
                .enableAudioVolumeIndicator(); // Triggers the "volume-indicator" callback event every two seconds.
            client.on("volume-indicator", function(evt) {
                for (let i = 0; evt.length > i; i++) {
                    let speaker = evt[i].uid
                    let volume = evt[i].level
                    if (volume > 0) {
                        document.getElementById(`volume-${speaker}`).src =
                            '{{ asset('img/assets-video-call/volume-on.svg') }}'
                    } else {
                        document.getElementById(`volume-${speaker}`).src =
                            '{{ asset('img/assets-video-call/volume-off.svg') }}'
                    }
                }
            });

            //#6 - Set and get back tracks for local user
            console.log('uid', config.uid, {{ $agora_chat->uid }});
            [config.uid, localTracks.audioTrack, localTracks.videoTrack] = await Promise.all([
                client.join(config.appid, config.channel, config.token || null, config.uid || null),
                AgoraRTC.createMicrophoneAudioTrack(),
                AgoraRTC.createCameraVideoTrack()

            ])

            client.enableDualStream().then(() => {
                console.log("Enable Dual stream success!");
            }).catch(err => {
                console.log(err);
            })

            //#7 - Create player and add it to player list
            let player = `<div class="video-containers" id="video-wrapper-${config.uid}">
                        <p class="user-uid"><img class="volume-icon" id="volume-${config.uid}" src="{{ asset('img/assets-video-call/volume-on.svg') }}" /> ${config.uid}</p>
                        <div class="video-player player" id="stream-${config.uid}"></div>
                  </div>`

            document.getElementById('user-streams').insertAdjacentHTML('beforeend', player);
            //#8 - Player user stream in div
            localTracks.videoTrack.play(`stream-${config.uid}`)

            //#9 Add user to user list of names/ids

            //#10 - Publish my local video tracks to entire channel so everyone can see it
            await client.publish([localTracks.audioTrack, localTracks.videoTrack])

        }

        let handleUserJoined = async (user, mediaType) => {
            console.log('Handle user joined')
            console.log(user);
            //#11 - Add user to list of remote users
            remoteTracks[user.uid] = user

            //#12 Subscribe ro remote users
            await client.subscribe(user, mediaType)

            if (mediaType === 'video') {
                let player = document.getElementById(`video-wrapper-${user.uid}`)
                console.log('player:', player)
                if (player != null) {
                    player.remove()
                }

                player = `<div class="video-containers" id="video-wrapper-${user.uid}">
                        <p class="user-uid"><img class="volume-icon" id="volume-${user.uid}" src="{{ asset('img/assets-video-call/volume-on.svg') }}" /> ${user.uid}</p>
                        <div  class="video-player player" id="stream-${user.uid}"></div>
                      </div>`
                document.getElementById('user-streams').insertAdjacentHTML('beforeend', player);
                user.videoTrack.play(`stream-${user.uid}`)
            }

            if (mediaType === 'audio') {
                user.audioTrack.play();
            }
            if (!startCounting) {
                startCounter()
            }
        }

        let handleUserLeft = (user) => {
            console.log('Handle user left!')
            //Remove from remote users and remove users video wrapper
            delete remoteTracks[user.uid]
            document.getElementById(`video-wrapper-${user.uid}`).remove()
        }

        window.addEventListener('load', async () => {
            await joinStreams();
            const joinWrapper = document.querySelector('#join-wrapper');
            const footer = document.querySelector('#footer');
            joinWrapper.style.display = 'none';
            footer.style.display = 'flex';
        });

        document.getElementById('leave-btn').addEventListener('click', async () => {
            if (confirm('Are you sure you want to leave?')) {
                leaveConfirmation = true;
                leaveCall();
            }
        });
    </script>

Screenshots or Video

Screenshots / Video demonstration

image

Logs

Logs when app user join
10:18:47:313 Agora-SDK [DEBUG]: [lock-P2PChannel-mutex-8] is locked, current queue 1. From P2PChannel.updateRemoteRTPCapabilities
AgoraRTC_N.js:5 10:18:47:315 Agora-SDK [DEBUG]: [lock-P2PConnection-mutex-11] is locked, current queue 1. From P2PConnection.updateRemoteRTPCapabilities
AgoraRTC_N.js:5 10:18:47:315 Agora-SDK [DEBUG]: [lock-P2PChannel-mutex-8] is not locked, current queue 0. From P2PChannel.updateRemoteRTPCapabilities
AgoraRTC_N.js:5 10:18:47:315 Agora-SDK [DEBUG]: codecs has not changed, no need to updateRemoteCodec, codecs: vp9,av1,vp8,h264
AgoraRTC_N.js:5 10:18:47:315 Agora-SDK [DEBUG]: [P2PConnection] updateRemoteRTPCapabilities no need to exchange SDP.
AgoraRTC_N.js:5 10:18:47:315 Agora-SDK [DEBUG]: [lock-P2PConnection-mutex-11] is not locked, current queue 0. From P2PConnection.updateRemoteRTPCapabilities

Flutter Doctor output

Doctor output
[!] Flutter (Channel unknown, 3.10.0, on macOS 14.4.1 23E224 darwin-x64, locale
en-VN)
! Flutter version 3.10.0 on channel unknown at
/Users/johnvu/development/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an
official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions
at https://flutter.dev/docs/get-started/install.
! Unknown upstream repository.
Reinstall Flutter by following instructions at
https://flutter.dev/docs/get-started/install.
• Framework revision 84a1e904f4 (12 months ago), 2023-05-09 07:41:44 -0700
• Engine revision d44b5a94c9
• Dart version 3.0.0
• DevTools version 2.23.1
• If those were intentional, you can disregard the above warnings; however
it is recommended to use "git" directly to perform update checks and
upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/johnvu/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = /Users/johnvu/Library/Android/sdk
• Java binary at: /Applications/Android
Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build
17.0.9+0-17.0.9b1087.7-11185874)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15E204a
• CocoaPods version 1.15.2

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build17.0.9+0-17.0.9b1087.7-11185874)
[✓] Connected device (2 available)
• macOS (desktop) • macos • darwin-x64  • macOS 14.4.1 23E224 darwin-x64• Chrome (web) • chrome • web-javascript • Google Chrome 124.0.6367.119
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
@littleGnAl littleGnAl added triage agora support waiting for customer response waiting for customer response, or closed by no-reponse bot labels May 7, 2024
Copy link
Contributor

github-actions bot commented May 7, 2024

Please submit a ticket to Agora Support for further investigation of this issue. If you have any conclusions, you can share them here which may help other developers. Thanks!

Copy link
Contributor

Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. If you find this problem please file a new issue with the same description, what happens, logs and the output. All system setups can be slightly different so it's always better to open new issues and reference the related ones. Thanks for your contribution.

Copy link
Contributor

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please raise a new issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
triage agora support waiting for customer response waiting for customer response, or closed by no-reponse bot
Projects
None yet
Development

No branches or pull requests

2 participants