Call Container

Similar to Flutter’s out-of-the-box Container widget, StreamCallContainer serves as a convenient widget for handling everything related to video and calling. It is the easiest way to setup a screen that shows incoming, outgoing and active call screens which contain the current participants video feeds and the call controls.

CallContainer sets up the following functionality by connecting multiple components:

  • StreamOutgoingCallContent: When the user is calling other people. Shows other participants avatars and controls for switching audio/video and canceling the call.
  • StreamIncomingCallContent: When the user is being called by another person. Shows the incoming call screen.
  • StreamCallContent: When the user is in an active call.

In this section we will cover this higher level component which enables you to quickly implement a video calling app.

At its simplest, you only need to provide a Call object to the StreamCallContainer widget:

import 'package:flutter/material.dart';
import 'package:stream_video_flutter/stream_video_flutter.dart';

// Example method called to create a new call
Future<void> startCall() {
    final call = StreamVideo.instance.makeCall(
      callType: StreamCallType.defaultType(),
      id: {CALL_ID},
    );

    final result = await call.getOrCreate();

    result.fold(
      success: (success) {
        if (mounted) {
          Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => MyCallScreen(call)),
            );
        }
      },
      failure: (failure) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error: ${failure.error.message}'),
          ),
        );
      },
    );
}

class MyCallScreen extends StatelessWidget {
    const MyCallScreen(this.call, {super.key});

    final Call call;
    
    @override
    Widget build(BuildContext context) {
        return StreamCallContainer(
            call: call,
        );
    }
}

Preview of Call Container

Customizing Call Container

const StreamCallContainer({
  super.key,
  required this.call,
  this.callConnectOptions,
  this.onBackPressed,
  this.onLeaveCallTap,
  this.onAcceptCallTap,
  this.onDeclineCallTap,
  this.onCancelCallTap,
  this.incomingCallBuilder,
  this.outgoingCallBuilder,
  this.callContentBuilder,
  this.pictureInPictureConfiguration = const PictureInPictureConfiguration(),
});

Developers can easily respond to user actions, such as accepting or declining a call, by using exposed callbacks and builders.

To replace default screens, such as the one displayed when an incoming call is detected, developers can use one of the many optional builders available.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamCallContainer(
        call: widget.call,
        incomingCallBuilder: (context, call, callState) {
          return CustomIncomingCallScreen(call: call, state: callState);
        },
      ),
    );
  }

All the builders exposed by StreamCallContainer provide users with an ongoing Call object and the associated CallState. These can be used to subscribe to changes and display different UI options depending on the events.

If your use case does not require ringing, incoming, or outgoing capabilities similar to Google Meet, then our CallScreen widget may be a better option. Keep reading to learn how to use it in your application.

Callbacks

Apart from UI customization you can also customize the behaviour of certain built-in actions.

  • onBackPressed: Called when the back button is pressed.
  • onLeaveCallTap: Called when the leave call button is tapped.
  • onAcceptCallTap: Called when the accept call button is tapped.
  • onDeclineCallTap: Called when the decline call button is tapped.
  • onCancelCallTap: Called when the cancel call button is tapped.

Call Connect Options

Providing callConnectOptions as a parameter to StreamCallContainer is one way of setting up initial call configuration. You can read more about it and other ways of providing it here.

CallConnectOptions({
    this.camera = TrackDisabled._instance,
    this.microphone = TrackDisabled._instance,
    this.screenShare = TrackDisabled._instance,
    this.audioOutputDevice,
    this.audioInputDevice,
    this.videoInputDevice,
    this.speakerDefaultOn = false,
    this.cameraFacingMode = FacingMode.user,
    this.targetResolution,
    this.screenShareTargetResolution,
  })

Picture-in-Picture Configuration

The pictureInPictureConfiguration property allows you to configure Picture-in-Picture mode. Detailed description of Picture in Picture functionality can be found here.

PictureInPictureConfiguration({
    this.enablePictureInPicture = false,
    this.androidPiPConfiguration = const AndroidPictureInPictureConfiguration(),
    this.iOSPiPConfiguration = const IOSPictureInPictureConfiguration(),
});
© Getstream.io, Inc. All Rights Reserved.