Giter Site home page Giter Site logo

videosdk-live / videosdk.live Goto Github PK

View Code? Open in Web Editor NEW
28.0 2.0 2.0 42 KB

High Scalable WebRTC infrastructure SDKs in JavaScipt, React, Flutter, React native, Android, IOS. Official community support repository for Video SDK.

Home Page: https://www.videosdk.live/

react-webrtc javascipt-webrtc android-webrtc react-native-webrtc ios-webrtc webrtc angular-webrtc flutter-webrtc php-webrtc vuejs-webrtc

videosdk.live's Introduction


GitHub badge GitHub badge

Custom SDK

At Video SDK, we’re building tools to help companies create world-class collaborative products with capabilities of live audio/videos, compose cloud recordings/rtmp/hls and interaction APIs

Documentation

Read the documentation to start using Video SDK.

Community

  • Discord - To get involved with the Video SDK community, ask questions and share tips.
  • Twitter - To receive updates, announcements, blog posts, and general Video SDK tips.
Custom Audio & Video SDK
πŸ“™ Language πŸ“„ Official Docs πŸƒ Run Code Samples πŸ‘¨β€πŸ”§API Reference ♻️ Plugin Demo App Demo App
JavaScript docs-javascript videosdk-js videosdk-js videosdk-js πŸ’» js-demo -
React docs-react docs-react videosdk-react videosdk-react πŸ’» react-demo -
React Native docs-react-native videosdk-r-n videosdk-r-n videosdk-r-n πŸ“² android-demo πŸ“² ios-demo
Android docs-androidvideosdk-android videosdk-android - πŸ“² android-demo -
iOS docs-ios videosdk-ios videosdk-ios - - -
Flutter docs-flutter videosdk-flutter videosdk-flutter videosdk-flutter πŸ“² android-demo πŸ“² ios-demo

videosdk.live's People

Contributors

ahmedbhesaniya97 avatar arjun-kava avatar sagarkava avatar videosdkadmin avatar

Stargazers

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

Watchers

 avatar  avatar

videosdk.live's Issues

Getting CORS Error on Login using Google

Getting the following error when trying to login to app.videosdk.live using Google to authenticate. Completely unable to login to the dashboard.

Access to fetch at 'https://api.videosdk.live/v1/users/auth' from origin 'https://app.videosdk.live' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

"TypeError: Cannot read properties of undefined (reading 'enumerateDevices')"

We're using the WebRTC API to enable webcam access. The video API works locally, but when I deploy it to my host, I get the following error:

php
Copy code
TypeError: Cannot read properties of undefined (reading 'enumerateDevices')
at e. (main.6e092ceb.js:2:190551)
at l (main.6e092ceb.js:2:632180)
at Generator._invoke (main.6e092ceb.js:2:631968)
at Generator.next (main.6e092ceb.js:2:632609)
at n (main.6e092ceb.js:2:651750)
at s (main.6e092ceb.js:2:651953)
at main.6e092ceb.js:2:652012
at new Promise ()
at e. (main.6e092ceb.js:2:651893)
at e. (main.6e092ceb.js:2:191304)

I believe this error is related to the navigator.mediaDevices.enumerateDevices() method used to retrieve a list of available media input and output devices. However, I am not sure how to resolve this issue.

I have already checked the browser compatibility and ensured that the correct permissions are granted to access the user's webcam and microphone. I have also verified that the necessary libraries and dependencies are included and up-to-date in my project.

Can anyone provide any guidance on how to troubleshoot and fix this error?

js-sdk package not working in iOS apps

I want to thank the team for providing everyone with this amazing resource in the first place.

In my application, I used the @videosdk.live/js-sdk package. It runs smoothly on the web and Android but not in the iOS apps.

I'm having trouble with the join meeting(join()) function because I'm not receiving a response from the "meeting-joined" event; instead, I'm getting a "meeting-left" event only in iOS apps.

Code

 
startMeeting() {
  this.initMeeting();
  this.meeting.join();
  this.handleMeetingEvents(this.meeting);
  const showJoinScreenMessage = this.renderer.createElement('div');
  this.renderer.setAttribute(
    showJoinScreenMessage,
    'id',
    'show-join-screen-message'
  );
  this.renderer.setProperty(
    showJoinScreenMessage,
    'innerHTML',
    'Please wait to join meeting...'
  );
  this.renderer.setStyle(showJoinScreenMessage, 'color', 'black');
  this.renderer.setStyle(showJoinScreenMessage, 'fontSize', '20px');
  this.renderer.setStyle(showJoinScreenMessage, 'fontWeight', 'bold');
  this.renderer.setStyle(showJoinScreenMessage, 'marginTop', '20px');
  this.renderer.setStyle(showJoinScreenMessage, 'marginLeft', '20px');
  this.renderer.appendChild(document.body, showJoinScreenMessage);
}

