How to android desktop sharing

Thank you for watching this!

I made a mobile app using jitsisdk and I’m running it.
I heard that the screen sharing function on Android has been officially distributed recently, so I’d like to add it to my project.
I’d like to know what settings or code I missed because I couldn’t load the desktop track while adding features.

An example of a project forked by jitsi/jitsi-meet.git with a simple code added to it.
I’d like someone to find out the problem with this example.
The code is located ‘react/features/app/components/App.native.js’

import React, { Component } from "react";
import { AppRegistry } from "react-native";
import SplashScreen from "react-native-splash-screen";
import JitsiMeetJS, { JitsiConnectionEvents } from "../../base/lib-jitsi-meet";

import { Text, View, Button, TextInput } from "react-native";
import { RTCView } from "react-native-webrtc";

import "../middlewares";
import "../reducers";

const config = {
    hosts: {
        domain: "meet.jit.si",
        focus: "focus.meet.jit.si",
        muc: "conference.meet.jit.si",
    },

    bosh: "https://meet.jit.si/http-bind",
    openBridgeChannel: "datachannel",
    channelLastN: -1,
    resolution: 720,
    constraints: {
        video: {
            aspectRatio: 1.3,
            height: {
                ideal: 320,
                max: 720,
                min: 240,
            },
            width: { min: 640, max: 1280 },
        },
    },
    disableSuspendVideo: true,
    disableSimulcast: false,
    minHDHeight: 240,
    p2p: {
        enabled: true,

        stunServers: [{ urls: "stun:meet-jit-si-turnrelay.jitsi.net:443" }],
    },

    stereo: true,
    e2eping: { pingInterval: 10000, analyticsInterval: 60000 },
    desktopSharing: "ext",
    desktopSharingSources: ["screen", "window"],

    enableNoAudioDetection: true,
    enableNoisyMicDetection: true,

    channelLastN: -1,
    enableWelcomePage: true,
};

export class App extends Component {
    constructor(props) {
        super(props);
        this._jitsiConference;
        this._jitsiConnection;
        this.state = {
            tracks: [],
            roomName: "test_choi",
            num: 0,
            localTracks: null,
        };
    }
    async componentDidMount() {
        SplashScreen.hide();
    }
    componentWillUnmount() {
        this._jitsiConnection?.disconnect();
        this._jitsiConference?.leave();
    }

