Giter VIP home page Giter VIP logo

react-native-janus's Introduction

Video Room

import {mediaDevices, MediaStream, RTCIceCandidate, RTCPeerConnection, RTCSessionDescription, RTCView} from 'react-native-webrtc';
import React from 'react';
import {Dimensions, FlatList, StatusBar, View} from 'react-native';
import {Janus, JanusVideoRoomPlugin} from 'react-native-janus';

Janus.setDependencies({
    RTCPeerConnection,
    RTCSessionDescription,
    RTCIceCandidate,
    MediaStream,
});

class JanusVideoRoomScreen extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            stream: null,
            publishers: [],
        };
    }

    async receivePublisher(publisher) {
        try {
            let videoRoom = new JanusVideoRoomPlugin(this.janus);
            videoRoom.setRoomID(1234);
            videoRoom.setOnStreamListener((stream) => {
                this.setState(state => ({
                    publishers: [
                        ...state.publishers,
                        {
                            publisher: publisher,
                            stream: stream,
                        },
                    ],
                }));
            });

            await videoRoom.createPeer();
            await videoRoom.connect();
            await videoRoom.receive(this.videoRoom.getUserPrivateID(), publisher);
        } catch (e) {
            console.error(e);
        }
    }

    async removePublisher(publisherID) {
        try {
            this.setState(state => ({
                publishers: state.publishers.filter(pub => pub.publisher == null || pub.publisher.id !== publisherID),
            }));
        } catch (e) {
            console.error(e);
        }
    }

    async initJanus(stream) {
        try {
            this.setState(state => ({
                publishers: [
                    {
                        publisher: null,
                        stream: stream,
                    },
                ],
            }));

            this.janus = new Janus('ws://${YOUR_JANUS_ADDRESS]:8188');
            this.janus.setApiSecret('janusrocks');
            await this.janus.init();

            this.videoRoom = new JanusVideoRoomPlugin(this.janus);
            this.videoRoom.setRoomID(1234);
            this.videoRoom.setDisplayName('can');
            this.videoRoom.setOnPublishersListener((publishers) => {
                for (let i = 0; i < publishers.length; i++) {
                    this.receivePublisher(publishers[i]);
                }
            });
            this.videoRoom.setOnPublisherJoinedListener((publisher) => {
                this.receivePublisher(publisher);
            });
            this.videoRoom.setOnPublisherLeftListener((publisherID) => {
                this.removePublisher(publisherID);
            });
            this.videoRoom.setOnWebRTCUpListener(async () => {

            });

            await this.videoRoom.createPeer();
            await this.videoRoom.connect();
            await this.videoRoom.join();
            await this.videoRoom.publish(stream);

        } catch (e) {
            console.error('main', JSON.stringify(e));
        }
    }

    getMediaStream = async () => {
        let isFront = true;
        let sourceInfos = await mediaDevices.enumerateDevices();
        let videoSourceId;
        for (let i = 0; i < sourceInfos.length; i++) {
            const sourceInfo = sourceInfos[i];
            console.log(sourceInfo);
            if (sourceInfo.kind == 'videoinput' && sourceInfo.facing == (isFront ? 'front' : 'environment')) {
                videoSourceId = sourceInfo.deviceId;
            }
        }

        let stream = await mediaDevices.getUserMedia({
            audio: true,
            video: {
                facingMode: (isFront ? 'user' : 'environment'),
            },
        });
        await this.initJanus(stream);
    };

    async componentDidMount() {
        this.getMediaStream();
    }

    componentWillUnmount = async () => {
        if (this.janus) {
            await this.janus.destroy();
        }
    };

    renderView() {
    }

    render() {
        return (
            <View style={{flex: 1, width: '100%', height: '100%', backgroundColor: '#000000', flexDirection: 'row'}}>
                <StatusBar translucent={true} barStyle={'light-content'}/>
                <FlatList
                    data={this.state.publishers}
                    numColumns={2}
                    keyExtractor={(item, index) => {
                        if (item.publisher === null) {
                            return `rtc-default`;
                        }
                        return `rtc-${item.publisher.id}`;
                    }}
                    renderItem={({item}) => (
                        <RTCView style={{
                            flex: 1,
                            height: (Dimensions.get('window').height / 2),
                        }} objectFit={'cover'} streamURL={item.stream.toURL()}/>
                    )}
                />
            </View>
        );
    }
}

export default JanusVideoRoomScreen;

react-native-janus's People

Contributors

canozgen9 avatar davidyashgur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-native-janus's Issues

plz provide code for react hook

hi, first thanks for your library
im new in React native, im trying to re-write your code using hook, but got some error


undefined is not an object (evaluating 'stream.publishers')


here is my code, please help


import React, { useEffect, useState } from 'react';
import {StyleSheet,View,Text, Dimensions, 
    TouchableOpacity, SearchBar, StatusBar, 
    FlatList, Button,
    PlatformColor} from "react-native" ;
import { useLayoutEffect } from 'react/cjs/react.production.min';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import * as RootNavigation from '../../utils/navigation/RootNavigation';

import { Janus } from 'react-native-janus';

import {mediaDevices, MediaStream, RTCIceCandidate, RTCPeerConnection, RTCSessionDescription, RTCView} from 'react-native-webrtc';
 
Janus.setDependencies({
    RTCPeerConnection,
    RTCSessionDescription,
    RTCIceCandidate,
    MediaStream,
});