async initMeeting() {
  this.showParticipantNameError = false;
  VideoSDK.config(meetingToken);
  this.meeting = VideoSDK.initMeeting({
    meetingId: this.meetingId,
    name: this.participantName,
    micEnabled: true,
    webcamEnabled: true,
    maxResolution: 'hd',
  });
}


handleMeetingEvents(meeting: any) {

  this.localParticipant = meeting.localParticipant;
  this.participants = meeting.participants;

  meeting.on('meeting-joined', () => {
    var showJoinScreenMessage = document.getElementById(
      'show-join-screen-message'
    );
    this.renderer.removeChild(document.body, showJoinScreenMessage);
    const { participantMediaElement } = this.participantGridGenerator(
      this.meeting.localParticipant
    );

    meeting.localParticipant.on('stream-enabled', (stream: any) => {
      console.log('Stream Enabled: ');
      this.handleStreamEnabled(
        stream,
        meeting.localParticipant,
        true,
        participantMediaElement
      );
    });
    meeting.localParticipant.on('stream-disabled', (stream: any) => {
      console.log('Stream Disabled: ');
      this.handleStreamDisabled(
        stream,
        meeting.localParticipant,
        true,
        participantMediaElement
      );
    });
  });

  meeting.on('participant-left', (participant: any) => {
    console.log('Participant Left: ', participant.id);

    var participantGridItem = document.getElementById(
      `participant-grid-item-${participant.id}`
    );

    this.participantGridContainer.nativeElement.removeChild(participantGridItem);
  });

  meeting.on('meeting-left', () => {
    console.log('Meeting Left');
    console.log(this.meeting.MediaStream)
    // remove all children nodes from participant grid container
    while (this.participantGridContainer.nativeElement.firstChild) {
      this.participantGridContainer.nativeElement.removeChild(
        this.participantGridContainer.nativeElement.firstChild
      );
    }
    this.showMeetingScreen = false;
    this.showJoinScreen = true;
  });

  //remote participant
  meeting.on('participant-joined', (participant: any) => {

    console.log('New Participant Joined: ', participant, participant.id);
    this.totalParticipant.push({
      displayName: participant.displayName,
      id: participant.id,
      isAdmin: false
    });

    this.disableMicUserResponse();
    console.log('totalParticipant', this.totalParticipant);

    var { participantMediaElement } =
      this.participantGridGenerator(participant);
    participant.setQuality('high');
    participant.on('stream-enabled', (stream: any) => {
      this.handleStreamEnabled(
        stream,
        participant,
        false,
        participantMediaElement
      );
    });
    participant.on('stream-disabled', (stream: any) => {
      this.handleStreamDisabled(
        stream,
        participant,
        false,
        participantMediaElement
      );
    });
  });

  meeting.on("speaker-changed", (participant: any) => {
    this.changedFullVideoMode(participant, true);
  });



  meeting.on("presenter-changed", (participant: any) => {
    console.log(participant, 'presenter-changed');

    document.getElementById('participant-grid-item-' + participant)?.classList.add('active-presenter');
  });



  if (meeting) {
    this.showJoinScreen = false;
    this.showMeetingScreen = true;
  }
}

ws response

ws response

Xcode Logs

Xcode log

Error occurred

Error page

Screen share doesnt share audio

Hi there, thanks for the incredible work!

I'm having trouble while sharing the screen cannot share the audio screen, and also is it possible to send attachments through chat?
Currently, Im using [email protected]

After migrating app to expo, app no longer builds

Seems related to this library since it references "webrtc" in that file.

Here is my AppEntry.js file

`import registerRootComponent from 'expo/build/launch/registerRootComponent';

import App from '../../App';
import { register } from '@videosdk.live/react-native-sdk';

register();

registerRootComponent(App);
`

Confirmed that it is related to videoSDK because error goes away when I comment out all references to it in the code.
Screenshot 2024-03-29 at 8 14 49β€―PM

[js-sdk] not getting `INVALID_MEETING_ID` error

Hello,

I'm trying out your service and have setup a simple demo, I wanted to test if I'm able to get reliable errors.

With latest js sdk, I you try to init & join a meeting that doesn't exists, you get a meeting-state-changed FAILED.
But no error event.

Room not found while validating it

Hi So i'm generating a meeting room on the backend,
When trying to validate the room id i get room not found.

