Skip to content

Commit 39b3e5c

Browse files
[video_player] Add documentation explaining the use of isPlaybackLikelyToKeepUp over isPlaybackBufferFull or isPlaybackLikelyToKeepUp for determining playback stall status
1 parent 899f0f1 commit 39b3e5c

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,24 @@ - (void)observeValueForKeyPath:(NSString *)path
337337
}
338338
}
339339
} else if (context == playbackBufferEmptyContext) {
340-
// There's a bug in AVFoundation, KVO for `playbackBufferEmpty` when playing HLS content. The
341-
// expected behavior of the value change for `playbackBufferEmpty` is not triggered. This
342-
// issue has been confirmed in iOS 16.5. Refer:
343-
// https://github.com/flutter/packages/pull/3826#discussion_r1204985454 Fortunately, the KVO
344-
// for `playbackBufferFull` is working correctly, so the bug won't affect the event passing
345-
// responsible for `bufferingEnd` or `bufferingStart` events.
346340
if (_eventSink != nil) {
341+
// There's a bug in AVFoundation, KVO for `playbackBufferEmpty` when playing HLS content. The
342+
// expected behavior of the value change for `playbackBufferEmpty` is not triggered. This
343+
// issue has been confirmed in iOS 16.5. Refer:
344+
// https://github.com/flutter/packages/pull/3826#discussion_r1204985454 Fortunately, the KVO
345+
// for `playbackBufferFull` is working correctly, so the bug won't affect the event passing
346+
// responsible for `bufferingEnd` or `bufferingStart` events.
347+
348+
// Here we check `isPlaybackLikelyToKeepUp` instead of `isPlaybackBufferEmpty` to determine if
349+
// the playback is stalled or not. According to the Apple documentation for
350+
// [`AVPlayerItem`](https://developer.apple.com/documentation/avfoundation/avplayeritem/1390348-playbacklikelytokeepup?language=objc),
351+
// `isPlaybackLikelyToKeepUp` effectively indicates the likelihood of uninterrupted playback.
352+
// When `isPlaybackBufferEmpty` is true, it indicates a possible stall or end of playback, as
353+
// explained in the
354+
// [documentation](https://developer.apple.com/documentation/avfoundation/avplayeritem/1386960-playbackbufferempty?language=objc).
355+
// However, when `isPlaybackBufferEmpty` is false, we cannot determine if the playback is
356+
// actively playing, stalled, or reaching the end. Therefore, we rely on
357+
// `isPlaybackLikelyToKeepUp` to make this determination.
347358
if ([[_player currentItem] isPlaybackLikelyToKeepUp]) {
348359
_eventSink(@{@"event" : @"bufferingEnd"});
349360
} else {
@@ -352,6 +363,17 @@ - (void)observeValueForKeyPath:(NSString *)path
352363
}
353364
} else if (context == playbackBufferFullContext) {
354365
if (_eventSink != nil) {
366+
// Here we check `isPlaybackLikelyToKeepUp` instead of `isPlaybackBufferFull` to determine if
367+
// the playback is stalled or not. The
368+
// [`isPlaybackLikelyToKeepUp`](https://developer.apple.com/documentation/avfoundation/avplayeritem/1390348-playbacklikelytokeepup?language=objc)
369+
// property effectively indicates the likelihood of uninterrupted playback. It's important to
370+
// note that
371+
// [`isPlaybackBufferFull`](https://developer.apple.com/documentation/avfoundation/avplayeritem/1388852-playbackbufferfull?language=objc)
372+
// is not suitable for predicting playback stalling. Its purpose is to determine whether the
373+
// internal media buffer is full and if further I/O is suspended, rather than indicating the
374+
// playback status. Since `isPlaybackBufferFull` does not provide information about playback
375+
// stall or end, we rely on `isPlaybackLikelyToKeepUp` to make a more accurate determination
376+
// about the playback status.
355377
if ([[_player currentItem] isPlaybackLikelyToKeepUp]) {
356378
_eventSink(@{@"event" : @"bufferingEnd"});
357379
} else {

0 commit comments

Comments
 (0)