    _joinUser = () => {};
    _addRemoteTrack = (track) => {
        if (track.getType() === "video") {
            let exist = false;
            let newTrack = [];

            this.state.tracks.forEach((e) => {
                if (e.user === track.ownerEndpointId) {
                    e.video = track;
                    exist = true;
                }
                newTrack.push(e);
            });

            if (exist) {
                this.setState({
                    ...this.state,
                    tracks: [...newTrack],
                });
            } else {
                this.setState({
                    ...this.state,
                    tracks: [
                        ...this.state.tracks,
                        { video: track, user: track.ownerEndpointId },
                    ],
                });
            }
        }
    };
    _changeRoomName = (text) => {
        this.setState({
            ...this.state,
            roomName: text,
        });
    };
    _disconnMeet = async () => {
        this._jitsiConference?.getConnectionState()
            ? await this._jitsiConference?.leave()
            : null;
        this._jitsiConference = null;
        await this._jitsiConnection?.disconnect();
        this._jitsiConnection = null;
        this.setState({
            ...this.state,
            tracks: [],
        });
    };
    _connMeet = async () => {
        const options = config;

        JitsiMeetJS.init({
            ...options,
        });
        JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
        const roomName = this.state.roomName;

        options.bosh = `${options.bosh}?room=${roomName}`;
        this._jitsiConnection = new JitsiMeetJS.JitsiConnection(
            null,
            null,
            options
        );
        const conferenceEvents = JitsiMeetJS.events.conference;
        await new Promise((res, rej) => {
            this._jitsiConnection.addEventListener(
                JitsiConnectionEvents.CONNECTION_ESTABLISHED,
                (a) => {
                    res(a);
                }
            );
            this._jitsiConnection.addEventListener(
                JitsiConnectionEvents.CONNECTION_FAILED,
                (a) => {}
            );
            this._jitsiConnection.addEventListener(
                JitsiConnectionEvents.CONNECTION_DISCONNECTED,
                (a) => {}
            );
            this._jitsiConnection.connect({});
        });
        this._jitsiConference = this._jitsiConnection.initJitsiConference(
            roomName,
            options
        );

        this._jitsiConference.on(conferenceEvents.CONFERENCE_JOINED, () => {});
        this._jitsiConference.on(conferenceEvents.CONFERENCE_FAILED, () => {});
        this._jitsiConference.on(conferenceEvents.USER_JOINED, (id, user) => {
            this._joinUser(user);
        });
        this._jitsiConference.on(conferenceEvents.TRACK_ADDED, (track, asd) => {
            if (!track.isLocal()) {
                this._addRemoteTrack(track);
            }
        });

        let video = (
            await JitsiMeetJS.createLocalTracks({
                devices: ["video"],
                resolution: 320,
            })
        )[0];

        // @@@ change this!
        // let video = (
        //     await JitsiMeetJS.createLocalTracks({
        //         devices: ["desktop"],
        //     })
        // )[0];

        let audio = (
            await JitsiMeetJS.createLocalTracks({
                devices: ["audio"],
                resolution: 320,
            })
        )[0];

        this._jitsiConference.addTrack(video);
        this._jitsiConference.addTrack(audio);

        this._jitsiConference.join();
        this.setState({
            ...this.state,
            tracks: [{ video, user: "local" }],
        });
    };

    render() {
        return (
            <View style={{ flex: 1 }}>
                <Button
                    title={"disconn"}
                    onPress={() => {
                        this._disconnMeet();
                    }}
                />
                <Button
                    title={"conn"}
                    onPress={() => {
                        this._connMeet();
                    }}
                />
                {this.state.tracks?.length ? (
                    this.state.tracks.map((track) => {
                        return (
                            <RTCView
                                style={{
                                    zIndex: 99,
                                    flex: 1,
                                    top: 0,
                                    bottom: 0,
                                    left: 0,
                                    right: 0,
                                }}
                                objectFit={"contain"}
                                streamURL={track.video
                                    .getOriginalStream()
                                    .toURL()}
                                zOrder={1}
                            />
                        );
                    })
                ) : (
                    <TextInput
                        style={{ backgroundColor: "#fff" }}
                        onChangeText={() => {
                            this._changeRoomName();
                        }}
                    >
                        {this.state.roomName}
                    </TextInput>
                )}
            </View>
        );
    }
}

AppRegistry.registerComponent("App", () => App);

Tell me what I missed?

update) Sorry, I forgot to write down what the symptoms were.

Get a track, a system notification window appears as shown in the picture, but if insert stream url into webrtc tag, the screen does not appear.

Does the call to createLocalTracks for a desktop track fail? What is the error? Do you see anything in adb ?

1 Like

I added it to the text.

Hello @sionel, have you ever get this working?

@sondinh
Yes, I solved this problem.
I don’t understand exactly why, but to use the desktop sharing function, you have to run the code “Ong Notification.buildOngoningConferenceNotification” in the jitsi SDK.

It’s hard to explain in English, so I’ll just tell you the keyword.

Just android, when you enter conference, you must use NativeModules.ExternalAPI.sendEvent(‘CONFERENCE_JOINED’,{url: ${enterRoomUrl}}, externalAPIScope)

Thanks for your reply.
I was able to solve this issue as well.
It’s because I used another app to wrap the original Jitsi App, and didn’t pass the props externalAPIScope to Jitsi App so it not work.
I think Jitsi use that config to determine which app is sharing screen, so if it missing then the screen sharing can’t start.