export const validateMeeting = async ({ roomId, token }) => {
  const url = `${API_BASE_URL}/v2/rooms/validate/${roomId}`;

  const options = {
    method: "GET",
    headers: { Authorization: token, "Content-Type": "application/json" },
  };

  const result = await fetch(url, options)
    .then((response) => {
      if(response.ok) response.json()
    }) //result will have meeting id
    .catch((error) => console.error("error", error));

  return result ? result.roomId === roomId : false;
};

UI of Viewer View

Screenshot_1688646950

I'm getting this view when a user is joining with "VIEWER" mode

Here's the code snippet I've used

`<SafeAreaView style={{ flex: 1, backgroundColor: 'black' }}>
{hlsState == 'HLS_PLAYABLE' ? (
<>
{/* Render Header for copy meetingId and leave meeting*/}

      {/* Render VideoPlayer that will play `downstreamUrl`*/}
      <Video
        // controls={true}
        source={{ uri: hlsUrls.downstreamUrl}}
        resizeMode={'stretch'}
        style={{
          flex: 1,
          backgroundColor: 'black',
        }}
        onError={e => console.log('error', e)}
      />
    </>
  ) : (
    <SafeAreaView
      style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text style={{ fontSize: 20, color: 'white' }}>
        HLS is not started yet or is stopped
      </Text>
    </SafeAreaView>
  )}
</SafeAreaView>`

thanks in advanced for helping

Quit Spamming

Hi, could I request you stop spamming other communities with messages directing people to your website?

Multiple customers have reported it to us and find it very annoying.

Prebuilt UI not responsive when displayed in a container (using containerId)

My goal is to embed the prebuilt UI in one of my (React) view so that it takes roughly half the screen (horizontally for large screen devices and vertically otherwise).

Some examples:

  • The join meeting button sometimes gets close to or partially under the bottom edge of the container when using half of the height on tablet/small laptop form factors.
  • The join screen view is not responsive for any small container (anything not full-size desktop), it is not compatible with mobile devices.

I know one workaround probably is to not use the prebuilt UI, but I'd like to get a first version out as fast as possible with as little work on the UI as possible.

Live stream in background service

I am using live stream in background service to start live stream even when app is closed so i added some lines in background service to start live stream when volume button pressed 5 times in row (Don't make anttention about the way i catch the volume button it's just for test ) . And in log the live stream start successfully but when i am trying to join the live stream from web the video disply as a dark screen.

Note : all the function is work fine when the app is in foreground this issue display in background only.

This my code that i use in background service

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:logger/logger.dart';
import 'package:myth/app.dart';
import 'package:myth/config/stream_config.dart';
import 'package:myth/features/emergency/data/data_source/emergency_data_remote_source.dart';
import 'package:myth/features/emergency/params/start_stream_parameters.dart';
import 'package:myth/features/home/data/api_call.dart';
import 'package:videosdk/videosdk.dart';

class BackgroundLiveStreamService {
  void handleVolumeButtonPress() async {
    await FlutterVolumeController.setVolume(1);
    double counter = 1;
    Timer? timer;
    FlutterVolumeController.addListener(
      (volume) async {
        counter++;
        timer?.cancel();
        print(counter);
        if (counter >= 5) {
          counter = 1.0;
          await FlutterVolumeController.setVolume(1);
          await startLiveStream();
          runApp(App.instance);
        }
        timer = Timer(const Duration(seconds: 1), () {
          counter = 1.0;
        });
      },
    );
  }

  Future<void> startLiveStream() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) {
      print('user is null');
      return;
    }
    //init meeting
    await createMeeting().then((meetingId) async {
      Logger().v(meetingId);

      final dataSource = EmergencyDataRemoteSource();
      final room = VideoSDK.createRoom(
        roomId: meetingId,
        token: LiveStreamConfig.token,
        displayName: 'User',
        defaultCameraIndex: 1,
      );
      dataSource.startLiveLocation(user.uid);
      Future<void> createLiveStream() async {
        Logger().i('createLiveStream');
        await dataSource.createLiveStream(
          StartSteamParameters(
            roomId: meetingId,
            dateTime: DateTime.now(),
            userId: user.uid,
            streamId: meetingId,
            userEmail: user.email ?? '',
            userName: user.displayName ?? '',
            deactivateCode: '5555',
          ),
        );
        Logger().i('live stream created');
      }

      await Future.wait(
        <Future<void>>[
          createLiveStream(),
          joinAndStartRecording(room),
        ].map<Future<void>>((e) => e),
      ).catchError((e) => Logger().e(e));
    });
  }

  Future<void> joinAndStartRecording(Room room) async {
    await room.join();
    Timer(const Duration(seconds: 5), () async {
      await room.startHls(
        config: {
          "layout": {
            "type": "SPOTLIGHT",
            "priority": "PIN",
            "GRID": 20,
          },
          "mode": "video-and-audio",
          "theme": "DARK",
          "quality": "high",
          "orientation": "portrait",
        },
      );
      Logger().i('start recording');
      await room.startRecording(
        config: {
          "autoStartConfig": {
            "recording": {
              "config": {
                "layout": {
                  "type": "SPOTLIGHT",
                  "priority": "SPEAKER",
                  "gridSize": 1,
                },
                "mode": "video-and-audio",
                "quality": "med",
                "orientation": "portrait",
              },
            },
          },
        },
      ).onError((error, stackTrace) => Logger().e(error, stackTrace));
      Logger().i('recording started');
    });
  }
}

