StreamCallContainer(
call: widget.call,
pictureInPictureConfiguration: const PictureInPictureConfiguration(
enablePictureInPicture: true,
disablePictureInPictureWhenScreenSharing: true,
),
)
Picture in Picture (PiP)
Picture in picture (PIP) keeps the call running and visible while you navigate to other apps.
Enable Picture-in-Picture
To enable Picture-in-Picture (PiP), set the enablePictureInPicture
property to true in the PictureInPictureConfiguration
provided to the StreamCallContainer
or StreamCallContent
widget.
Additionally, you can control whether PiP remains enabled when the local device is screen sharing using the disablePictureInPictureWhenScreenSharing
parameter (disabled by default).
Keep the Connection Active in Background
For Picture-in-Picture to function properly while the app is in the background, it is important to keep the connection to Stream backend active.
This is controlled by the keepConnectionsAliveWhenInBackground
property in StreamVideoOptions
, which must be set to true
.
Additionally, to ensure the local participant remains visible and audible in PiP mode, ensure muteVideoWhenInBackground
and muteAudioWhenInBackground
are set to false (false by default).
StreamVideo(
apiKey,
user: user,
token: token,
options: const StreamVideoOptions(
muteAudioWhenInBackground: false,
muteVideoWhenInBackground: false,
keepConnectionsAliveWhenInBackground: true,
),
);
Android
Android Configuration
To enable Picture in Picture on Android, you need to add the following configuration to your AndroidManifest.xml
file.
<activity android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
..
/>
Then you need to add this code to your MainActivity
class. It will enter Picture in Picture mode when the user leaves the app but only if the call is active.
import io.flutter.embedding.android.FlutterActivity
import io.getstream.video.flutter.stream_video_flutter.service.PictureInPictureHelper
class MainActivity: FlutterActivity() {
override fun onUserLeaveHint() {
super.onUserLeaveHint()
PictureInPictureHelper.enterPictureInPictureIfInCall(this)
}
}
Android Customization
For Android, you can customize the widget rendered while app is in Picture-in-Picture mode by providing callPictureInPictureBuilder
to PictureInPictureConfiguration
.
StreamCallContainer(
call: widget.call,
callContentBuilder: (
BuildContext context,
Call call,
CallState callState,
) {
return StreamCallContent(
call: call,
callState: callState,
pictureInPictureConfiguration: const PictureInPictureConfiguration(
enablePictureInPicture: true,
androidPiPConfiguration: AndroidPictureInPictureConfiguration(
callPictureInPictureBuilder: (context, call, callState) {
// YOUR CUSTOM WIDGET
},
)
),
);
},
);
iOS
Local camera feed in Picture-in-Picture mode
By default, iOS does not allow access to the user’s camera while the app is in the background. To enable it, the multitasking camera access property must be set to true.
For apps linked against iOS 18 or later, this property is automatically true if voip is included in UIBackgroundModes
. Additionally, apps with the com.apple.developer.avfoundation.multitasking-camera-access
entitlement will also have multitasking camera access enabled.
If the multitasking camera access property is true for your app based on the above conditions, the local camera feed will be visible in PiP mode. However, if you prefer to disable the local feed in PiP mode, set includeLocalParticipantVideo
to false:
StreamCallContainer(
call: widget.call,
callContentBuilder: (
BuildContext context,
Call call,
CallState callState,
) {
return StreamCallContent(
call: call,
callState: callState,
pictureInPictureConfiguration: const PictureInPictureConfiguration(
enablePictureInPicture: true,
iOSPiPConfiguration: IOSPictureInPictureConfiguration(
includeLocalParticipantVideo: false,
)
),
);
},
);
Enabling PiP support with custom call content widget
If you are not using our StreamCallContent
and instead building custom call content widget you can still enable Picture in Picture mode by adding StreamPictureInPictureUiKitView
anywhere in the widget tree. This widget will handle the Picture in Picture mode in iOS for you.
StreamCallContainer(
call: widget.call,
callContentBuilder: (
BuildContext context,
Call call,
CallState callState,
) {
return Stack(
children: [
StreamPictureInPictureUiKitView(call: call),
// YOUR CUSTOM WIDGET
],
);
},
);
Done. Now after leaving the app, you’ll see that the call will be still alive in the background like the one below: