Skip to content
Merged
Prev Previous commit
Next Next commit
Merge branch 'main' into speed_reset
  • Loading branch information
misos1 committed Dec 12, 2024
commit 39a189da020a8ca95f771f4e181002db900e8818
10 changes: 9 additions & 1 deletion packages/video_player/video_player_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
## 2.6.4
## 2.6.6

* Fixes playback speed resetting.

## 2.6.5

* Bugfix to allow the audio-only HLS (.m3u8) on iOS.

## 2.6.4

* Refactors native code structure.

## 2.6.3

* Fixes VideoPlayerController.initialize() future never resolving with invalid video file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ @interface FVPVideoPlayer ()
@property(nonatomic) CGAffineTransform preferredTransform;
/// Indicates whether the video player is currently playing.
@property(nonatomic, readonly) BOOL isPlaying;
/// The target playback speed requested by the plugin client.
@property(nonatomic, readonly) NSNumber *targetPlaybackSpeed;
/// Indicates whether the video player has been initialized.
@property(nonatomic, readonly) BOOL isInitialized;
/// The updater that drives callbacks to the engine to indicate that a new frame is ready.
Expand Down Expand Up @@ -323,7 +325,15 @@ - (void)updatePlayingState {
return;
}
if (_isPlaying) {
[_player play];
// Calling play is the same as setting the rate to 1.0 (or to defaultRate depending on iOS
// version) so last set playback speed must be set here if any instead.
// https://github.com/flutter/flutter/issues/71264
// https://github.com/flutter/flutter/issues/73643
if (_targetPlaybackSpeed) {
[self updateRate];
} else {
[_player play];
}
} else {
[_player pause];
}
Expand All @@ -332,6 +342,32 @@ - (void)updatePlayingState {
_displayLink.running = _isPlaying || self.waitingForFrame;
}

/// Synchronizes the player's playback rate with targetPlaybackSpeed, constrained by the playback
/// rate capabilities of the player's current item.
- (void)updateRate {
// See https://developer.apple.com/library/archive/qa/qa1772/_index.html for an explanation of
// these checks.
// If status is not AVPlayerItemStatusReadyToPlay then both canPlayFastForward
// and canPlaySlowForward are always false and it is unknown whether video can
// be played at these speeds, updatePlayingState will be called again when
// status changes to AVPlayerItemStatusReadyToPlay.
float speed = _targetPlaybackSpeed.floatValue;
BOOL readyToPlay = _player.currentItem.status == AVPlayerItemStatusReadyToPlay;
if (speed > 2.0 && !_player.currentItem.canPlayFastForward) {
if (!readyToPlay) {
return;
}
speed = 2.0;
}
if (speed < 1.0 && !_player.currentItem.canPlaySlowForward) {
if (!readyToPlay) {
return;
}
speed = 1.0;
}
_player.rate = speed;
}

- (void)sendFailedToLoadVideoEvent {
if (_eventSink == nil) {
return;
Expand Down Expand Up @@ -473,27 +509,8 @@ - (void)setVolume:(double)volume {
}

- (void)setPlaybackSpeed:(double)speed {
// See https://developer.apple.com/library/archive/qa/qa1772/_index.html for an explanation of
// these checks.
if (speed > 2.0 && !_player.currentItem.canPlayFastForward) {
if (_eventSink != nil) {
_eventSink([FlutterError errorWithCode:@"VideoError"
message:@"Video cannot be fast-forwarded beyond 2.0x"
details:nil]);
}
return;
}

if (speed < 1.0 && !_player.currentItem.canPlaySlowForward) {
if (_eventSink != nil) {
_eventSink([FlutterError errorWithCode:@"VideoError"
message:@"Video cannot be slow-forwarded"
details:nil]);
}
return;
}

_player.rate = speed;
_targetPlaybackSpeed = @(speed);
[self updatePlayingState];
}

- (CVPixelBufferRef)copyPixelBuffer {
Expand Down
Loading
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.