And this is the AndroidManifest.xml :
`

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<uses-feature android:name="android.hardware.camera" />

<application
    android:name="${applicationName}"
    android:icon="@mipmap/ic_launcher"
    android:label="myth">
    <uses-library
        android:name="org.apache.http.legacy"
        android:required="false" />
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location">
    </service>
    <receiver
        android:name=".SosWidget"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/sos_widget_info" />
    </receiver>

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="AIzaSyDObDhEPX50nDJ4NuApPrJ0pMg41igS5Ao" />

    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:exported="true"
        android:hardwareAccelerated="true"
        android:launchMode="standard"
        android:theme="@style/LaunchTheme"
        android:windowSoftInputMode="adjustResize">

        <!--
             Specifies an Android theme to apply to this Activity as soon as
             the Android process has started. This theme is visible to the user
             while the Flutter UI initializes. After that, this theme continues
             to determine the Window background behind the Flutter UI.
        -->
        <meta-data
            android:name="io.flutter.embedding.android.NormalTheme"
            android:resource="@style/NormalTheme" />

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data
            android:name="flutter_deeplinking_enabled"
            android:value="true" />
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "https://mythsostrigger.page.link/sos” -->
            <data
                android:host="mythsostrigger.page.link"
                android:pathPrefix="/sos"
                android:scheme="https" />
            <data android:scheme="https" />
        </intent-filter>

    </activity>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="high_importance_channel" />
    <!--

Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
-->

`

And this is my background service code :

import 'dart:async';
import 'dart:ui';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get_it/get_it.dart';
import 'package:logger/logger.dart';
import 'package:myth/core/app_manager/user/user_location.dart';
import 'package:myth/core/service_locator/service_locator.dart';
import 'package:myth/firebase_options.dart';

import 'background_service_functions.dart';

@pragma('vm:entry-point')
Future<void> onStart(ServiceInstance service) async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  setup();
  DartPluginRegistrant.ensureInitialized();
  Logger().i('AppBackgroundService', 'onStart');
  UserLocation().startUpdatingLocation();
  BackgroundLiveStreamService().handleVolumeButtonPress();
}

@pragma('vm:entry-point')
FutureOr<bool> onIosBackground(ServiceInstance service) async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  GetIt.instance.registerSingleton<FirebaseAuth>(FirebaseAuth.instance);
  DartPluginRegistrant.ensureInitialized();
  Logger().i('AppBackgroundService', 'onStart');
  UserLocation().startUpdatingLocation();
  // await handleVolumeButtonPress();
  return true;
}

class AppBackgroundService {
  factory AppBackgroundService() => _instance;

  AppBackgroundService._internal();

  static final AppBackgroundService _instance =
      AppBackgroundService._internal();

  @pragma('vm:entry-point')
  Future<void> init() async {
    DartPluginRegistrant.ensureInitialized();
    final service = FlutterBackgroundService();
    await service.configure(
      androidConfiguration: AndroidConfiguration(
        onStart: onStart,
        autoStart: true,
        isForegroundMode: true,
      ),
      iosConfiguration: IosConfiguration(
        autoStart: true,
        onForeground: onStart,
        onBackground: onIosBackground,
      ),
    );
    await service.startService();
  }
}

For now i need it to work only on android.

Duplicated participants when only one participant is joining

Hello,

Not sure what the issue but participants in the below snippet returns duplicated participants. The issue does not appear in react/react-dom @17.0.2

  import { useMeeting } from "@videosdk.live/react-sdk";
  const { participants } = useMeeting();

Which React version this issue appear?

 "react": "^18.1.0"
 "react-dom": "^18.1.0"

[codesandbox]
https://codesandbox.io/s/great-ganguly-km6pke
[code repo]
https://github.com/mohamedsamara/react-videosdk-codesandbox

Thanks,
Mohamed

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.