From e6e4e33123f086346a8a90c9b679b8c7efd2ef4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Braz=CC=87ewicz?= Date: Tue, 7 Jul 2026 12:07:47 +0200 Subject: [PATCH 1/2] make video fit adaptive on web and desktop --- packages/stream_video_flutter/CHANGELOG.md | 1024 ++++++++++------- .../lib/src/renderer/video_renderer.dart | 72 +- .../lib/src/theme/call_participant_theme.dart | 9 +- 3 files changed, 643 insertions(+), 462 deletions(-) diff --git a/packages/stream_video_flutter/CHANGELOG.md b/packages/stream_video_flutter/CHANGELOG.md index 37cd3ec1e..c2b60803e 100644 --- a/packages/stream_video_flutter/CHANGELOG.md +++ b/packages/stream_video_flutter/CHANGELOG.md @@ -1,8 +1,13 @@ ## Upcoming +### βœ… Added + +- Added `VideoFit.adaptive`, which picks between `cover` and `contain` based on the video's own orientation: landscape/square video fills the tile while portrait/tall video is letterboxed so the whole frame stays visible. + ### πŸ”„ Changed - Increased minimum Flutter version to 3.38.0. +- Participant video fit now defaults per-platform when not explicitly set: `VideoFit.adaptive` on web and desktop (so portrait feeds such as phone cameras are shown in full instead of being cropped) and `VideoFit.cover` on mobile. Set `videoFit` explicitly on `StreamCallParticipantThemeData` (or the renderer widgets) to override. ## 1.4.1 @@ -60,174 +65,199 @@ Each call now owns an isolated native `PeerConnectionFactory`. This fixes cross- ## 1.3.2 ### 🐞 Fixed -* Fixed `consumeAndAcceptActiveCall` auto-accepting incoming calls on Android when the user opens the app without pressing the Accept button on the notification. The method now only consumes calls that the user explicitly accepted. -* Fixed coordinator REST API calls failing permanently when the JWT token expires. -* Fixed iOS Picture-in-Picture window not dismissing when the call ends during PiP mode. -* Fixed `CallDiagnosticsContent` throwing `failed to call super.dispose` when the widget was disposed while awaiting stats subscription cancellation. + +- Fixed `consumeAndAcceptActiveCall` auto-accepting incoming calls on Android when the user opens the app without pressing the Accept button on the notification. The method now only consumes calls that the user explicitly accepted. +- Fixed coordinator REST API calls failing permanently when the JWT token expires. +- Fixed iOS Picture-in-Picture window not dismissing when the call ends during PiP mode. +- Fixed `CallDiagnosticsContent` throwing `failed to call super.dispose` when the widget was disposed while awaiting stats subscription cancellation. ### πŸ”„ Changed -* Regenerated OpenAPI models to match the latest backend schema. -* Fixed broadcasting status updates not being wired through to call state. -* Updated conditional imports to support WASM. + +- Regenerated OpenAPI models to match the latest backend schema. +- Fixed broadcasting status updates not being wired through to call state. +- Updated conditional imports to support WASM. ### ⚠️ Deprecated -* `StreamHlsSettings.qualityTracks` (`List`) is deprecated β€” use `StreamHlsSettings.qualities` (`List`) instead. + +- `StreamHlsSettings.qualityTracks` (`List`) is deprecated β€” use `StreamHlsSettings.qualities` (`List`) instead. ### ✨ Refactor -* Refactored call control options to use `PartialCallStateBuilder` for reactive state updates instead of one-shot `call.state.value` reads. + +- Refactored call control options to use `PartialCallStateBuilder` for reactive state updates instead of one-shot `call.state.value` reads. ## 1.3.1 ### 🐞 Fixed -* Reverted iOS audio session release on call leave ([#1155](https://github.com/GetStream/stream-video-flutter/pull/1155)) due to reports of broken audio playout on some iOS sessions. -* Improved SFU join, recovery and migration logic to reduce failed joins with reconnect loops when joining full or shutting-down SFU -* Fixed race condition in `Call.join` when another connect is already in progress, with proper timeout handling. -* Fixed `consumeAndAcceptActiveCall` to ensure the coordinator WS is connected before consuming incoming calls during cold start. + +- Reverted iOS audio session release on call leave ([#1155](https://github.com/GetStream/stream-video-flutter/pull/1155)) due to reports of broken audio playout on some iOS sessions. +- Improved SFU join, recovery and migration logic to reduce failed joins with reconnect loops when joining full or shutting-down SFU +- Fixed race condition in `Call.join` when another connect is already in progress, with proper timeout handling. +- Fixed `consumeAndAcceptActiveCall` to ensure the coordinator WS is connected before consuming incoming calls during cold start. ## 1.3.0 ### βœ… Added -* Added video moderation support by providing `VideoModerationConfig` in `CallPreferences`. Check [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/call-moderation/) for more details. -* Added HiFi audio mode for high-fidelity scenarios such as live music, podcasts, and professional streaming. Use `SfuAudioBitrateProfile` to select an audio quality profile before joining a call: - * `SfuAudioBitrateProfile.voiceStandard` – Standard voice (64 kbps, default) - * `SfuAudioBitrateProfile.voiceHighQuality` – High-quality voice (128 kbps) - * `SfuAudioBitrateProfile.musicHighQuality` – HiFi music mode (128 kbps, audio processing disabled) -* Added stereo playout (iOS and Android) and capture (Android only) support with new `audioConfigurationPolicy` in `StreamVideoOptions`. Includes predefined policies: - * `AudioConfigurationPolicy.broadcaster()` – Mono playout with voice processing enabled (default) - * `AudioConfigurationPolicy.viewer()` – Stereo playout with voice processing disabled, ideal for passive listeners - * `AudioConfigurationPolicy.hiFi()` – Stereo capture and playout with voice processing disabled, ideal for hosts streaming high-fidelity audio - * `AudioConfigurationPolicy.custom()` – Full control over platform-specific audio settings with optional `basePolicy` fallback -* Added `RtcMediaDeviceNotifier.reinitializeAudioConfiguration()` to switch audio configuration policy at runtime (must be called before starting a call). + +- Added video moderation support by providing `VideoModerationConfig` in `CallPreferences`. Check [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/call-moderation/) for more details. +- Added HiFi audio mode for high-fidelity scenarios such as live music, podcasts, and professional streaming. Use `SfuAudioBitrateProfile` to select an audio quality profile before joining a call: + - `SfuAudioBitrateProfile.voiceStandard` – Standard voice (64 kbps, default) + - `SfuAudioBitrateProfile.voiceHighQuality` – High-quality voice (128 kbps) + - `SfuAudioBitrateProfile.musicHighQuality` – HiFi music mode (128 kbps, audio processing disabled) +- Added stereo playout (iOS and Android) and capture (Android only) support with new `audioConfigurationPolicy` in `StreamVideoOptions`. Includes predefined policies: + - `AudioConfigurationPolicy.broadcaster()` – Mono playout with voice processing enabled (default) + - `AudioConfigurationPolicy.viewer()` – Stereo playout with voice processing disabled, ideal for passive listeners + - `AudioConfigurationPolicy.hiFi()` – Stereo capture and playout with voice processing disabled, ideal for hosts streaming high-fidelity audio + - `AudioConfigurationPolicy.custom()` – Full control over platform-specific audio settings with optional `basePolicy` fallback +- Added `RtcMediaDeviceNotifier.reinitializeAudioConfiguration()` to switch audio configuration policy at runtime (must be called before starting a call). See the [documentation](https://getstream.io/video/docs/flutter/guides/camera-and-microphone/high-fidelity-audio/) for details. ### ⚠️ Deprecated -* Deprecated `androidAudioConfiguration` in `StreamVideoOptions`. Use `audioConfigurationPolicy` instead. + +- Deprecated `androidAudioConfiguration` in `StreamVideoOptions`. Use `audioConfigurationPolicy` instead. ### 🐞 Fixed -* Added handling for SFU `iceRestart` event β€” the client now correctly performs ICE restart and renegotiation when instructed by the SFU, improving fast reconnect reliability. -* Added PeerConnection SDP rollback on failed remote answer to prevent the publisher from getting stuck in an inconsistent signaling state. -* When `dropIfAloneInRingingFlow` is set to true in `CallPreferences` the call will now end when the last participant leaves the call. + +- Added handling for SFU `iceRestart` event β€” the client now correctly performs ICE restart and renegotiation when instructed by the SFU, improving fast reconnect reliability. +- Added PeerConnection SDP rollback on failed remote answer to prevent the publisher from getting stuck in an inconsistent signaling state. +- When `dropIfAloneInRingingFlow` is set to true in `CallPreferences` the call will now end when the last participant leaves the call. ## 1.2.4 ### 🐞 Fixed -* [Web] Fixed an issue with call being stuck during Connecting state. + +- [Web] Fixed an issue with call being stuck during Connecting state. ## 1.2.3 ### ⚑ Performance -* Improved `call.leave()` performance + +- Improved `call.leave()` performance ### βœ… Added -* Added `includesCallsInRecents` to iOS push configuration to control whether CallKit calls appear in Recents. + +- Added `includesCallsInRecents` to iOS push configuration to control whether CallKit calls appear in Recents. ### 🐞 Fixed -* Fixed race condition where remote tracks could arrive before participant join events, causing track state to be lost. -* Improved reconnection reliability: - * Added exponential backoff with jitter to fast reconnect attempts. - * Fixed fast reconnect deadline check to correctly trigger fallback to rejoin. - * Fixed network availability verification during subsequent fast reconnect attempts. - * Added `reconnectReason` to reconnect details for sfu logs. - * Fixed race condition where automatic ICE restart could interfere with fast reconnect, causing subscriber video to not recover. -* [iOS] Fixed audio session not being released when leaving a call, which prevented other audio packages from using the microphone. -* [iOS] Fixed CallKit event suppression to avoid repeated mute toggle loops. -* [Android] Fixed issues when accepting incoming calls from detached state (app exited via back button). -* [Android] Fixed incoming call notifications not showing when the app is in a detached state (e.g., after pressing the back button). -* [Android] Fixed video flickering in Skia renderer by scoping renderer keys with prefix and using stable participant-based keys. + +- Fixed race condition where remote tracks could arrive before participant join events, causing track state to be lost. +- Improved reconnection reliability: + - Added exponential backoff with jitter to fast reconnect attempts. + - Fixed fast reconnect deadline check to correctly trigger fallback to rejoin. + - Fixed network availability verification during subsequent fast reconnect attempts. + - Added `reconnectReason` to reconnect details for sfu logs. + - Fixed race condition where automatic ICE restart could interfere with fast reconnect, causing subscriber video to not recover. +- [iOS] Fixed audio session not being released when leaving a call, which prevented other audio packages from using the microphone. +- [iOS] Fixed CallKit event suppression to avoid repeated mute toggle loops. +- [Android] Fixed issues when accepting incoming calls from detached state (app exited via back button). +- [Android] Fixed incoming call notifications not showing when the app is in a detached state (e.g., after pressing the back button). +- [Android] Fixed video flickering in Skia renderer by scoping renderer keys with prefix and using stable participant-based keys. ## 1.2.2 ### 🐞 Fixed -* [Android] Fixed WebSocket/WebRTC connections persisting after app is killed from recents. Foreground services now properly terminate and leave calls when the app task is removed. + +- [Android] Fixed WebSocket/WebRTC connections persisting after app is killed from recents. Foreground services now properly terminate and leave calls when the app task is removed. ## 1.2.1 ### βœ… Added -* Added default sorting preset for Picture-in-Picture mode to prioritize the most relevant participant. + +- Added default sorting preset for Picture-in-Picture mode to prioritize the most relevant participant. ### 🐞 Fixed -* [Android] Fixed screen share notification tap not opening the app. -* [Android] Improved screen sharing foreground service reliability: + +- [Android] Fixed screen share notification tap not opening the app. +- [Android] Improved screen sharing foreground service reliability: - Added proper synchronization to ensure the foreground service is fully started before initiating media projection. - `startScreenSharingNotificationService` now returns a boolean indicating success/failure, preventing screen share attempts when the service fails to start. -* [iOS/macOS] Fixed crash when VoIP push is received before Flutter fully initializes from the terminated state. +- [iOS/macOS] Fixed crash when VoIP push is received before Flutter fully initializes from the terminated state. ## 1.2.0 ### βœ… Added -* [Android] Added support for screen audio sharing. To enable it set `captureScreenAudio` to true in `ScreenShareConstraints`. See [documentation](https://getstream.io/video/docs/flutter/advanced/screen_sharing/#screen-audio-sharing) for more details. + +- [Android] Added support for screen audio sharing. To enable it set `captureScreenAudio` to true in `ScreenShareConstraints`. See [documentation](https://getstream.io/video/docs/flutter/advanced/screen_sharing/#screen-audio-sharing) for more details. ### 🐞 Fixed -* Fixed unnecessary video filter reapplication when camera track is disabled. -* [Android] Fixed an issue where the camera freezes for person using screen sharing without PiP enabled. -* [Android] Fixed active foreground service not being started when notification permission is denied. + +- Fixed unnecessary video filter reapplication when camera track is disabled. +- [Android] Fixed an issue where the camera freezes for person using screen sharing without PiP enabled. +- [Android] Fixed active foreground service not being started when notification permission is denied. ## 1.1.0 ### βœ… Added -* Added `pipTrackPriority` parameter to `PictureInPictureConfiguration` to control whether screen sharing or camera track is preferred in PiP mode. When set to `camera`, the camera track is preferred, but screen share will still be shown as a fallback if the camera is disabled. -* Added multiple-host and screen sharing support in `LivestreamPlayer` and `LivestreamContent`. + +- Added `pipTrackPriority` parameter to `PictureInPictureConfiguration` to control whether screen sharing or camera track is preferred in PiP mode. When set to `camera`, the camera track is preferred, but screen share will still be shown as a fallback if the camera is disabled. +- Added multiple-host and screen sharing support in `LivestreamPlayer` and `LivestreamContent`. - New flags: `showMultipleHosts`, `layoutMode`, `screenShareMode`. - New builders: `livestreamHostsParticipantBuilder` and `livestreamHostsParticipantsFilter` to customize how hosts are selected and rendered. -* Added `videoFit` parameter in `LivestreamPlayer` to control contain/cover behavior when not in fullscreen. -* Livestream reconnect UI customization: +- Added `videoFit` parameter in `LivestreamPlayer` to control contain/cover behavior when not in fullscreen. +- Livestream reconnect UI customization: - `LivestreamPlayer`/`LivestreamContent`: added `livestreamFastReconnectingOverlayBuilder` to customize the UI shown during fast reconnect. - `LivestreamContent`: `livestreamNotConnectedBuilder` provides `isMigrating`/`isReconnecting` flags to tailor messaging when not connected. -* Call screen reconnect UI customization: +- Call screen reconnect UI customization: - `StreamCallContent`: added `callFastReconnectingOverlayBuilder` to render a custom overlay while fast reconnecting. - `StreamCallContent`: `callNotConnectedBuilder` now exposes `CallNotConnectedProperties` with `isMigrating`/`isReconnecting` to customize the not-connected/reconnecting view. ### 🐞 Fixed -* Fixed ANR (Application Not Responding) issue on Android that could happen when starting screen share service. -* Fixed crash on Android versions below API 31 when disabling Picture-in-Picture mode. + +- Fixed ANR (Application Not Responding) issue on Android that could happen when starting screen share service. +- Fixed crash on Android versions below API 31 when disabling Picture-in-Picture mode. ### ⚑ Performance -* Improved `call.join()` performance - reduced join time by optimizing WebRTC setup and deferring non-critical operations. -* Improved SFU allocation reliability. +- Improved `call.join()` performance - reduced join time by optimizing WebRTC setup and deferring non-critical operations. +- Improved SFU allocation reliability. ## 1.0.2 🐞 Fixed -* Fixed incoming call timeout handling. + +- Fixed incoming call timeout handling. - Use `streamVideo.observeCoreRingingEventsForBackground()` instead of `streamVideo.observeCallDeclinedRingingEvent()` in `firebaseMessagingBackgroundHandler` to support all necessary events. ## 1.0.1 ### βœ… Added -* Added support for changing the camera target resolution during an ongoing call using the `call.setCameraTargetResolution()` method. + +- Added support for changing the camera target resolution during an ongoing call using the `call.setCameraTargetResolution()` method. #### LivestreamPlayer Improvements -* Added support for Picture in Picture (PiP) mode, configurable via the `pictureInPictureConfiguration` parameter. For platform-specific setup, refer to the [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/). -* Introduced the `joinBehaviour` parameter, allowing control over whether and when the `LivestreamPlayer` automatically connects the user to a call. -* Added the `showRecordingsWhenEnded` parameter to `LivestreamPlayer`, which enables you to show or hide the recordings list in the default livestream ended UI. -* Refactored `LivestreamPlayer` to leverage `call.partialState` for more efficient state management. New builder methods have been introduced to accommodate this change, and some previous builder methods are now deprecated. + +- Added support for Picture in Picture (PiP) mode, configurable via the `pictureInPictureConfiguration` parameter. For platform-specific setup, refer to the [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/). +- Introduced the `joinBehaviour` parameter, allowing control over whether and when the `LivestreamPlayer` automatically connects the user to a call. +- Added the `showRecordingsWhenEnded` parameter to `LivestreamPlayer`, which enables you to show or hide the recordings list in the default livestream ended UI. +- Refactored `LivestreamPlayer` to leverage `call.partialState` for more efficient state management. New builder methods have been introduced to accommodate this change, and some previous builder methods are now deprecated. ## 1.0.0 ### 🚧 Breaking changes #### CallKit/Ringing + This release removes the dependency on `flutter_callkit_incoming`, resulting in several breaking changes to CallKit and ringing functionality: -* **CallKit/ringing configuration:** The initialization process is updated. Replace the `pushParams` parameter in `StreamVideoPushNotificationManager` with the new `pushConfiguration` field (`StreamVideoPushConfiguration`). -* **Parameter renaming:** The `nameCaller` parameter has been standardized and renamed to `callerName` across all relevant locations. -* **Removed properties:** - * The deprecated `callerCustomizationCallback` and `backgroundVoipCallHandler` have been fully removed from `StreamVideoPushNotificationManager`. - * The previously used `appName` field in `pushParams` has been removed as it was deprecated. On iOS, the app’s product name from build settings is now used instead. -* **API renames and type changes** - - `onCallKitEvent` is now `onRingingEvent` - - `observeCoreCallKitEvents` is now `observeCoreRingingEvents` - - `observeCallAcceptCallKitEvent` is now `observeCallAcceptRingingEvent` - - `observeCallDeclinedCallKitEvent` is now `observeCallDeclinedRingingEvent` - - `observeCallEndedCallKitEvent` is now `observeCallEndedRingingEvent` - - The `CallKitEvent` type is now `RingingEvent` +- **CallKit/ringing configuration:** The initialization process is updated. Replace the `pushParams` parameter in `StreamVideoPushNotificationManager` with the new `pushConfiguration` field (`StreamVideoPushConfiguration`). +- **Parameter renaming:** The `nameCaller` parameter has been standardized and renamed to `callerName` across all relevant locations. +- **Removed properties:** + - The deprecated `callerCustomizationCallback` and `backgroundVoipCallHandler` have been fully removed from `StreamVideoPushNotificationManager`. + - The previously used `appName` field in `pushParams` has been removed as it was deprecated. On iOS, the app’s product name from build settings is now used instead. +- **API renames and type changes** + - `onCallKitEvent` is now `onRingingEvent` + - `observeCoreCallKitEvents` is now `observeCoreRingingEvents` + - `observeCallAcceptCallKitEvent` is now `observeCallAcceptRingingEvent` + - `observeCallDeclinedCallKitEvent` is now `observeCallDeclinedRingingEvent` + - `observeCallEndedCallKitEvent` is now `observeCallEndedRingingEvent` + - The `CallKitEvent` type is now `RingingEvent` #### Video Filter + - The video filters feature, which enables blur and virtual backgrounds during calls, has been moved to a new package: `stream_video_filters`. To use video filters, add the package to your `pubspec.yaml` and update your relevant imports. #### Deprecated members + - Removed deprecated APIs and parameters. Migrate as follows: - `StreamVideo.muteVideoWhenInBackground` β†’ `StreamVideo.options.muteVideoWhenInBackground` - `StreamVideo.muteAudioWhenInBackground` β†’ `StreamVideo.options.muteAudioWhenInBackground` @@ -237,31 +267,37 @@ This release removes the dependency on `flutter_callkit_incoming`, resulting in - Removed `localParticipant` parameter from `AddReactionOption` constructor - Removed multiple deprecated builder callbacks in favor of [callbacks that don't provide the state object](https://github.com/GetStream/stream-video-flutter/pull/983); corresponding state object parameters in affected widgets have been removed. - Deprecated `androidAudioAttributesUsageType` and `androidAudioAttributesContentType` parameters in `RtcMediaDeviceNotifier.handleCallInterruptionCallbacks()` + --- ### 🍏 **Swift Package Manager (SPM)** + - Added Swift Package Manager (SPM) support for iOS. -> [!IMPORTANT] -> Flutter's iOS SPM is experimental and disabled by default. You can enable it via `flutter config --enable-swift-package-manager`. Flutter will fall back to CocoaPods for plugins that don't support SPM. See the [Flutter SPM docs](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers). + > [!IMPORTANT] + > Flutter's iOS SPM is experimental and disabled by default. You can enable it via `flutter config --enable-swift-package-manager`. Flutter will fall back to CocoaPods for plugins that don't support SPM. See the [Flutter SPM docs](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers). ### ✨ Improvements + - [Android] Significantly improved video filter performance, resulting in smoother frame rates during calls. ### βœ… Added + - Added `Call.ring()` to ring specific members of an existing call. Example: `call.ring(userIds: [''], video: true)`. Sends a ringing/VoIP push to the users’ devices. Users must already be members - use `call.addMembers()` first if needed. - Added `RtcMediaDeviceNotifier.pauseAudioPlayout()` / `RtcMediaDeviceNotifier.resumeAudioPlayout()` to mute and restore remote playback with platform-specific handling for iOS/macOS and Android. - [Android] Enhanced interruption handling via `RtcMediaDeviceNotifier.handleCallInterruptionCallbacks()`. - [Android] Added `RtcMediaDeviceNotifier.regainAndroidAudioFocus()` to request audio focus when it was lost without automatic regain. ### 🐞 Fixed -* [iOS] Resolved an issue in Picture in Picture where video tracks might remain disabled after returning the app to the foreground. -* [iOS] Addressed a problem where Picture in Picture was not exited properly if the call ended during PiP mode. -* [iOS] Fixed a bug where quickly backgrounding the app right after ending a call could still activate PiP mode. -* Resolved an issue that could cause the StreamVideo instance to be disposed prematurely before ringing events were fully processed when handling ringing notifications in the terminated state. + +- [iOS] Resolved an issue in Picture in Picture where video tracks might remain disabled after returning the app to the foreground. +- [iOS] Addressed a problem where Picture in Picture was not exited properly if the call ended during PiP mode. +- [iOS] Fixed a bug where quickly backgrounding the app right after ending a call could still activate PiP mode. +- Resolved an issue that could cause the StreamVideo instance to be disposed prematurely before ringing events were fully processed when handling ringing notifications in the terminated state. ## 0.11.2 🐞 Fixed + - [Web] Fixed setting input audio/video device passed by `CallConnectOptions` as well as switching those devices during the call. - [Web] Fixed changing the output audio device during the call. - [Android/iOS] Fixed an issue where screen sharing was not stopped correctly when canceled via the system UI on Android or iOS. @@ -271,11 +307,13 @@ This release removes the dependency on `flutter_callkit_incoming`, resulting in - Fixed an issue with initials creation when multicharacter symbols were used in a user name. βœ… Added + - [Web] Added `checkIfAudioOutputChangeSupported()` to the `Call` class to check whether the browser supports changing the audio output device. ## 0.11.1 πŸ”„ Changed + - The `byParticipantSource` participant sorting now accepts a list of sources. The default sorting for `speaker` and `livestream` presets now include other ingress sources. - Updated the renderscript dependency on Android to support 16kb page size. @@ -284,29 +322,30 @@ This release removes the dependency on `flutter_callkit_incoming`, resulting in 🚧 Build breaking changes > **Important:** This release includes breaking changes for Android development. -> +> > **Android Requirements:** +> > - Minimum compileSDK 36 > - Android Gradle Plugin >=8.12.1 > - Gradle wrapper >=8.13 > - Kotlin 2.2.0 -* Updated minimum Flutter version to 3.32.0 -* Updated minimum supported Dart SDK version to 3.8.0 +- Updated minimum Flutter version to 3.32.0 +- Updated minimum supported Dart SDK version to 3.8.0 🚧 Breaking changes -* **`Call.stats` payload structure changed** +- **`Call.stats` payload structure changed** - **Before:** `({ CallStats publisherStats, CallStats subscriberStats })` - **Now:** `({ PeerConnectionStatsBundle publisherStatsBundle, PeerConnectionStatsBundle subscriberStatsBundle })` - The record field names and element types have changed to provide more detailed WebRTC statistics -* **Stats-related fields removed from `CallState`** +- **Stats-related fields removed from `CallState`** - Removed: `publisherStats`, `subscriberStats`, `latencyHistory` - For periodic WebRTC stats: Use `call.stats` stream - For latest aggregated metrics: Use `call.statsReporter?.currentMetrics` -* **Dependency updates** +- **Dependency updates** - Updated most dependencies to their latest versions to ensure compatibility and security βœ… Added @@ -328,621 +367,714 @@ This release removes the dependency on `flutter_callkit_incoming`, resulting in ## 0.10.4 βœ… Added -* Extended `CallParticipantState` with `participantSource`. This indicates the participant's source channel (e.g., WebRTC, RTMP, WHIP) and can be used in filtering and sorting criteria. -* Livestream sorting preset now prioritises RTMP sources in layout sorting. -* Automatic SFU-driven pausing of inbound video to save bandwidth and prevent visual artifacts: - * New `SfuClientCapability.subscriberVideoPause` (on by default). Control via `Call.enableClientCapabilities()` / `Call.disableClientCapabilities()`. - * New `SfuInboundStateNotificationEvent` notifies when inbound tracks are paused or resumed. - * `CallParticipantState.pausedTracks` and `CallParticipantState.isTrackPaused()` let you check which tracks are currently paused. -* Added capability to remove a participant from a call via `call.kickUser()`. Requires the `kick-user` permission. + +- Extended `CallParticipantState` with `participantSource`. This indicates the participant's source channel (e.g., WebRTC, RTMP, WHIP) and can be used in filtering and sorting criteria. +- Livestream sorting preset now prioritises RTMP sources in layout sorting. +- Automatic SFU-driven pausing of inbound video to save bandwidth and prevent visual artifacts: + - New `SfuClientCapability.subscriberVideoPause` (on by default). Control via `Call.enableClientCapabilities()` / `Call.disableClientCapabilities()`. + - New `SfuInboundStateNotificationEvent` notifies when inbound tracks are paused or resumed. + - `CallParticipantState.pausedTracks` and `CallParticipantState.isTrackPaused()` let you check which tracks are currently paused. +- Added capability to remove a participant from a call via `call.kickUser()`. Requires the `kick-user` permission. 🐞 Fixed -* Multitasking camera on iOS is now enabled only once and kept enabled. This fixes potential errors when quickly toggling camera. + +- Multitasking camera on iOS is now enabled only once and kept enabled. This fixes potential errors when quickly toggling camera. ## 0.10.3 🐞 Fixed -* Handled SFU stats reporting failures gracefully + +- Handled SFU stats reporting failures gracefully βœ… Added -* Added option to configure android audio configuration when initializing `StreamVideo` instance by providing `androidAudioConfiguration` to `StreamVideoOptions`. + +- Added option to configure android audio configuration when initializing `StreamVideo` instance by providing `androidAudioConfiguration` to `StreamVideoOptions`. ## 0.10.2 βœ… Added -* Added support for setting video filters before the video track is created by listening for local participant state changes and applying the filters once the video is enabled. -* Added support for setting video filters on a specific video track before the local participant is available β€” useful for scenarios like lobby previews with a temporary video track. -* Introduced the `reconnectTimeout` option in `CallPreferences`, allowing you to set the maximum duration the SDK will attempt to reconnect to a call before giving up. + +- Added support for setting video filters before the video track is created by listening for local participant state changes and applying the filters once the video is enabled. +- Added support for setting video filters on a specific video track before the local participant is available β€” useful for scenarios like lobby previews with a temporary video track. +- Introduced the `reconnectTimeout` option in `CallPreferences`, allowing you to set the maximum duration the SDK will attempt to reconnect to a call before giving up. πŸ”„ Changed -* Deprecated `callRejoinTimeout` in `RetryConfig`, instead added `networkAvailabilityTimeout` to `CallPreferences` to control how long the SDK waits for network connectivity to be restored during reconnection attempts before timing out. + +- Deprecated `callRejoinTimeout` in `RetryConfig`, instead added `networkAvailabilityTimeout` to `CallPreferences` to control how long the SDK waits for network connectivity to be restored during reconnection attempts before timing out. πŸ”„ Dependency updates -* Updated `flutter_callkit_incoming` dependency to version 2.5.7. That version contains Android 14 compatibility fixes for ringing notifications and lock screen handling. + +- Updated `flutter_callkit_incoming` dependency to version 2.5.7. That version contains Android 14 compatibility fixes for ringing notifications and lock screen handling. 🐞 Fixed -* (Android) CircleTransform Argument type mismatch on Bitmap.Config? -* Sorting of participants after screen sharing stopped. -* Fixed an issue where video filters were cleared after toggling the camera. -* (Windows) Fixed `DtlsSrtpKeyAgreement` audio constraint parameter mapping + +- (Android) CircleTransform Argument type mismatch on Bitmap.Config? +- Sorting of participants after screen sharing stopped. +- Fixed an issue where video filters were cleared after toggling the camera. +- (Windows) Fixed `DtlsSrtpKeyAgreement` audio constraint parameter mapping ## 0.10.1 🐞 Fixed -* (iOS) Fixed Picture-in-Picture (PiP) issue where remote participants joining during active PiP mode would not have their video tracks displayed properly. -* (iOS) Fixed a visual issue where the Picture-in-Picture view displayed an empty container when participant name and microphone indicator settings were disabled. -* Fixed an issue where the last reaction was removed too fast when a user sends multiple reactions quickly after each other. -* Fixed an issue where toggling camera enabled quickly could cause AVCaptureMultiCamSession to crash. -* Fixed an issue where the default camera selection would occasionally be incorrect even when properly configured. -* Fixed an issue where changing the audio input device while muted from the start of a call would not apply the new device when unmuting. The selected device will now be correctly set upon unmuting. + +- (iOS) Fixed Picture-in-Picture (PiP) issue where remote participants joining during active PiP mode would not have their video tracks displayed properly. +- (iOS) Fixed a visual issue where the Picture-in-Picture view displayed an empty container when participant name and microphone indicator settings were disabled. +- Fixed an issue where the last reaction was removed too fast when a user sends multiple reactions quickly after each other. +- Fixed an issue where toggling camera enabled quickly could cause AVCaptureMultiCamSession to crash. +- Fixed an issue where the default camera selection would occasionally be incorrect even when properly configured. +- Fixed an issue where changing the audio input device while muted from the start of a call would not apply the new device when unmuting. The selected device will now be correctly set upon unmuting. βœ… Added -* Added support for customization of display name for ringing notifications by providing `display_name` custom data to the call. See the [documentation](https://getstream.io/video/docs/flutter/advanced/incoming-calls/customization/#display-name-customization) for details. + +- Added support for customization of display name for ringing notifications by providing `display_name` custom data to the call. See the [documentation](https://getstream.io/video/docs/flutter/advanced/incoming-calls/customization/#display-name-customization) for details. ## 0.10.0 🚧 (Android) Picture-in-Picture (PiP) Improvements - Breaking Change -* **Simplified Setup:** Introduced `StreamFlutterActivity` - extend it instead of `FlutterActivity` for automatic PiP support. -* **Automatic Activation:** PiP now triggers automatically when users press home button or background the app during calls. -* **Fixed Overlay Issues:** PiP view can no longer be overlapped by other widgets and will always display the correct video layout. -* **Migration Required:** In your `MainActivity`, remove the manual `onUserLeaveHint()` implementation and extend the MainActivity with `StreamFlutterActivity`. Previously required manually calling `PictureInPictureHelper.enterPictureInPictureIfInCall(this)` - now handled automatically. -* **Removed Deprecated Methods:** Removed the deprecated `setPictureInPictureEnabled` method from `StreamVideoFlutterPlatform`, `StreamVideoFlutterBackground`, and `MethodChannelStreamVideoFlutter` classes, and the deprecated `enterPictureInPictureIfInCall` method from `PictureInPictureHelper` (Android). PiP is now handled automatically by `StreamPictureInPictureAndroidView`. + +- **Simplified Setup:** Introduced `StreamFlutterActivity` - extend it instead of `FlutterActivity` for automatic PiP support. +- **Automatic Activation:** PiP now triggers automatically when users press home button or background the app during calls. +- **Fixed Overlay Issues:** PiP view can no longer be overlapped by other widgets and will always display the correct video layout. +- **Migration Required:** In your `MainActivity`, remove the manual `onUserLeaveHint()` implementation and extend the MainActivity with `StreamFlutterActivity`. Previously required manually calling `PictureInPictureHelper.enterPictureInPictureIfInCall(this)` - now handled automatically. +- **Removed Deprecated Methods:** Removed the deprecated `setPictureInPictureEnabled` method from `StreamVideoFlutterPlatform`, `StreamVideoFlutterBackground`, and `MethodChannelStreamVideoFlutter` classes, and the deprecated `enterPictureInPictureIfInCall` method from `PictureInPictureHelper` (Android). PiP is now handled automatically by `StreamPictureInPictureAndroidView`. πŸ”„ Partial State Updates: For a more detailed explanation check [the dedicated documentation](https://github.com/GetStream/stream-video-flutter/blob/main/packages/stream_video_flutter/docs/partial_state_update_changes.md). -* Added `call.partialState` for more specific and efficient state updates. -* Added callbacks in `StreamCallContainer`, `StreamCallContent`, `StreamIncomingCallContent`, and others that no longer return a state. -By (only) using these callbacks the root widgets will use more efficient partial state updates. -* Added `PartialCallStateBuilder` to help with making widgets that depend on `partialState`. -* Deprecated old callbacks + +- Added `call.partialState` for more specific and efficient state updates. +- Added callbacks in `StreamCallContainer`, `StreamCallContent`, `StreamIncomingCallContent`, and others that no longer return a state. + By (only) using these callbacks the root widgets will use more efficient partial state updates. +- Added `PartialCallStateBuilder` to help with making widgets that depend on `partialState`. +- Deprecated old callbacks βœ… Added -* Added `setMirrorVideo` method to `Call` class to control video mirroring for participants. -* Added `maxParticipantsExcludeOwner` and `maxParticipantsExcludeRoles` to Call limits settings, providing finer control over participant limits by allowing exclusion of call owners and specific roles from the maximum count. + +- Added `setMirrorVideo` method to `Call` class to control video mirroring for participants. +- Added `maxParticipantsExcludeOwner` and `maxParticipantsExcludeRoles` to Call limits settings, providing finer control over participant limits by allowing exclusion of call owners and specific roles from the maximum count. 🐞 Fixed -* Improved SFU error handling in Call flow and disconnect reason handling. The disconnected call state now accurately reflects the original cause of disconnection. -* Fixed an issue where rejecting a ringing call on one device would incorrectly end the call for all already connected participants. -* Enhanced fast reconnect mechanism with improved PeerConnection issue detection and recovery. The system now attempts multiple fast reconnects before falling back to a full call rejoin. -* Fixed simulcast video quality by correcting resolution calculations and layer selection for optimal video track display. -* Fixed an edge case where a call with the same CID as an incoming call is also an outgoing call to ensure the same Call instance is used. + +- Improved SFU error handling in Call flow and disconnect reason handling. The disconnected call state now accurately reflects the original cause of disconnection. +- Fixed an issue where rejecting a ringing call on one device would incorrectly end the call for all already connected participants. +- Enhanced fast reconnect mechanism with improved PeerConnection issue detection and recovery. The system now attempts multiple fast reconnects before falling back to a full call rejoin. +- Fixed simulcast video quality by correcting resolution calculations and layer selection for optimal video track display. +- Fixed an edge case where a call with the same CID as an incoming call is also an outgoing call to ensure the same Call instance is used. ## 0.9.6 βœ… Added -* Added `handleCallInterruptionCallbacks` method to `RtcMediaDeviceNotifier` that provides an option to handle system audio interruption like incoming calls, or other media playing. See the [documentation](https://getstream.io/video/docs/flutter/advanced/handling-system-audio-interruptions/) for details. -* Improved the Picture-in-Picture (PiP) implementation for video calls - * (iOS) Shows participant avatar instead of black screen when video track is disabled. - * (iOS) Added overlay with participant name, microphone indicator and connection qualit indicator. - * (iOS/Android) Added `sort` in `PictureInPictureConfiguration` that enables customization of PiP participant selection. + +- Added `handleCallInterruptionCallbacks` method to `RtcMediaDeviceNotifier` that provides an option to handle system audio interruption like incoming calls, or other media playing. See the [documentation](https://getstream.io/video/docs/flutter/advanced/handling-system-audio-interruptions/) for details. +- Improved the Picture-in-Picture (PiP) implementation for video calls + - (iOS) Shows participant avatar instead of black screen when video track is disabled. + - (iOS) Added overlay with participant name, microphone indicator and connection qualit indicator. + - (iOS/Android) Added `sort` in `PictureInPictureConfiguration` that enables customization of PiP participant selection. 🐞 Fixed -* Fixed the handling of user blocking event to disconnect the blocked user with a proper reason. + +- Fixed the handling of user blocking event to disconnect the blocked user with a proper reason. ## 0.9.5 βœ… Added -* Introduced `extendBody` parameter in `StreamCallContent` that extends the participants view to the bottom edge of the scaffold when enabled. -* Introduced `allowMultipleActiveCalls` option in `StreamVideoOptions` enabling support for concurrent active calls. See the [documentation](https://getstream.io/video/docs/flutter/advanced/multiple-simultaneous-calls-support/) for details. + +- Introduced `extendBody` parameter in `StreamCallContent` that extends the participants view to the bottom edge of the scaffold when enabled. +- Introduced `allowMultipleActiveCalls` option in `StreamVideoOptions` enabling support for concurrent active calls. See the [documentation](https://getstream.io/video/docs/flutter/advanced/multiple-simultaneous-calls-support/) for details. 🐞 Fixed -* Enhanced permission update handling to only process events targeting the current user. -* Improved audio output device selection to prioritize external audio devices during call connection. + +- Enhanced permission update handling to only process events targeting the current user. +- Improved audio output device selection to prioritize external audio devices during call connection. ## 0.9.4 🐞 Fixed -* Resolved an issue where the screen share track would disappear when zoomed in. -* Fixed screen sharing layout issues on wide screens. -* Fixed `ScreenShareCallParticipantsContent` with Spotlight view on very wide windows. + +- Resolved an issue where the screen share track would disappear when zoomed in. +- Fixed screen sharing layout issues on wide screens. +- Fixed `ScreenShareCallParticipantsContent` with Spotlight view on very wide windows. βœ… Added -* Introduced new builder parameters to `LivestreamPlayer` for enhanced customization: - - `videoRendererBuilder`: Build a custom video renderer. - - `videoPlaceholderBuilder`: Build a placeholder for the video renderer. - - `livestreamHostsUnavailableBuilder`: Customize the UI when a livestream is connected but no hosts have video enabled. - - `livestreamNotConnectedBuilder`: Customize the UI when the livestream is not connected. + +- Introduced new builder parameters to `LivestreamPlayer` for enhanced customization: + - `videoRendererBuilder`: Build a custom video renderer. + - `videoPlaceholderBuilder`: Build a placeholder for the video renderer. + - `livestreamHostsUnavailableBuilder`: Customize the UI when a livestream is connected but no hosts have video enabled. + - `livestreamNotConnectedBuilder`: Customize the UI when the livestream is not connected. ## 0.9.3 βœ… Added -* Introduced `callDurationStream` to the `Call` class. A `Stream` that emits the current call duration. -* Added `createdByUser` property to the `CallState` for better tracking of the initiating user. -* Added `livestreamControlsBuilder` parameter to `LivestreamPlayer` allowing customisation of controls panel. + +- Introduced `callDurationStream` to the `Call` class. A `Stream` that emits the current call duration. +- Added `createdByUser` property to the `CallState` for better tracking of the initiating user. +- Added `livestreamControlsBuilder` parameter to `LivestreamPlayer` allowing customisation of controls panel. 🐞 Fixed -* Resolved an issue where participants’ tracks would briefly disappear ("blink") or change location when many participants are in the call. -* Fixed a bug where subsequent screen sharing sessions did not end properly when terminated via the browser UI. + +- Resolved an issue where participants’ tracks would briefly disappear ("blink") or change location when many participants are in the call. +- Fixed a bug where subsequent screen sharing sessions did not end properly when terminated via the browser UI. ## 0.9.2 🐞 Fixed -* Fixed issue with the user feedback collection endpoint. + +- Fixed issue with the user feedback collection endpoint. βœ… Added -* Added `ring`, `audio`, `video`, `screenshare`, `session` and `frameRecordings` settings to `Call.getOrCreate()` method. -* Added `members` list parameter to `Call.getOrCreate()` method to allow assigning roles when creating a call. -* Added `session` and `frameRecordings` settings to `Call.update()` method. + +- Added `ring`, `audio`, `video`, `screenshare`, `session` and `frameRecordings` settings to `Call.getOrCreate()` method. +- Added `members` list parameter to `Call.getOrCreate()` method to allow assigning roles when creating a call. +- Added `session` and `frameRecordings` settings to `Call.update()` method. πŸ”„ Updated -* Updated `LivestreamPlayer` widget with a refreshed look and feel. Added `livestreamEndedBuilder` and `livestreamBackstageBuilder` for enhanced configuration options. + +- Updated `LivestreamPlayer` widget with a refreshed look and feel. Added `livestreamEndedBuilder` and `livestreamBackstageBuilder` for enhanced configuration options. ## 0.9.1 βœ… Added -* Introduced camera focus and zoom control features: - * New `Call.setZoom()` method to adjust the camera’s zoom level. - * New `Call.focus()` method for setting focus and exposure points on the camera. + +- Introduced camera focus and zoom control features: + - New `Call.setZoom()` method to adjust the camera’s zoom level. + - New `Call.focus()` method for setting focus and exposure points on the camera. 🐞 Fixed -* [Android] Fixes the device orientation detection when screen-sharing on some Android devices. -* Addressed minor bugs and improved performance. + +- [Android] Fixes the device orientation detection when screen-sharing on some Android devices. +- Addressed minor bugs and improved performance. ## 0.9.0 βœ… Added -* Introducing noise cancellation support to enhance call audio quality. Implement this feature easily by following our [documentation](https://getstream.io/video/docs/flutter/guides/noise-cancellation/). -* Added `networkMonitorSettings` to `StreamVideoOptions` for configuring network monitoring, including customization of test URLs for connection checks. + +- Introducing noise cancellation support to enhance call audio quality. Implement this feature easily by following our [documentation](https://getstream.io/video/docs/flutter/guides/noise-cancellation/). +- Added `networkMonitorSettings` to `StreamVideoOptions` for configuring network monitoring, including customization of test URLs for connection checks. 🚧 (Breaking Changes) -* Enhanced the `onCallDisconnected` callback in `StreamCallContainer` to include a `CallDisconnectedProperties` parameter with detailed disconnection reason information. -* Improved `setScreenShareEnabled` method in `CallSession` class to return the screen sharing track. -* Relocated `callPreferences` property from `CallStateNotifier` to `CallState` for better state management. -* Increased minimum platform requirements - * **Android:** Minimum SDK 21 (Android 5.0 Lollipop) - * **iOS:** iOS 14.0 or higher + +- Enhanced the `onCallDisconnected` callback in `StreamCallContainer` to include a `CallDisconnectedProperties` parameter with detailed disconnection reason information. +- Improved `setScreenShareEnabled` method in `CallSession` class to return the screen sharing track. +- Relocated `callPreferences` property from `CallStateNotifier` to `CallState` for better state management. +- Increased minimum platform requirements + - **Android:** Minimum SDK 21 (Android 5.0 Lollipop) + - **iOS:** iOS 14.0 or higher 🐞 Fixed -* Enhanced fast reconnect flow for more reliable connection recovery during network interruptions. -* Resolved an issue where video tracks weren't properly subscribed when participants joined calls. -* Fixed multi-device support to properly handle when the same user joins from multiple devices. -* Corrected screen sharing source switching when changing between multiple sources. -* Fixed a bug where `CallPreferences` could be ignored when accepting a ringing call. -* (Android) Resolved compatibility issues with `battery_plus` plugin on older Android devices. -* (Web) Fixed screen sharing termination when using browser UI controls to stop sharing. -* (iOS) Synchronized CallKit microphone mute state with the actual call mute state. + +- Enhanced fast reconnect flow for more reliable connection recovery during network interruptions. +- Resolved an issue where video tracks weren't properly subscribed when participants joined calls. +- Fixed multi-device support to properly handle when the same user joins from multiple devices. +- Corrected screen sharing source switching when changing between multiple sources. +- Fixed a bug where `CallPreferences` could be ignored when accepting a ringing call. +- (Android) Resolved compatibility issues with `battery_plus` plugin on older Android devices. +- (Web) Fixed screen sharing termination when using browser UI controls to stop sharing. +- (iOS) Synchronized CallKit microphone mute state with the actual call mute state. ## 0.8.4 🐞 Fixed -* (iOS) Fixed an issue where Picture-in-Picture (PiP) would not stop when bringing the app back to the foreground. + +- (iOS) Fixed an issue where Picture-in-Picture (PiP) would not stop when bringing the app back to the foreground. πŸ”„ Changed -* Updated the `device_info_plus` dependency to support a wider range of versions and resolve potential conflicts. -* Deprecated the `setParticipantPinned()` method in the `Call` class β€” use `setParticipantPinnedLocally()` instead. -* Replaced the `isPinned` parameter in `CallParticipantState` with a `pin` object, which now differentiates between local and remote pinning. + +- Updated the `device_info_plus` dependency to support a wider range of versions and resolve potential conflicts. +- Deprecated the `setParticipantPinned()` method in the `Call` class β€” use `setParticipantPinnedLocally()` instead. +- Replaced the `isPinned` parameter in `CallParticipantState` with a `pin` object, which now differentiates between local and remote pinning. βœ… Added -* Introduced a `membersLimit` parameter in the `getOrCreate()` and `join()` methods of the `Call` class to limit the number of members included in the response. -* Added `setParticipantPinnedForEveryone()`, allowing users with the required permissions to pin participants for all. The `setParticipantPinned()` method has been replaced with `setParticipantPinnedLocally()`, which, as before, only pins participants locally. + +- Introduced a `membersLimit` parameter in the `getOrCreate()` and `join()` methods of the `Call` class to limit the number of members included in the response. +- Added `setParticipantPinnedForEveryone()`, allowing users with the required permissions to pin participants for all. The `setParticipantPinned()` method has been replaced with `setParticipantPinnedLocally()`, which, as before, only pins participants locally. πŸ”„ Changed -* Update stream_webrtc_flutter and device_info_plus dependencies + +- Update stream_webrtc_flutter and device_info_plus dependencies ## 0.8.3 βœ… Added -* Introduced `CallParticipantState.audioLevels`, which stores the last 10 audio levels of a participant. -* Added `CallState.activeSpeakers` to retrieve a list of currently active speakers. -* Enhanced `observeCoreCallKitEvents()` in `StreamVideo` with a new `CallPreferences? preferences` parameter, allowing for configuration of the accepted call. -* Implemented localization support for the SDK's UI components. See the [documentation](https://getstream.io/video/docs/flutter/localization/) for details. -* Added the ability to customize the screen share selector on desktop devices. See the [updated documentation](https://getstream.io/video/docs/flutter/advanced/screen_sharing/) for details. + +- Introduced `CallParticipantState.audioLevels`, which stores the last 10 audio levels of a participant. +- Added `CallState.activeSpeakers` to retrieve a list of currently active speakers. +- Enhanced `observeCoreCallKitEvents()` in `StreamVideo` with a new `CallPreferences? preferences` parameter, allowing for configuration of the accepted call. +- Implemented localization support for the SDK's UI components. See the [documentation](https://getstream.io/video/docs/flutter/localization/) for details. +- Added the ability to customize the screen share selector on desktop devices. See the [updated documentation](https://getstream.io/video/docs/flutter/advanced/screen_sharing/) for details. 🐞 Fixed -* Resolved various issues related to screen sharing on desktop devices. + +- Resolved various issues related to screen sharing on desktop devices. ## 0.8.2 -βœ… Added -* Added `CallPreferences? preferences` parameter to `consumeIncomingCall()` method in `StreamVideo` to make it possible to configure the consumed call. +βœ… Added + +- Added `CallPreferences? preferences` parameter to `consumeIncomingCall()` method in `StreamVideo` to make it possible to configure the consumed call. 🐞 Fixed -* Fixed remote participant roles array being empty after joining the call. -* Fixed and issue with `thermal` package throwing exception on Android 9 and lower. + +- Fixed remote participant roles array being empty after joining the call. +- Fixed and issue with `thermal` package throwing exception on Android 9 and lower. ## 0.8.1 -βœ… Added -* Introduced the `onCallDisconnected` callback in `StreamCallContainer`, enabling customization of the default behavior, which invokes `Navigator.pop` upon call disconnection. -* Made `registerDevice()` and `unregisterDevice()` methods publicly available in `PushNotificationManager`. +βœ… Added + +- Introduced the `onCallDisconnected` callback in `StreamCallContainer`, enabling customization of the default behavior, which invokes `Navigator.pop` upon call disconnection. +- Made `registerDevice()` and `unregisterDevice()` methods publicly available in `PushNotificationManager`. ## 0.8.0 -* Updated minimum Flutter version to 3.27.4 - * Note: If you updated Flutter version and are using `flutterfire_cli` for push notifications you might need to reactivate it by running: `dart pub global activate flutterfire_cli`. +- Updated minimum Flutter version to 3.27.4 + - Note: If you updated Flutter version and are using `flutterfire_cli` for push notifications you might need to reactivate it by running: `dart pub global activate flutterfire_cli`. βœ… Added -* Introduced `disposeAfterResolvingRinging()` and `consumeAndAcceptActiveCall()` methods in `StreamVideo` to simplify the ringing flow implementation. - - Refer to the updated [Incoming Call Documentation](https://getstream.io/video/docs/flutter/advanced/incoming-calls/overview/) or the [Ringing Tutorial](https://getstream.io/video/sdk/flutter/tutorial/ringing/) for more details. + +- Introduced `disposeAfterResolvingRinging()` and `consumeAndAcceptActiveCall()` methods in `StreamVideo` to simplify the ringing flow implementation. + - Refer to the updated [Incoming Call Documentation](https://getstream.io/video/docs/flutter/advanced/incoming-calls/overview/) or the [Ringing Tutorial](https://getstream.io/video/sdk/flutter/tutorial/ringing/) for more details. πŸ”„ Changed -* Deprecated the `backgroundVoipCallHandler` parameter in `StreamVideoPushNotificationManager`, as it is no longer required for iOS ringing to function in a terminated state. + +- Deprecated the `backgroundVoipCallHandler` parameter in `StreamVideoPushNotificationManager`, as it is no longer required for iOS ringing to function in a terminated state. 🐞 Fixed -* Center alignment of buttons in `StreamLobbyVideo` to support more screen sizes. -* **(Windows/Linux)** Fixes compilation issues caused by `stream_webrtc_flutter` package. + +- Center alignment of buttons in `StreamLobbyVideo` to support more screen sizes. +- **(Windows/Linux)** Fixes compilation issues caused by `stream_webrtc_flutter` package. 🚧 (Breaking) Picture-in-Picture (PiP) Improvements & Fixes -* **Fixed:** PiP not working on Android 15. -* **Fixed:** PiP not displaying other participants' screen sharing. -* **Added support for iOS 18 Multitasking Camera Access changes.** From **iOS 18**, you can easily enable camera usage while the app is in the background (e.g., for PiP). Refer to [Picture in Picture documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) for details. -* Added `disablePictureInPictureWhenScreenSharing` configuration option to `PictureInPictureConfiguration`. When **true** (default), PiP is disabled if the local device is screen sharing. -* ❗ Breaking Change: `ignoreLocalParticipantVideo` parameter in `IOSPictureInPictureConfiguration` is replaced by `includeLocalParticipantVideo`. By default, local video **is enabled** and will appear in PiP mode if the iOS device supports **Multitasking Camera Access**. -* ❗ Breaking Change: `ignoreLocalParticipantVideo` parameter in `StreamPictureInPictureUiKitView` is also replaced by `includeLocalParticipantVideo`. + +- **Fixed:** PiP not working on Android 15. +- **Fixed:** PiP not displaying other participants' screen sharing. +- **Added support for iOS 18 Multitasking Camera Access changes.** From **iOS 18**, you can easily enable camera usage while the app is in the background (e.g., for PiP). Refer to [Picture in Picture documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) for details. +- Added `disablePictureInPictureWhenScreenSharing` configuration option to `PictureInPictureConfiguration`. When **true** (default), PiP is disabled if the local device is screen sharing. +- ❗ Breaking Change: `ignoreLocalParticipantVideo` parameter in `IOSPictureInPictureConfiguration` is replaced by `includeLocalParticipantVideo`. By default, local video **is enabled** and will appear in PiP mode if the iOS device supports **Multitasking Camera Access**. +- ❗ Breaking Change: `ignoreLocalParticipantVideo` parameter in `StreamPictureInPictureUiKitView` is also replaced by `includeLocalParticipantVideo`. ## 0.7.2 🐞 Fixed -* Resolved an issue where accepting a second call while already on a call would not open the call screen correctly. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) and [#834](https://github.com/GetStream/stream-video-flutter/pull/834) -* **(Web)** Fixed web compilation issues. [#832](https://github.com/GetStream/stream-video-flutter/pull/832) -* **(Web)** Addressed an issue where `battery_plus` and `thermal` packages were erroneously called on web. [#837](https://github.com/GetStream/stream-video-flutter/pull/837) -* **(iOS)** Fixed an issue where Picture-in-Picture mode was not ended when the call ended. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) -* **(iOS)** Resolved an issue where CallKit calls sometimes were not terminated when the Stream call ended. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) -* **(iOS)** Fixed a missing app icon on the CallKit screen when the app was in a terminated state. [#841](https://github.com/GetStream/stream-video-flutter/pull/841) + +- Resolved an issue where accepting a second call while already on a call would not open the call screen correctly. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) and [#834](https://github.com/GetStream/stream-video-flutter/pull/834) +- **(Web)** Fixed web compilation issues. [#832](https://github.com/GetStream/stream-video-flutter/pull/832) +- **(Web)** Addressed an issue where `battery_plus` and `thermal` packages were erroneously called on web. [#837](https://github.com/GetStream/stream-video-flutter/pull/837) +- **(iOS)** Fixed an issue where Picture-in-Picture mode was not ended when the call ended. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) +- **(iOS)** Resolved an issue where CallKit calls sometimes were not terminated when the Stream call ended. [#840](https://github.com/GetStream/stream-video-flutter/pull/840) +- **(iOS)** Fixed a missing app icon on the CallKit screen when the app was in a terminated state. [#841](https://github.com/GetStream/stream-video-flutter/pull/841) πŸ”„ Changed -* Deprecated the `handleVoipPushNotification()` method in the `StreamVideo` class. Use `handleRingingFlowNotifications()` instead. + +- Deprecated the `handleVoipPushNotification()` method in the `StreamVideo` class. Use `handleRingingFlowNotifications()` instead. ## 0.7.1 🐞 Fixed -* Resolved an issue where media tracks were not being disabled or enabled correctly. [#828](https://github.com/GetStream/stream-video-flutter/pull/828) -* Fixed a problem causing anonymous users to fail when connecting and joining calls. [#827](https://github.com/GetStream/stream-video-flutter/pull/827) + +- Resolved an issue where media tracks were not being disabled or enabled correctly. [#828](https://github.com/GetStream/stream-video-flutter/pull/828) +- Fixed a problem causing anonymous users to fail when connecting and joining calls. [#827](https://github.com/GetStream/stream-video-flutter/pull/827) ## 0.7.0 🚧 Breaking changes -* The package is now compatible with Gradle 8. The minimum required Java version is now 17. [#820](https://github.com/GetStream/stream-video-flutter/pull/820) -* Updated the `flutter_callkit_incoming` package to version 2.5.0, which also requires Java 17. [#820](https://github.com/GetStream/stream-video-flutter/pull/820) -* The `resolution` parameter of `Call.setPreferredIncomingVideoResolution()` method changed type from `VideoResolution` to `VideoDimension`. -* The `Call.onPermissionRequest` callback changed the event type passed as an argument from `CoordinatorCallPermissionRequestEvent` to `StreamCallPermissionRequestEvent` + +- The package is now compatible with Gradle 8. The minimum required Java version is now 17. [#820](https://github.com/GetStream/stream-video-flutter/pull/820) +- Updated the `flutter_callkit_incoming` package to version 2.5.0, which also requires Java 17. [#820](https://github.com/GetStream/stream-video-flutter/pull/820) +- The `resolution` parameter of `Call.setPreferredIncomingVideoResolution()` method changed type from `VideoResolution` to `VideoDimension`. +- The `Call.onPermissionRequest` callback changed the event type passed as an argument from `CoordinatorCallPermissionRequestEvent` to `StreamCallPermissionRequestEvent` βœ… Added -* Added out-of-the-box support for blur background filters and image filters. As well as the option to create custom video filters. For complete documentation of those features please check [here.](https://getstream.io/video/docs/flutter/advanced/apply-video-filters/) [#799](https://github.com/GetStream/stream-video-flutter/pull/799) -* Added support for Closed Captions. [#796](https://github.com/GetStream/stream-video-flutter/pull/796) - * Listen to the `Call.closedCaptions` stream to overlay captions during your call. - * Use `CallPreferences` to configure: - * `closedCaptionsVisibilityDurationMs` for controlling how long captions are displayed. - * `closedCaptionsVisibleCaptions` for managing the number of captions in the display queue. - * Easily enable or disable captions with the `ToggleClosedCaptionsOption` widget. - * Learn More: - * Check the [guide](https://getstream.io/video/docs/flutter/closed-captions/) for integration steps. - * Explore the [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/closed-captions/) for UI tips. -* Dynamic codec negotiation during calls. [#811](https://github.com/GetStream/stream-video-flutter/pull/811) + +- Added out-of-the-box support for blur background filters and image filters. As well as the option to create custom video filters. For complete documentation of those features please check [here.](https://getstream.io/video/docs/flutter/advanced/apply-video-filters/) [#799](https://github.com/GetStream/stream-video-flutter/pull/799) +- Added support for Closed Captions. [#796](https://github.com/GetStream/stream-video-flutter/pull/796) + - Listen to the `Call.closedCaptions` stream to overlay captions during your call. + - Use `CallPreferences` to configure: + - `closedCaptionsVisibilityDurationMs` for controlling how long captions are displayed. + - `closedCaptionsVisibleCaptions` for managing the number of captions in the display queue. + - Easily enable or disable captions with the `ToggleClosedCaptionsOption` widget. + - Learn More: + - Check the [guide](https://getstream.io/video/docs/flutter/closed-captions/) for integration steps. + - Explore the [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/closed-captions/) for UI tips. +- Dynamic codec negotiation during calls. [#811](https://github.com/GetStream/stream-video-flutter/pull/811) 🐞 Fixed -* Fixed issues when ending the call while in Picture in Picture mode on Android. [#822](https://github.com/GetStream/stream-video-flutter/pull/822) -* Fixes rejecting ringing call when CallEnd, instead of CallDecline, event is triggered by CallKit during ringing. [#824](https://github.com/GetStream/stream-video-flutter/pull/824) + +- Fixed issues when ending the call while in Picture in Picture mode on Android. [#822](https://github.com/GetStream/stream-video-flutter/pull/822) +- Fixes rejecting ringing call when CallEnd, instead of CallDecline, event is triggered by CallKit during ringing. [#824](https://github.com/GetStream/stream-video-flutter/pull/824) ## 0.6.1 -* Updated minimum Flutter version to 3.24.5 +- Updated minimum Flutter version to 3.24.5 βœ… Added -* Added the `call.collectUserFeedback()` method which allows users to send call quality rating. These ratings are visible on the Dashboard and are aggregated in call stats for easy tracking. For a sample implementation, please refer to the [documentation](https://getstream.io/video/docs/flutter/user-rating/). -* Added device thermal status reporting to better optimize call quality. -* Added the `StreamVideoPushNotificationManager.ensureFullScreenIntentPermission()` method. This resolves an issue on some Android 14 devices where full-screen notifications would not appear due to missing permissions. -You can now invoke this method to show a settings screen, allowing users to enable the required permission if it's not already enabled. + +- Added the `call.collectUserFeedback()` method which allows users to send call quality rating. These ratings are visible on the Dashboard and are aggregated in call stats for easy tracking. For a sample implementation, please refer to the [documentation](https://getstream.io/video/docs/flutter/user-rating/). +- Added device thermal status reporting to better optimize call quality. +- Added the `StreamVideoPushNotificationManager.ensureFullScreenIntentPermission()` method. This resolves an issue on some Android 14 devices where full-screen notifications would not appear due to missing permissions. + You can now invoke this method to show a settings screen, allowing users to enable the required permission if it's not already enabled. 🐞 Fixed -* Resolved an issue where CallKit calls would not connect when accepted while the screen was locked. -* Fixed a bug where the Android foreground service would not stop when the app was killed, keeping the call connection active. + +- Resolved an issue where CallKit calls would not connect when accepted while the screen was locked. +- Fixed a bug where the Android foreground service would not stop when the app was killed, keeping the call connection active. ## 0.6.0 This release introduces a major rework of the join/reconnect flow in the Call class to support Reconnect V2, enhancing reconnection handling across various scenarios. Most updates are within the internals of the Call class, though some changes are outward-facing, including a few breaking changes. πŸ”„ Changed -* `Call.reject()` method will now always call `Call.leave()` method internally. + +- `Call.reject()` method will now always call `Call.leave()` method internally. 🚧 Breaking changes -* Removed the deprecated `Call.joinLobby()` method. -* The `maxDuration` and `maxParticipants` parameters of `Call.getOrCreate()` are now combined into the `StreamLimitsSettings? limits` parameter. + +- Removed the deprecated `Call.joinLobby()` method. +- The `maxDuration` and `maxParticipants` parameters of `Call.getOrCreate()` are now combined into the `StreamLimitsSettings? limits` parameter. πŸ”„ Dependency updates -* Updated Firebase dependencies to resolve Xcode 16 build issues. + +- Updated Firebase dependencies to resolve Xcode 16 build issues. βœ… Added -* Added the `registerPushDevice` optional parameter (default is `true`) to the `StreamVideo.connect()` method,allowing the prevention of automatic push token registration. -* Added `participantCount` and `anonymousParticipantCount` to `CallState` reflecting the current number of participants in the call. -* Introduced the `watch` parameter to `Call.get()` and `Call.getOrCreate()` methods (default is `true`). When set to `true`, this enables the `Call` to listen for coordinator events and update its state accordingly, even before the call is joined (`Call.join()`). -* Added support for `targetResolution` setting set on the Dashboard to determine the max resolution the video stream. -* Introduced new API methods to give greater control over incoming video quality. `Call.setPreferredIncomingVideoResolution()` allows you to manually set a preferred video resolution, while `Call.setIncomingVideoEnabled()` enables or disables incoming video. For more details, refer to the [documentation](https://getstream.io/video/docs/flutter/manual-video-quality-selection/). + +- Added the `registerPushDevice` optional parameter (default is `true`) to the `StreamVideo.connect()` method,allowing the prevention of automatic push token registration. +- Added `participantCount` and `anonymousParticipantCount` to `CallState` reflecting the current number of participants in the call. +- Introduced the `watch` parameter to `Call.get()` and `Call.getOrCreate()` methods (default is `true`). When set to `true`, this enables the `Call` to listen for coordinator events and update its state accordingly, even before the call is joined (`Call.join()`). +- Added support for `targetResolution` setting set on the Dashboard to determine the max resolution the video stream. +- Introduced new API methods to give greater control over incoming video quality. `Call.setPreferredIncomingVideoResolution()` allows you to manually set a preferred video resolution, while `Call.setIncomingVideoEnabled()` enables or disables incoming video. For more details, refer to the [documentation](https://getstream.io/video/docs/flutter/manual-video-quality-selection/). 🐞 Fixed -* Automatic push token registration by `StreamVideo` now stores registered token in `SharedPreferences`, performing an API call only when the token changes. -* Fixed premature ringing termination issues. -* Resolved issues where ringing would not end when the caller terminates the call in an app-terminated state. -* Fixed issue with call not ending in some cases when only one participant is left and `dropIfAloneInRingingFlow` is set to `true`. + +- Automatic push token registration by `StreamVideo` now stores registered token in `SharedPreferences`, performing an API call only when the token changes. +- Fixed premature ringing termination issues. +- Resolved issues where ringing would not end when the caller terminates the call in an app-terminated state. +- Fixed issue with call not ending in some cases when only one participant is left and `dropIfAloneInRingingFlow` is set to `true`. ## 0.5.5 🐞 Fixed -* Migrated from `internet_connection_checker` to `internet_connection_checker_plus` due to [license issues](https://github.com/github/dmca/blob/master/2024/09/2024-09-04-internet-connection-checker-plus.md). -* `callAppBarBuilder` in `StreamCallContent` can now return null in order to hide the app bar. -* `backgroundColor` field in `StreamCallControls` is now correctly applied. + +- Migrated from `internet_connection_checker` to `internet_connection_checker_plus` due to [license issues](https://github.com/github/dmca/blob/master/2024/09/2024-09-04-internet-connection-checker-plus.md). +- `callAppBarBuilder` in `StreamCallContent` can now return null in order to hide the app bar. +- `backgroundColor` field in `StreamCallControls` is now correctly applied. ## 0.5.4 🐞 Fixed -* Fixed an issue where active call foreground service was recreated after being stopped when ringing call was declined and in-app incoming screen was displayed. + +- Fixed an issue where active call foreground service was recreated after being stopped when ringing call was declined and in-app incoming screen was displayed. 🚧 Breaking changes -* The regular push notification handling has been removed from iOS, providing more control over the implementation. VoIP push notifications will continue to be handled as before. For more details, refer to the [documentation](https://getstream.io/video/docs/flutter/push-notifications/). - -* Dependency updates - * **Flutter SDK** constraint updated to >=3.22.0 (**Dart SDK** to >=3.4.0 <4.0.0) - * **internet_connection_checker** updated from ^1.0.0+1 to ^2.0.0 - * **rxdart** updated from ^0.27.7 to ^0.28.0 - * **web** updated from ^0.5.1 to ^1.0.0 - * **web_socket_channel** updated from ^2.4.0 to ^3.0.1 - * **firebase_core updated** from ^2.15.1 to ^3.4.0 - * **firebase_messaging** updated from ^14.5.0 to ^15.1.1 - * **share_plus** updated from ^7.1.0 to ^10.0.2 - * **json_annotation** updated from ^4.8.0 to ^4.9.0 + +- The regular push notification handling has been removed from iOS, providing more control over the implementation. VoIP push notifications will continue to be handled as before. For more details, refer to the [documentation](https://getstream.io/video/docs/flutter/push-notifications/). + +- Dependency updates + - **Flutter SDK** constraint updated to >=3.22.0 (**Dart SDK** to >=3.4.0 <4.0.0) + - **internet_connection_checker** updated from ^1.0.0+1 to ^2.0.0 + - **rxdart** updated from ^0.27.7 to ^0.28.0 + - **web** updated from ^0.5.1 to ^1.0.0 + - **web_socket_channel** updated from ^2.4.0 to ^3.0.1 + - **firebase_core updated** from ^2.15.1 to ^3.4.0 + - **firebase_messaging** updated from ^14.5.0 to ^15.1.1 + - **share_plus** updated from ^7.1.0 to ^10.0.2 + - **json_annotation** updated from ^4.8.0 to ^4.9.0 ## 0.5.3 🐞 Fixed -* Improved video quality for a smoother experience. -* Resolved an issue where the participant's state showed an empty roles list. -* Fixed a bug that caused the CallKit ringing notification to continue after a call was accepted. + +- Improved video quality for a smoother experience. +- Resolved an issue where the participant's state showed an empty roles list. +- Fixed a bug that caused the CallKit ringing notification to continue after a call was accepted. ## 0.5.2 🐞 Fixed -* Fixed CallKit integration on iOS when app is in a terminated state. It now correctly openes the app when the call is accepted. -* Fixed `onLeaveCallTap` callback in `StreamCallContent`. It's now correctly handled. -* (Android) Prevented the app from crashing when microphone permission is not granted and actove call foreground services is started. The service will now not start if no permission is granted. -* (Android) Marked the active call notification channel's lockscreen visibility as public to ensure it shows when the Android device is locked. + +- Fixed CallKit integration on iOS when app is in a terminated state. It now correctly openes the app when the call is accepted. +- Fixed `onLeaveCallTap` callback in `StreamCallContent`. It's now correctly handled. +- (Android) Prevented the app from crashing when microphone permission is not granted and actove call foreground services is started. The service will now not start if no permission is granted. +- (Android) Marked the active call notification channel's lockscreen visibility as public to ensure it shows when the Android device is locked. πŸ”„ Changed -* `SortParam` changed to `SortParamRequest` in `queryMembers()` method inside `Call` and `StreamVideo` class + +- `SortParam` changed to `SortParamRequest` in `queryMembers()` method inside `Call` and `StreamVideo` class ## 0.5.1 βœ… Added -* Added `backstage` parameter to `call.getOtCreate()` method with backstage settings. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/joining-and-creating-calls/#backstage-setup) - * Ability to join call in advance with `joinAheadTimeSeconds` parameter (part of `StreamBackstageSettings`) -* Added `startsAt` parameter to `call.getOtCreate()` method -* Added `maxDuration` and `maxParticipants` parameters to `call.getOtCreate()` method -* Added `video` parameter to `call.getOtCreate()`, `call.getCall()` and `call.join()` methods. This parameter is used to distinguish between audio-only and video calls for ringing purposes. - * ❗Important❗ the `video` parameter is `false` by default. If you want your call to be treated as a video call while ringing set it to `true`. -* Added `streamVideo` paramter to `StreamLobbyView` and `StreamLobbyVideo` widgets provide a custom `StreamVideo` instance. + +- Added `backstage` parameter to `call.getOtCreate()` method with backstage settings. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/joining-and-creating-calls/#backstage-setup) + - Ability to join call in advance with `joinAheadTimeSeconds` parameter (part of `StreamBackstageSettings`) +- Added `startsAt` parameter to `call.getOtCreate()` method +- Added `maxDuration` and `maxParticipants` parameters to `call.getOtCreate()` method +- Added `video` parameter to `call.getOtCreate()`, `call.getCall()` and `call.join()` methods. This parameter is used to distinguish between audio-only and video calls for ringing purposes. + - ❗Important❗ the `video` parameter is `false` by default. If you want your call to be treated as a video call while ringing set it to `true`. +- Added `streamVideo` paramter to `StreamLobbyView` and `StreamLobbyVideo` widgets provide a custom `StreamVideo` instance. 🐞 Fixed -* Fixed reaction dismissal: Sent and received reactions are now correctly dismissed after a 5-second timeout (configurable in `CallPreferences`). -* Fixed the cancel button behavior in the screen-sharing notification on Android. It will now correctly stop the screen-sharing process. -* Fixed the issue with the cancel button in the call-in-progress notification was not stopping the call. -* Fixed the connection quality updates for other call participants. -* Fixed an issue where declining a ringing call when the app was in a terminated state did not stop the ringing on the caller's end. + +- Fixed reaction dismissal: Sent and received reactions are now correctly dismissed after a 5-second timeout (configurable in `CallPreferences`). +- Fixed the cancel button behavior in the screen-sharing notification on Android. It will now correctly stop the screen-sharing process. +- Fixed the issue with the cancel button in the call-in-progress notification was not stopping the call. +- Fixed the connection quality updates for other call participants. +- Fixed an issue where declining a ringing call when the app was in a terminated state did not stop the ringing on the caller's end. ## 0.5.0 βœ… Added -* Picture in Picture (PiP) is now also supported on iOS. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) + +- Picture in Picture (PiP) is now also supported on iOS. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) 🐞 Fixed -* Fixed an issue where the microphone was being muted when the app was running in the background on Android versions greater than 14. + +- Fixed an issue where the microphone was being muted when the app was running in the background on Android versions greater than 14. 🚧 Breaking changes -* The implementation of `BroadcastSampleHandler`, used for `broadcast` screen-sharing mode on iOS is now moved from `stream_video_flutter` package to a separate [stream_video_screen_sharing](https://pub.dev/packages/stream_video_screen_sharing) package. -Migration steps: -- Add `stream_video_screen_sharing` dependency to your `pubspec.yaml` file -- Replace the import in `SampleHandler.swift` file from `stream_video_flutter` to `stream_video_screen_sharing` -- Replace the dependancy added to the extension target in `Podfile` file from `stream_video_flutter` to `stream_video_screen_sharing` + +- The implementation of `BroadcastSampleHandler`, used for `broadcast` screen-sharing mode on iOS is now moved from `stream_video_flutter` package to a separate [stream_video_screen_sharing](https://pub.dev/packages/stream_video_screen_sharing) package. + Migration steps: + +* Add `stream_video_screen_sharing` dependency to your `pubspec.yaml` file +* Replace the import in `SampleHandler.swift` file from `stream_video_flutter` to `stream_video_screen_sharing` +* Replace the dependancy added to the extension target in `Podfile` file from `stream_video_flutter` to `stream_video_screen_sharing` For complete screen-sharing guide please refer to the [documentaiton](https://getstream.io/video/docs/flutter/advanced/screen_sharing/) -* Previously deprecated `String` `type` parameters in `makeCall()` and `getCallRingingState()` methods are now removed. Use `StreamCallType` `callType` parameter now. -* Previously deprecated `events` and `coordinatorEvents` streams are now removed from `Call` class. Use `callEvents` instead. +- Previously deprecated `String` `type` parameters in `makeCall()` and `getCallRingingState()` methods are now removed. Use `StreamCallType` `callType` parameter now. +- Previously deprecated `events` and `coordinatorEvents` streams are now removed from `Call` class. Use `callEvents` instead. ## 0.4.4 βœ… Added -* Added `watch` parameter to `StreamVideo.queryCalls()` method, allowing you to subscribe to queried call events. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/querying-calls/). -* Introduced `listRecordings()` to `StreamVideo` object, enabling you to query call recordings using a provided call CID. + +- Added `watch` parameter to `StreamVideo.queryCalls()` method, allowing you to subscribe to queried call events. For more information, refer to the [documentation](https://getstream.io/video/docs/flutter/querying-calls/). +- Introduced `listRecordings()` to `StreamVideo` object, enabling you to query call recordings using a provided call CID. πŸ”„ Changed -* The default constructor for `StreamCallType` is now deprecated. Instead, use the `StreamCallType.defaultType()` factory constuctor. + +- The default constructor for `StreamCallType` is now deprecated. Instead, use the `StreamCallType.defaultType()` factory constuctor. 🐞 Fixed -* Improved the quality of screen sharing. It now correctly respects the parameters set in `ScreenSharingConstraints` to adjust the quality. -* The `FloatingViewAlignment` enum is now properly exported in the `stream_video_flutter` package. + +- Improved the quality of screen sharing. It now correctly respects the parameters set in `ScreenSharingConstraints` to adjust the quality. +- The `FloatingViewAlignment` enum is now properly exported in the `stream_video_flutter` package. ## 0.4.3 🐞 Fixed -* Fixed reconnection flow. -* Fixed compilation errors on web. -* Fixed screen-sharing not working on some versions of Android. -* Fixed accepting incoming call during another call (or outgoing call). -* Fixed CallKit incoming push label and Android accept call button icons for audio-only calls. + +- Fixed reconnection flow. +- Fixed compilation errors on web. +- Fixed screen-sharing not working on some versions of Android. +- Fixed accepting incoming call during another call (or outgoing call). +- Fixed CallKit incoming push label and Android accept call button icons for audio-only calls. βœ… Added -* Added support for missed calls. Push notifications and `CallMissedEvent` event will be sent now when the user misses the call. -* Added support for call transcription [check transcription cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/transcriptions/) - * Added `startTranscription()`, `stopTranscription()` and `listTranscriptions()` methods to `Call` class. -* Added option to take a screenshot during the call [check screenshot documentation](https://getstream.io/video/docs/flutter/screenshots/) - * Added `takeScreenshot()` method to `Call` class. -* Added `recordingExternalStorage` optional param to `call.startRecording()` method. -* Added `requestScreenSharePermission()` method to `Call` class that ensures correct permissions are given for screen-sharing on Android. + +- Added support for missed calls. Push notifications and `CallMissedEvent` event will be sent now when the user misses the call. +- Added support for call transcription [check transcription cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/transcriptions/) + - Added `startTranscription()`, `stopTranscription()` and `listTranscriptions()` methods to `Call` class. +- Added option to take a screenshot during the call [check screenshot documentation](https://getstream.io/video/docs/flutter/screenshots/) + - Added `takeScreenshot()` method to `Call` class. +- Added `recordingExternalStorage` optional param to `call.startRecording()` method. +- Added `requestScreenSharePermission()` method to `Call` class that ensures correct permissions are given for screen-sharing on Android. πŸ”„ Changed -* Changed `role` member to `roles`, to reflect the possibility of the user having multiple roles, in `CallParticipantState` and `CallMember`. -* Changed `SortParamRequest` to `SortParam`. + +- Changed `role` member to `roles`, to reflect the possibility of the user having multiple roles, in `CallParticipantState` and `CallMember`. +- Changed `SortParamRequest` to `SortParam`. πŸ”„ Changed some of the signatures -* `listRecordings()` method in PermissionsManager doesn't require `sessionId` param now. -* `setParticipantPinned()` method in `Call` and `CallSession` now requires `sessionId`, `userId`, and `pinned` params instead of `SetParticipantPinned` action. -* `updateViewportVisibility()` method in `CallSession` now requires `visibilityChange` param instead of `UpdateViewportVisibility` action. -* `setSubscriptions()` and `updateSubscription()` methods in `CallSession` now require a list of `subscriptionChanges` param instead of a list of `SetSubscription` actions. -* Added optional `reason` param to `reject()` method in `Call` class. + +- `listRecordings()` method in PermissionsManager doesn't require `sessionId` param now. +- `setParticipantPinned()` method in `Call` and `CallSession` now requires `sessionId`, `userId`, and `pinned` params instead of `SetParticipantPinned` action. +- `updateViewportVisibility()` method in `CallSession` now requires `visibilityChange` param instead of `UpdateViewportVisibility` action. +- `setSubscriptions()` and `updateSubscription()` methods in `CallSession` now require a list of `subscriptionChanges` param instead of a list of `SetSubscription` actions. +- Added optional `reason` param to `reject()` method in `Call` class. Removed -* Removed `updateSubscriptions` method from `Call`. + +- Removed `updateSubscriptions` method from `Call`. ## 0.4.2 βœ… Added -* Added `ClientDetails` to SFU's `join` request. + +- Added `ClientDetails` to SFU's `join` request. 🐞 Fixed -* Tweaked SFU events handling to ensure there is no gap in handling them. -* Fixed camera and microphone toggling on incoming/outgoing screen. -* Fixed screen sharing not working when camera track was enabled. -* Fixed issues with video freezing sometimes. + +- Tweaked SFU events handling to ensure there is no gap in handling them. +- Fixed camera and microphone toggling on incoming/outgoing screen. +- Fixed screen sharing not working when camera track was enabled. +- Fixed issues with video freezing sometimes. ## 0.4.1 🚧 Build breaking changes -* Bumped `connectivity_plus` dependency to `6.0.3` + +- Bumped `connectivity_plus` dependency to `6.0.3` > Note, that this changes the plugin requirements: +> > - compileSDK 34 for Android part > - Java 17 for Android part > - Gradle 8.4 for Android part 🐞 Fixed -* Added foreground service type to service declaration in AndroidManifest + +- Added foreground service type to service declaration in AndroidManifest ## 0.4.0 🚧 Breaking changes -* Updated minimum supported dart SDK version to `3.3.0` (which requires min Flutter SDK `3.19.0`) -* Updated `flutter_webrtc` to 0.10.4 +- Updated minimum supported dart SDK version to `3.3.0` (which requires min Flutter SDK `3.19.0`) + +- Updated `flutter_webrtc` to 0.10.4 🐞 Fixed -* Fixed an issue where subscriber offer events might be missed causing missing video/audio tracks for call participants. -* Fixed speakerphone/earpiece switching on iOS. -* User is now diconnected immedietaly when leaving the call. + +- Fixed an issue where subscriber offer events might be missed causing missing video/audio tracks for call participants. +- Fixed speakerphone/earpiece switching on iOS. +- User is now diconnected immedietaly when leaving the call. ## 0.3.9 -* Reverted `flutter_webrtc` dependency version back to `0.9.47` to fix the compilation issues for web in Flutter 3.19. + +- Reverted `flutter_webrtc` dependency version back to `0.9.47` to fix the compilation issues for web in Flutter 3.19. ## 0.3.8 🐞 Fixed -* Fixed application of initial call configuration (via `CallConnectOptions`) and default settings from Stream Dashboard -* Default camera facing is now applied from Dashboard settings (was ignored previously) + +- Fixed application of initial call configuration (via `CallConnectOptions`) and default settings from Stream Dashboard +- Default camera facing is now applied from Dashboard settings (was ignored previously) βœ… Added -* `audioOutputDevice`, `audioInputDevice` and `cameraFacingMode` added to `CallConnectOptions` -* Optional `connectOptions` parameter added to `call.join()` method as a preferred way of setting initial call configuration - check out our [documentation](https://getstream.io/video/docs/flutter/initial-call-configuration/) for more info + +- `audioOutputDevice`, `audioInputDevice` and `cameraFacingMode` added to `CallConnectOptions` +- Optional `connectOptions` parameter added to `call.join()` method as a preferred way of setting initial call configuration - check out our [documentation](https://getstream.io/video/docs/flutter/initial-call-configuration/) for more info ## 0.3.7 -* Updated minimum supported SDK version to Flutter 3.16 + +- Updated minimum supported SDK version to Flutter 3.16 βœ… Added -* Added `mirrorMode` parameter to `CameraConstraints`, which determines whether the camera for the given track should be mirrored or not. When set as `defaultMode` the mirroring is set as true, when `facingMode` is set to `user` and false when facingMode is set to `environment`. +- Added `mirrorMode` parameter to `CameraConstraints`, which determines whether the camera for the given track should be mirrored or not. When set as `defaultMode` the mirroring is set as true, when `facingMode` is set to `user` and false when facingMode is set to `environment`. 🐞 Fixed -* Fixed an issue that might break screen sharing functionality. -* Fixed an issue that caused output audio device not being set correctly. -* Fixed an issue that still caused constant notification sound being triggered during the call on Android. -* Fixed an issue that blocked volume adjastment during the call on Android. +- Fixed an issue that might break screen sharing functionality. +- Fixed an issue that caused output audio device not being set correctly. +- Fixed an issue that still caused constant notification sound being triggered during the call on Android. +- Fixed an issue that blocked volume adjastment during the call on Android. ## 0.3.6 + βœ… Added -* Added `callEvents` stream to `Call` that replaces `events` and `coordinatorEvents` streams (both are now deprecated). -* Added `callBackgroundBuilder` to `StreamOutg/oingCallContent`. +- Added `callEvents` stream to `Call` that replaces `events` and `coordinatorEvents` streams (both are now deprecated). +- Added `callBackgroundBuilder` to `StreamOutg/oingCallContent`. 🚧 Breaking changes -* Removed the `callCid` parameter requirement from `sendCustomEvent()` method in `Call` class. +- Removed the `callCid` parameter requirement from `sendCustomEvent()` method in `Call` class. 🐞 Fixed -* Fixed an issue that caused an empty Call participants list in CallState during ringing. -* Fixed an issue that caused constant notification sound being triggered during the call on Android. -* Disabled camera mirroring when using back camera and when screensharing. +- Fixed an issue that caused an empty Call participants list in CallState during ringing. +- Fixed an issue that caused constant notification sound being triggered during the call on Android. +- Disabled camera mirroring when using back camera and when screensharing. ## 0.3.5 + βœ… Added -* Added `keepConnectionsAliveWhenInBackground` to `StreamVideoOptions` to allow keeping websocket connections and event subscribtions open when app is in the background (false by default). -* Added support for Picture in Picture feature to Android - check out our [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) for more info -* Added usage statictics reporting +- Added `keepConnectionsAliveWhenInBackground` to `StreamVideoOptions` to allow keeping websocket connections and event subscribtions open when app is in the background (false by default). +- Added support for Picture in Picture feature to Android - check out our [documentation](https://getstream.io/video/docs/flutter/advanced/picture_in_picture/) for more info +- Added usage statictics reporting 🐞 Fixed -* Fixed handling of default audio output device setting from Stream dashboard -* Fixed handling of default camera/microphone state setting from Stream dashboard -* Fixed an issue where call could sometimes loose participants state -* Fixed an issue in `LobbyView` where camera/microphone state selected would not be correctly applied into the call +- Fixed handling of default audio output device setting from Stream dashboard +- Fixed handling of default camera/microphone state setting from Stream dashboard +- Fixed an issue where call could sometimes loose participants state +- Fixed an issue in `LobbyView` where camera/microphone state selected would not be correctly applied into the call ## 0.3.4 -* Fixed the size of the LeaveCall aciton button in `CallAppBar` -* Added `showLeaveCallAction` property to `CallAppBar` +- Fixed the size of the LeaveCall aciton button in `CallAppBar` +- Added `showLeaveCallAction` property to `CallAppBar` ## 0.3.3 🚧 UI changes to SDK components -* `CallParticipantsLabel` - removed internal padding, it sticks to the corner of the video frame by default now -* Extracted `StreamLobbyVideo` widget from `StreamLobbyView` that can be easly reused in custom layout -* `CallAppBar` - - `LeaveCallOption` moved from default call controls to `CallAppBar` - - Participants button removed from `CallAppBar` together with `onParticipantsInfoTap` and `participantsInfoBuilder` properties - - Layout Mode button removed from `CallAppBar` together with `onLayoutModeChanged` property. You can use new `ToggleLayoutOption` instead in custom layout anywhere -* `ToggleLayoutOption` added -* Components related to participants menu item from `CallAppBar` are removed: `CallParticipantsInfoItem`, `StreamCallParticipantsInfoMenu` and `CallParticipantsInfoOptions` -* `StreamCallParticipantsInfoMenuTheme` is removed +- `CallParticipantsLabel` - removed internal padding, it sticks to the corner of the video frame by default now +- Extracted `StreamLobbyVideo` widget from `StreamLobbyView` that can be easly reused in custom layout +- `CallAppBar` + - `LeaveCallOption` moved from default call controls to `CallAppBar` + - Participants button removed from `CallAppBar` together with `onParticipantsInfoTap` and `participantsInfoBuilder` properties + - Layout Mode button removed from `CallAppBar` together with `onLayoutModeChanged` property. You can use new `ToggleLayoutOption` instead in custom layout anywhere +- `ToggleLayoutOption` added +- Components related to participants menu item from `CallAppBar` are removed: `CallParticipantsInfoItem`, `StreamCallParticipantsInfoMenu` and `CallParticipantsInfoOptions` +- `StreamCallParticipantsInfoMenuTheme` is removed Other changes: -* Added `StreamCallType` class that replaces depricated String `type` parameter -* Exapanded `CallStats` class with more structured WebRTC statistics as `stats` field -* Changed `raw` statistics in `CallStats` to be of a Map type -* Added `publisherStats`, `subsciberStats` and `latencyHistory` to the `CallState` that hold some of the processed statistcs + +- Added `StreamCallType` class that replaces depricated String `type` parameter +- Exapanded `CallStats` class with more structured WebRTC statistics as `stats` field +- Changed `raw` statistics in `CallStats` to be of a Map type +- Added `publisherStats`, `subsciberStats` and `latencyHistory` to the `CallState` that hold some of the processed statistcs Bug fixes -* Fixes incoming call behavior when both CallKit and Stream incoming screen component is used -* Fixes the issue on Android that caused missed call notification when ringing with reused call id + +- Fixes incoming call behavior when both CallKit and Stream incoming screen component is used +- Fixes the issue on Android that caused missed call notification when ringing with reused call id ## 0.3.2 🐞 Fixed -* Various fixes to call ringing and push notifications. -- Fixes call ringing cancellation when app is terminated on iOS (requires additional setup - check Step 6 of the [APNS integration](https://getstream.io/video/docs/flutter/advanced/ringing_and_callkit/#integrating-apns-for-ios)) in our documentation. -- Fixes late push notification handling on Android, where already ended call was ringing if the device was offline and the push was delivered with a delay. -- Fixes call ringing cancellation when caller timed out while calling -* Fixed action tap callback on Android call notification. -* Fixed background image for incoming/outgoing call screens when `participant.image` is invalid. -* Fixes possible crashes for Android SDKs versions <26. -* Fixed screen sharing on iOS when screen sharing mode was switched between `in-app` and `broadcast`. -* Changed the version range of `intl` package to >=0.18.1 <=0.19.0 because it was causing isses with other packages. +- Various fixes to call ringing and push notifications. + +* Fixes call ringing cancellation when app is terminated on iOS (requires additional setup - check Step 6 of the [APNS integration](https://getstream.io/video/docs/flutter/advanced/ringing_and_callkit/#integrating-apns-for-ios)) in our documentation. +* Fixes late push notification handling on Android, where already ended call was ringing if the device was offline and the push was delivered with a delay. +* Fixes call ringing cancellation when caller timed out while calling + +- Fixed action tap callback on Android call notification. +- Fixed background image for incoming/outgoing call screens when `participant.image` is invalid. +- Fixes possible crashes for Android SDKs versions <26. +- Fixed screen sharing on iOS when screen sharing mode was switched between `in-app` and `broadcast`. +- Changed the version range of `intl` package to >=0.18.1 <=0.19.0 because it was causing isses with other packages. βœ… Added -* Added `custom` field to `CallParticipantState` with custom user data. +- Added `custom` field to `CallParticipantState` with custom user data. ## 0.3.1 -* Important: Fixes crash for CallKit on iOS. -* Added support for SFU migration to improve video resilience. -* Fixes for streaming flags in `CallState` (backstage, broadcasting, recording). +- Important: Fixes crash for CallKit on iOS. +- Added support for SFU migration to improve video resilience. +- Fixes for streaming flags in `CallState` (backstage, broadcasting, recording). ## 0.3.0 -🚧 Breaking changes +🚧 Breaking changes -* The functionality from `stream_video_flutter_background` is now merged into `stream_video_flutter`. You no longer have to use the background plugin. -* Removed the `incomingCallerNameOverride` and `incomingCallerHandlerOverride` from `StreamVideoPushParams` in favor of the new `callerCustomizationCallback` in `StreamVideoPushNotificationManager`. +- The functionality from `stream_video_flutter_background` is now merged into `stream_video_flutter`. You no longer have to use the background plugin. +- Removed the `incomingCallerNameOverride` and `incomingCallerHandlerOverride` from `StreamVideoPushParams` in favor of the new `callerCustomizationCallback` in `StreamVideoPushNotificationManager`. βœ… Added -* Added `LivestreamPlayer` - a in-built widget that allows you to easily view livestreams. -* Added screen sharing functionality and related toggle option for both Android and iOS. Check [our documentation](https://getstream.io/video/docs/flutter/) for more details -* Exposed call coordinator events through the `coordinatorEvents` stream in the `Call` class. -* Added `StreamCallContentTheme` to video theme. -* `callerCustomizationCallback` to `StreamVideoPushNotificationManager` that allow dynamic customization of CallKit call screen. +- Added `LivestreamPlayer` - a in-built widget that allows you to easily view livestreams. +- Added screen sharing functionality and related toggle option for both Android and iOS. Check [our documentation](https://getstream.io/video/docs/flutter/) for more details +- Exposed call coordinator events through the `coordinatorEvents` stream in the `Call` class. +- Added `StreamCallContentTheme` to video theme. +- `callerCustomizationCallback` to `StreamVideoPushNotificationManager` that allow dynamic customization of CallKit call screen. Example usage: @@ -954,77 +1086,79 @@ pushNotificationManagerProvider: StreamVideoPushNotificationManager.create( ), ``` -* Added a `includeUserDetails` field to determine if user details should be passed to backend when connecting user. -* Added `team`, `notify`, and `custom` properties to `getOrCreate()` for `Call`. +- Added a `includeUserDetails` field to determine if user details should be passed to backend when connecting user. +- Added `team`, `notify`, and `custom` properties to `getOrCreate()` for `Call`. 🐞 Fixed -* Added Apple audio configuration to make audio work in silent mode. -* Fixed ringing call cancellation issues. +- Added Apple audio configuration to make audio work in silent mode. +- Fixed ringing call cancellation issues. ## 0.2.0 βœ… Added -* `removeMembers` and `updateCallMembers` to `Call` -* `incomingCallerNameOverride` and `incomingCallerHandlerOverride` to `StreamVideoPushParams` to allow customization of CallKit call screen -* `participantsAvatarBuilder` and `participantsDisplayNameBuilder` to `StreamOutgoingCallContent` and `StreamIncomingCallContent` to allow customiztion of Incoming and Outgoing call screens +- `removeMembers` and `updateCallMembers` to `Call` +- `incomingCallerNameOverride` and `incomingCallerHandlerOverride` to `StreamVideoPushParams` to allow customization of CallKit call screen +- `participantsAvatarBuilder` and `participantsDisplayNameBuilder` to `StreamOutgoingCallContent` and `StreamIncomingCallContent` to allow customiztion of Incoming and Outgoing call screens Example usage: - ```dart - StreamCallContainer( - ... - outgoingCallBuilder: (context, call, callState) => - StreamOutgoingCallContent( - call: call, - callState: callState, - participantsDisplayNameBuilder: - (context, call, callState, participants) => your widget here, - ), - ) - ``` + +```dart +StreamCallContainer( + ... + outgoingCallBuilder: (context, call, callState) => + StreamOutgoingCallContent( + call: call, + callState: callState, + participantsDisplayNameBuilder: + (context, call, callState, participants) => your widget here, + ), +) +``` πŸ”„ Changed Breaking changes 🚧 -* renamed `inviteUsers` to `addMembers` in `Call` -* renamed parameter name in `getOrCreateCall` from `participantIds` to `memberIds` + +- renamed `inviteUsers` to `addMembers` in `Call` +- renamed parameter name in `getOrCreateCall` from `participantIds` to `memberIds` ## 0.1.1 -* Fixed call join bug -* Fixed CallKit call not ending bug -* Anonymous users can no longer connect to WS -* Users can no longer join a call twice -* Fixed landscape call control visibility +- Fixed call join bug +- Fixed CallKit call not ending bug +- Anonymous users can no longer connect to WS +- Users can no longer join a call twice +- Fixed landscape call control visibility ## 0.1.0 -* Aligned SDK initialization with other SDKs -* Fixed callkit and push implementation for SDK -* Added parsing for CallPermissions -* Fix duplicate participants in call -* Hide debug stats in production -* Display call participants in lobby view -* General bug fixes and improvements +- Aligned SDK initialization with other SDKs +- Fixed callkit and push implementation for SDK +- Added parsing for CallPermissions +- Fix duplicate participants in call +- Hide debug stats in production +- Display call participants in lobby view +- General bug fixes and improvements ## 0.0.4 -* Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0 +- Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0 ## 0.0.3 -* Fixed track subscription bug +- Fixed track subscription bug ## 0.0.2 -* Updates for backend -* Support for reactions +- Updates for backend +- Support for reactions ## 0.0.1+1 -* Fixed README +- Fixed README ## 0.0.1 -* Initial beta release of Stream Video πŸš€ \ No newline at end of file +- Initial beta release of Stream Video πŸš€ diff --git a/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart b/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart index bb44b6a35..1cd910206 100644 --- a/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart +++ b/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import 'package:visibility_detector/visibility_detector.dart'; @@ -16,7 +17,7 @@ class StreamVideoRenderer extends StatefulWidget { required this.participant, required this.videoTrackType, this.placeholderBuilder = _defaultPlaceholderBuilder, - this.videoFit = VideoFit.cover, + this.videoFit, this.onSizeChanged, this.persistTrackIfNotVisible = false, this.rendererScopePrefix, @@ -35,7 +36,10 @@ class StreamVideoRenderer extends StatefulWidget { final WidgetBuilder placeholderBuilder; /// The scale type to use for the video renderer. - final VideoFit videoFit; + /// + /// When `null`, [defaultVideoFit] is used, which resolves to + /// [VideoFit.adaptive] on web and desktop and [VideoFit.cover] on mobile. + final VideoFit? videoFit; /// Called when the size of the widget changes. final ValueSetter? onSizeChanged; @@ -247,6 +251,21 @@ enum VideoFit { /// Scale the video uniformly (maintain the video's aspect ratio) /// to cover the entire widget area. cover, + + /// Automatically pick between [cover] and [contain] based on the video's + /// own orientation: landscape (or square) video fills the widget ([cover]), + /// while portrait/tall video is letterboxed so the whole frame stays + /// visible ([contain]). + adaptive, +} + +/// The [VideoFit] used for participant video when none is explicitly set. +/// +/// Resolves to [VideoFit.adaptive] on web and desktop, so portrait video is +/// letterboxed instead of cropped, and to [VideoFit.cover] on mobile. +VideoFit get defaultVideoFit { + if (CurrentPlatform.isMobile) return VideoFit.cover; + return VideoFit.adaptive; } /// A widget that renders a single video track. @@ -256,7 +275,7 @@ class VideoTrackRenderer extends StatefulWidget { super.key, required this.videoTrack, this.mirror = false, - this.videoFit = VideoFit.cover, + this.videoFit, this.placeholderBuilder = _defaultPlaceholderBuilder, }); @@ -267,7 +286,10 @@ class VideoTrackRenderer extends StatefulWidget { final bool mirror; /// The scale type of the video. - final VideoFit videoFit; + /// + /// When `null`, [defaultVideoFit] is used, which resolves to + /// [VideoFit.adaptive] on web and desktop and [VideoFit.cover] on mobile. + final VideoFit? videoFit; /// A builder for the placeholder. final WidgetBuilder placeholderBuilder; @@ -313,23 +335,45 @@ class _VideoTrackRendererState extends State { @override Widget build(BuildContext context) { - return !_isInitialized - ? widget.placeholderBuilder.call(context) - : rtc.RTCVideoView( - _videoRenderer, - mirror: widget.mirror, - objectFit: _getVideoViewObjectFit(widget.videoFit), - filterQuality: FilterQuality.medium, - placeholderBuilder: widget.placeholderBuilder, - ); + if (!_isInitialized) { + return widget.placeholderBuilder.call(context); + } + + final videoFit = widget.videoFit ?? defaultVideoFit; + + // Listen to the renderer's value so [VideoFit.adaptive] can recompute the + // object fit whenever the incoming video dimensions or rotation change. + return ValueListenableBuilder( + valueListenable: _videoRenderer, + builder: (context, value, _) { + return rtc.RTCVideoView( + _videoRenderer, + mirror: widget.mirror, + objectFit: _getVideoViewObjectFit(videoFit, value), + filterQuality: FilterQuality.medium, + placeholderBuilder: widget.placeholderBuilder, + ); + }, + ); } - rtc.RTCVideoViewObjectFit _getVideoViewObjectFit(VideoFit videoFit) { + rtc.RTCVideoViewObjectFit _getVideoViewObjectFit( + VideoFit videoFit, + rtc.RTCVideoValue value, + ) { switch (videoFit) { case VideoFit.cover: return rtc.RTCVideoViewObjectFit.RTCVideoViewObjectFitCover; case VideoFit.contain: return rtc.RTCVideoViewObjectFit.RTCVideoViewObjectFitContain; + case VideoFit.adaptive: + // [RTCVideoValue.aspectRatio] is rotation-aware and returns 1.0 until + // the first frame arrives, so tall/portrait video is letterboxed while + // landscape (or square, or not-yet-known) video fills the widget. + final isWide = value.aspectRatio >= 1.0; + return isWide + ? rtc.RTCVideoViewObjectFit.RTCVideoViewObjectFitCover + : rtc.RTCVideoViewObjectFit.RTCVideoViewObjectFitContain; } } } diff --git a/packages/stream_video_flutter/lib/src/theme/call_participant_theme.dart b/packages/stream_video_flutter/lib/src/theme/call_participant_theme.dart index 8bb997095..a94bddef7 100644 --- a/packages/stream_video_flutter/lib/src/theme/call_participant_theme.dart +++ b/packages/stream_video_flutter/lib/src/theme/call_participant_theme.dart @@ -10,7 +10,7 @@ import '../../stream_video_flutter.dart'; class StreamCallParticipantThemeData with Diagnosticable { /// Creates a new instance of [StreamCallParticipantThemeData]. const StreamCallParticipantThemeData({ - this.videoFit = VideoFit.cover, + this.videoFit, this.backgroundColor = const Color(0xffB4B7BB), this.borderRadius = BorderRadius.zero, this.userAvatarTheme = const StreamUserAvatarThemeData( @@ -48,8 +48,11 @@ class StreamCallParticipantThemeData with Diagnosticable { }); // ignore: comment_references - /// The fit of the [VideoRenderer] widget - final VideoFit videoFit; + /// The fit of the [VideoRenderer] widget. + /// + /// When `null`, [defaultVideoFit] is used, which resolves to + /// [VideoFit.adaptive] on web and desktop and [VideoFit.cover] on mobile. + final VideoFit? videoFit; /// The background color of the call participant. final Color backgroundColor; From c183bf23b1aeb14a03afe71c666938e2828c2658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Braz=CC=87ewicz?= Date: Tue, 7 Jul 2026 12:08:08 +0200 Subject: [PATCH 2/2] tweak --- .../stream_video_flutter/lib/src/renderer/video_renderer.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart b/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart index 1cd910206..6800cc245 100644 --- a/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart +++ b/packages/stream_video_flutter/lib/src/renderer/video_renderer.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import 'package:visibility_detector/visibility_detector.dart';