Suggestions

close search

Getting started with Stringee Video Conference API using Flutter Plugin

Step 1: Prepare

  1. Before using Stringee Video Conference API for the first time, you must have a Stringee account If you do not have a Stringee account, sign up for free here: https://developer.stringee.com/account/register

  2. Create a Project on Stringee Dashboard Stringee create Project

Step 2: Install stringee-flutter-plugin

  1. Put stringee-flutter-plugin into the same directory of your project them add the following to your pubspec.yaml file
    dependencies:
        stringee_flutter_plugin:
            git:
                url: https://github.com/stringeecom/stringee_flutter_plugin.git
  2. Install the plugin by running the following command from the project root:
    $ flutter pub get

Step 3: Setup

Android

  1. Permissions The Stringee Android SDK requires some permissions from your AndroidManifest
    • Open up android/app/src/main/AndroidManifest.xml
    • Add the following lines:
      // for internet access
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      // for audio access
      <uses-permission android:name="android.permission.RECORD_AUDIO" />
      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
      // for camera access
      <uses-permission android:name="android.permission.CAMERA" />
      // for bluetooth access
      <uses-permission android:name="android.permission.BLUETOOTH" />
      <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
  2. Proguard If your project uses ProGuard, you may have to add the following settings to the ProGuard configuration file to ensure Stringee builds correctly:
    • Create file proguard-rules.pro in your app/ dir and insert inside:
      #Flutter Wrapper
      -dontwarn org.webrtc.**
      -keep class org.webrtc.** { *; }
      -keep class com.stringee.** { *; }
    • Add the following lines to /app/buidl.gradle :
      android {
      ...
          buildTypes {
          ...
              release {
              ...
              useProguard true
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
              }
          }
      }

iOS

  1. From the command line run following command:

    pod install --repo-update
  2. After run cocoapods command, open project file .xcworkspace

  3. In the "Build Settings" tab -> "Other linker flags" add "$(inherited)" flag

  4. In the "Build Settings" tab -> "Enable bitcode" select "NO"

  5. Right-click the information property list file (Info.plist) and select Open As -> Source Code. Then insert the following XML snippet into the body of your file just before the final element:

    <key>NSCameraUsageDescription</key>
    <string>$(PRODUCT_NAME) uses Camera</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>$(PRODUCT_NAME) uses Microphone</string>
  6. In the "Build Settings" tab -> "Allow Non-modular includes in Framework Modules" select "YES"

Step 4: Connect to Stringee Server

In order to connect to Stringee Server, 3-parties authentication is required as described here: Client authentication

For testing purpose, go to Dashboard -> Tools -> Generate Access token and generates an access_token. In production, the access_token should be generated by your server, here is a sample code generates access token here: https://github.com/stringeecom/server-samples/tree/master/access_token

  1. Initialize StringeeClient:
    import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart';
    ...
    StringeeClient _client = StringeeClient();
  2. Register the client's events in your State

    class _MyHomePageState extends State<MyHomePage> {
    ...
        @override
        Future<void> initState() {
            super.initState();
            ...
            /// Listen for the StringeeClient event
            _client.eventStreamController.stream.listen((event) {
                Map<dynamic, dynamic> map = event;
                switch (map['eventType']) {
                    case StringeeClientEvents.didConnect:
                        handleDidConnectEvent();
                        break;
                    case StringeeClientEvents.didDisconnect:
                        handleDiddisconnectEvent();
                        break;
                    case StringeeClientEvents.didFailWithError:
                        int code = map['body']['code'];
                        String msg = map['body']['message'];
                        handleDidFailWithErrorEvent(code,msg);
                        break;
                    case StringeeClientEvents.requestAccessToken:
                        handleRequestAccessTokenEvent();
                        break;
                    case StringeeClientEvents.didReceiveCustomMessage:
                        handleDidReceiveCustomMessageEvent(map['body']);
                        break;
                    default:
                        break;
                }
            });
            ...
        }
        ...
        /// Invoked when the StringeeClient is connected
        void handleDidConnectEvent() {}
    
        /// Invoked when the StringeeClient is disconnected
        void handleDiddisconnectEvent() {}
    
        /// Invoked when StringeeClient connect false
        void handleDidFailWithErrorEvent(int code, String message) {}
    
        /// Invoked when your token is expired
        void handleRequestAccessTokenEvent() {}
    
        /// Invoked when get Custom message
        void handleDidReceiveCustomMessageEvent(Map<dynamic, dynamic> map) {}
        ...
    }
  3. Connect
        @override
            Future<void> initState() {
                super.initState();
                ...
                String token = 'PUT YOUR TOKEN HERE'
                _client.connect(token);
                ...
            }

Step 5: Connect room

After the client connects to Stirngee server, follows these steps to connect to a room:

  1. Initialize StringeeVideo
    import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart';
    ...
    late StringeeVideo _video;
    ...
    _video = StringeeVideo(client);

    When creating StringeeVideo, you must pass StringeeClient which you used to connect in step 4.

  2. Create and join room