export default function GroupCallScreen({navigation}){
    const [stream, setStream] = useState()
    const [publisher, setPublisher] = useState([])
    

    useEffect(() => {
        navigation.setOptions({
            headerLeft: () => (<MaterialCommunityIcons 
                    name='arrow-left'
                    size={24}
                    color={RootNavigation.defaultNavBtnColor}
                    onPress={() => {navigation.pop()}} />)
        })
    }, []);


    _receivePublisher = async (publisher) => {
        try {
            let videoRoom = new JanusVideoRoomPlugin(this.janus);
            videoRoom.setRoomID(1234);
            videoRoom.setOnStreamListener((stream) => {
                setStream(stream)
                setPublisher(publisher)
            });

            await videoRoom.createPeer();
            await videoRoom.connect();
            await videoRoom.receive(this.videoRoom.getUserPrivateID(), publisher);
        } catch (e) {
            console.error(e);
        }
    };

    _removePublisher = async (publisher) => {
        try {
            setPublisher(publishers.filter(pub => pub.publisher == null || pub.publisher.id !== publisherID))
        } catch(e) {
            console.error(e);
        }
    };

    _initJanus = async (stream) => {
        try {
            setStream(null)
            setPublisher([])

            this.janus = new Janus('ws://${YOUR_JANUS_ADDRESS]:8188');
            this.janus.setApiSecret('janusrocks');
            await this.janus.init();
 
            this.videoRoom = new JanusVideoRoomPlugin(this.janus);
            this.videoRoom.setRoomID(1234);
            this.videoRoom.setDisplayName('can');
            this.videoRoom.setOnPublishersListener((publishers) => {
                for (let i = 0; i < publishers.length; i++) {
                    this.receivePublisher(publishers[i]);
                }
            });
            this.videoRoom.setOnPublisherJoinedListener((publisher) => {
                this.receivePublisher(publisher);
            });
            this.videoRoom.setOnPublisherLeftListener((publisherID) => {
                this.removePublisher(publisherID);
            });
            this.videoRoom.setOnWebRTCUpListener(async () => {
 
            });
 
            await this.videoRoom.createPeer();
            await this.videoRoom.connect();
            await this.videoRoom.join();
            await this.videoRoom.publish(stream);
        } catch(e) {
            console.error(e);
        }
    };
   
    _getMediaStream = async () => {
        let isFront = true;
        let sourceInfos = await mediaDevices.enumerateDevices();
        let videoSourceId;
        for (let i = 0; i < sourceInfos.length; i++) {
            const sourceInfo = sourceInfos[i];
            console.log(sourceInfo);
            if (sourceInfo.kind == 'videoinput' && sourceInfo.facing == (isFront ? 'front' : 'environment')) {
                videoSourceId = sourceInfo.deviceId;
            }
        }

        let stream = await mediaDevices.getUserMedia({
            audio: true,
            video: {
                facingMode: (isFront ? 'user' : 'environment'),
            },
        });
        await this.initJanus(stream);
    };
 
    return(
        <View style={{flex: 1, width: '100%', height: '100%', backgroundColor: 'white', flexDirection: 'row'}}>
                <StatusBar translucent={true} barStyle={'light-content'}/>
                <FlatList
                    data={stream.publishers}
                    numColumns={2}
                    keyExtractor={(item, index) => {
                        if (item.publisher === null) {
                            return `rtc-default`;
                        }
                        return `rtc-${item.publisher.id}`;
                    }}
                    renderItem={({item}) => (
                        <RTCView style={{
                            flex: 1,
                            height: (Dimensions.get('window').height / 2),
                        }} objectFit={'cover'} streamURL={item.stream.toURL()}/>
                    )}
                />
        </View>
    )
}

const GroupCallLeftHeader = (props) => {
    return(
        <View style={{
            flexDirection: 'row',
            justifyContent: 'center',
            alignItems: 'center'
        }}>
            <MaterialCommunityIcons name='qrcode' color={navBtnColor} size={24} style={{ marginLeft: 12, marginRight: 24}}/>
            <MaterialIcons name='business-center' color={navBtnColor} size={28} style={{ marginBottom: 3}}/>
        </View>
        
    )
}

Add data channel support

I am trying to add the data channel support to this plugin but the code refuses to work. Any insight on this. ?

README example doesn't work.

Hello. I'm trying to build these package and examples in my environment, but it doesn't work, it just shows white screen.
I've trying to fix it out, I've trace it and in my console log, this.state.publishers.publisher always print null, so I changed like this:

on line 27
--            videoRoom.setOnStreamListener((stream) => {
--                this.setState(state => ({
--                    publishers: [
--                        ...state.publishers,
--                       {
--                            publisher: publisher,
--                            stream: stream,
--                        },
--                    ],
--                }));
--            });

to
++            let tstream = videoRoom.setOnStreamListener()
++            this.setState({
++                publishers: [
++                    ...this.state.publishers,
++                    {
++                        publisher: _publisher,
++                        stream: tstream,
++                    }
++                ]
++            });

after changing this, the publishers doesn't have null and now they have proper objects, but after this I got another error on render:

TypeError: Cannot read property 'toURL' of undefined

This error is located at:
    in CellRenderer (at VirtualizedList.js:851)
    in RCTView (at ScrollView.js:1063)
    in RCTScrollView (at ScrollView.js:1196)
    in ScrollView (at VirtualizedList.js:1280)
    in VirtualizedList (at FlatList.js:633)
    in FlatList (at test.js:181)
    in RCTView (at test.js:173)
    in JanusVideoRoomScreen
    in RCTView (at SafeAreaView.js:41)
    in ForwardRef(SafeAreaView) (at App.js:39)
    in App (at renderApplication.js:45)
    in RCTView (at AppContainer.js:109)
    in RCTView (at AppContainer.js:135)
    in AppContainer (at renderApplication.js:39)

How can I fix these? Can you give me a advice?

Also, here is my environment:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.