Search code examples
androidflutteragora.iovideochat

Agora in Flutter- disablle one persons's video and make another person's video full screen in the video chat


I am using Agora in a Flutter application. It's a very basic app where 2 users can just go online to have a video chat with one another. The source code is pretty small in size and easy to understand as well. But my issue is: I want to show only one person (Person1) in the video and not the other person (Person2).

I have used the agora_rtc_engine plugin.

main.dart:

import 'dart:async';

import 'package:agora_rtc_engine/rtc_engine.dart';
import 'package:agora_rtc_engine/rtc_local_view.dart' as RtcLocalView;
import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView;
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';


const appId = "...";//Obtain it from Agora site
const token = ""; // Temporary token generated from Agora site

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // int? _remoteUid=1;

  int _remoteUid=1; // for another user remoteUid=2;
  bool _localUserJoined = false;
  late RtcEngine _engine;

  @override
  void initState() {
    super.initState();
    initAgora();
  }

  Future<void> initAgora() async {
    // retrieve permissions
    await [Permission.microphone, Permission.camera].request();

    //create the engine
    _engine = await RtcEngine.create(appId);
    await _engine.enableVideo();
    _engine.setEventHandler(
      RtcEngineEventHandler(
        joinChannelSuccess: (String channel, int uid, int elapsed) {
          print("local user $uid joined");
          setState(() {
            _localUserJoined = true;
          });
        },
        userJoined: (int uid, int elapsed) {
          print("remote user $uid joined");
          setState(() {
            _remoteUid = uid;
          });
        },
        userOffline: (int uid, UserOfflineReason reason) {
          print("remote user $uid left channel");
          setState(() {
            // _remoteUid = null;
            _remoteUid = 0;
          });
        },
      ),
    );

    // await _engine.joinChannel(token, "test", null, 0);
    await _engine.joinChannel(token, "InstaClass", null, 0);

  }

  // Create UI with local view and remote view
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Agora Video Call'),
      ),
      body: Stack(
        children: [
          Center(
            child: _remoteVideo(),
          ),
          Align(
            alignment: Alignment.topLeft,
            child: Container(
              width: 100,
              height: 150,
              child: Center(
                child: _localUserJoined
                    ? RtcLocalView.SurfaceView()
                    : CircularProgressIndicator(),
              ),
            ),
          ),
        ],
      ),
    );
  }

  // Display remote user's video
  Widget _remoteVideo() {
    
    if (_remoteUid != 0) {
      return RtcRemoteView.SurfaceView(
        uid: _remoteUid,
        channelId: "InstaClass",
      );
    }else {
      return Text(
        'Please wait for remote user to join',
        textAlign: TextAlign.center,
      );
    }
  }
}

Same code is used for both Person1 and Person2 with a few changes. The above code snippet is for Person1 (notice int remoteUid=1;). For Person2, I have used int remoteUid=2;. For disabling the video of Person2, in Person2's app, I have added the following line

_engine.enableLocalVideo(false)

after the line:

await _engine.enableVideo();

Now Person2 sees Person1's video (i.e., remote video) in full screen but does not see his own (Person2) video (i.e., local video). A black rectangle is shown in the place of the local video.

Q1) How can I hide this black rectangle ? I just want to show only the remote video from Person2's side.

And from person1's side, no video of Person2 is shown and Person1's video is shown in a small rectangle.

Q2) How can I show Person1's video in full screen instead of a small rectangle from his own (Person1) side ?


Solution

  • You need to remove Align widget from you code to hide the small screen from your call UI. This will hide the box and even if you don't call _engine.enableLocalVideo(false) functions local video will not be visible and after doing so your both questions should be solved. Try once

     @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Agora Video Call'),
          ),
          body: Stack(
            children: [
              Center(
                child: _remoteVideo(),
              ),
            ],
          ),
        );
      }
    

    For Full screen video of self you can assign local video instead of remote video to the Center widget

     @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Agora Video Call'),
          ),
          body: Stack(
            children: [
              Center(
                child: _localUserJoined
                    ? RtcLocalView.SurfaceView()
                    : CircularProgressIndicator(),
              ),
            ],
          ),
        );
      }