In order to create room, you will need to use rest api, described here: https://developer.stringee.com/docs/rest-api-reference/room-management.

In order to join room, you will need token to the room credential : room_token. In production application, the room_token should be generated by your server sample code generates room token here: https://developer.stringee.com/docs/room-token

```
late StringeeRoom? _room;
...
_video.joinRoom('YOUR_ROOM_TOKEN').then((value) {
    if (value['status']) {
        _room = value['body']['room'];
        List<StringeeVideoTrackInfo> trackInfos = value['body']['videoTrackInfos'];
        List<StringeeRoomUser> users = value['body']['users'];
    }
});
```

In which:

  1. Register the room's events

    /// Listen for the StringeeRoom event
    _room!.eventStreamController.stream.listen((event) {
        Map<dynamic, dynamic> map = event;
        switch (map['eventType']) {
            case StringeeRoomEvents.didJoinRoom:
                handleJoinRoomEvent(map['body']);
                break;
            case StringeeRoomEvents.didLeaveRoom:
                handleLeaveRoomEvent(map['body']);
                break;
            case StringeeRoomEvents.didAddVideoTrack:
                handleAddVideoTrackEvent(map['body']);
                break;
            case StringeeRoomEvents.didRemoveVideoTrack:
                handleRemoveVideoTrackEvent(map['body']);
                break;
            case StringeeRoomEvents.didReceiveRoomMessage:
                handleReceiveRoomMessageEvent(map['body']);
                break;
            case StringeeRoomEvents.trackReadyToPlay:
                handleTrackReadyToPlayEvent(map['body']);
                break;
            default:
                break;
        }
    }
    ...
    
    /// Invoked when the another user join room
    void handleJoinRoomEvent(StringeeRoomUser joinUser) {}
    
    /// Invoked when the another user leave room
    void handleLeaveRoomEvent(StringeeRoomUser leaveUser) {}
    
    /// Invoked when the add track to room
    void handleAddVideoTrackEvent(StringeeVideoTrack addTrack) {}
    
    /// Invoked when the remove track from room
    void handleRemoveVideoTrackEvent(StringeeVideoTrack removeTrack) {}
    
    /// Invoked when receive message in room
    void handleReceiveRoomMessageEvent(Map<dynamic, dynamic> bodyMap) {}
    
    /// Invoked when track is ready to display video
    void handleTrackReadyToPlayEvent(StringeeVideoTrack track) {}

    Step 6: Create local video track and publish to room

/// Create video track options
StringeeVideoTrackOptions options = StringeeVideoTrackOptions(
    audio: true,
    video: true,
    screen: false,
);
/// Create local video track
_video.createLocalVideoTrack(options).then((value) {
    if (value['status']) {
        /// After create Track success, you can publish track to room
        _room!.publish(value['body']).then((value) {
            if (value['status']) {
                // Success
            }
        });
    }
});

Step 7: Subscribe another video track

After receiving another video track information, you need to subscribe the track to display the video

StringeeVideoTrackOptions options = StringeeVideoTrackOptions(
    audio: track.audioEnable,
    video: track.videoEnable,
    screen: track.isScreenCapture,
);

_room!.subscribe(trackInfo, options).then((value) {
    if (value['status']) {
        // Success
    }
});

Step 8: Display track

fter subscribing another video track successfully or publishing your track successfully, you can display the video

StringeeVideoView videoView = track.attach(
    isOverlay: true,
    height: 200.0,
    width: 150.0,
    scalingType: ScalingType.fit,
);
...
return new Scaffold(
    backgroundColor: Colors.black,
    body: new Stack(
        children: <Widget>[
            ...
            videoView,
        ],
    ),
);

Step 8: Un publish video track:

If you don't want to stop showing your track in the room, you can remove your track from the room by unpublishing it:

_room!.unPublish(_localTrack).then((result) {
    if (result['status']) {
        // Success
    }
});

Step 9: Un subscribe video track:

If you don't want to receive another track's audio or video in the room, you can unsubscribe this track:

_room!.unsubscribe(removeTrackInfo).then((value) {
    if (value['status']) {
        // Success
    }
});

Step 10: Leave room

In order to leave room, you can call the following method:

_room!.leave(allClient: false).then((result) {
    if (result['status']) {
        // Success
    }
});

Step 11: Mute

Mute the local sound:

bool mute = true; // true: mute, false: unmute
your_track.mute(mute).then((result) {
    if (result['status']) {
        ///success
    }
});

Step 12: Switch camera

Switch the local camera:

your_track.switchCamera().then((result) {
    if (result['status']) {
        ///success
    }
});

Step 13: Turn on/off video

Turn on/off video:

bool enableVideo = true; // true: turn on, false: turn off
your_track.enableVideo(enableVideo).then((result) {
    if (result['status']) {
        ///success
    }
});

Step 14: Destroy room

After leaving the room, you need to release all resources in the StringeeRoom. Call this function to release all resources:

_room!.destroy();

Sample

You can view a completed version of this sample app on GitHub: https://github.com/stringeecom/stringee_flutter_plugin/tree/master/example