Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/video_player/video_player_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.12.0

* Routes video over AirPlay when an external screen is active, by setting
`usesExternalPlaybackWhileExternalScreenIsActive` on the `AVPlayer`. Selecting
an AirPlay route previously moved only the audio, leaving the video on the
device while the receiver showed a mirrored screen.

## 2.11.0

* Implements `setPreventsDisplaySleepDuringVideoPlayback` using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,23 @@ private let hlsAudioTestURI =
#expect(player.player.preventsDisplaySleepDuringVideoPlayback == true)
}

#if os(iOS)
@Test func externalPlaybackIsEnabledForAirPlay() {
let stubAVFactory = StubFVPAVFactory(player: AVPlayer())
let player = FVPVideoPlayer(
playerItem: StubPlayerItem(),
avFactory: stubAVFactory,
viewProvider: StubViewProvider())

// usesExternalPlaybackWhileExternalScreenIsActive defaults to NO, which
// keeps the video on the device whenever an external screen is active. An
// AirPlay route then moves only the audio, and the receiver shows a
// mirrored screen rather than playing the stream itself.
#expect(player.player.allowsExternalPlayback == true)
#expect(player.player.usesExternalPlaybackWhileExternalScreenIsActive == true)
}
#endif

/// Sanity checks a video player playing the given URL with the actual AVPlayer. This is essentially
/// a mini integration test of the player component.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ - (instancetype)initWithPlayerItem:(NSObject<FVPAVPlayerItem> *)item
_player = [avFactory playerWithPlayerItem:item];
_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

#if TARGET_OS_IOS
// Allow the video to follow an AirPlay route to an external device.
//
// allowsExternalPlayback already defaults to YES, but
// usesExternalPlaybackWhileExternalScreenIsActive defaults to NO, so the
// player deliberately keeps the picture on the device whenever an external
// screen is active. The result is that selecting an AirPlay route changes the
// audio route while the video stays on the phone and the TV only receives a
// mirrored copy of the screen.
//
// Verified on an Apple TV: with both set, the receiver plays the stream
// itself and the local surface is released.
_player.allowsExternalPlayback = YES;
_player.usesExternalPlaybackWhileExternalScreenIsActive = YES;
#endif

// Configure output. AVVideoColorPropertiesKey must be declared on the output settings (not on
// pixel buffer attributes, where AVFoundation silently ignores it) so that HDR sources are
// tone-mapped to BT.709 SDR for the Flutter texture.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: video_player_avfoundation
description: iOS and macOS implementation of the video_player plugin.
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
version: 2.11.0
version: 2.12.0

environment:
sdk: ^3.10.0
Expand Down