@@ -36,7 +36,11 @@ - (void)onDisplayLink:(CADisplayLink *)link {
3636@interface FLTVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
3737@property (readonly , nonatomic ) AVPlayer *player;
3838@property (readonly , nonatomic ) AVPlayerItemVideoOutput *videoOutput;
39- // / An invisible player layer used to access the pixel buffers in protected video streams in iOS 16.
39+ // This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
40+ // (https://github.com/flutter/flutter/issues/111457) and 2. swapped width and height for some video
41+ // streams (not just iOS 16). (https://github.com/flutter/flutter/issues/109116).
42+ // An invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
43+ // for issue #1, and restore the correct width and height for issue #2.
4044@property (readonly , nonatomic ) AVPlayerLayer *playerLayer;
4145@property (readonly , nonatomic ) CADisplayLink *displayLink;
4246@property (nonatomic ) FlutterEventChannel *eventChannel;
@@ -134,17 +138,13 @@ NS_INLINE CGFloat radiansToDegrees(CGFloat radians) {
134138 return degrees;
135139};
136140
137- NS_INLINE UIViewController *rootViewController () API_AVAILABLE(ios(16.0 )) {
138- for (UIScene *scene in UIApplication.sharedApplication .connectedScenes ) {
139- if ([scene isKindOfClass: UIWindowScene.class]) {
140- for (UIWindow *window in ((UIWindowScene *)scene).windows ) {
141- if (window.isKeyWindow ) {
142- return window.rootViewController ;
143- }
144- }
145- }
146- }
147- return nil ;
141+ NS_INLINE UIViewController *rootViewController () {
142+ #pragma clang diagnostic push
143+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
144+ // TODO: (hellohuanlin) Provide a non-deprecated codepath. See
145+ // https://github.com/flutter/flutter/issues/104117
146+ return UIApplication.sharedApplication .keyWindow .rootViewController ;
147+ #pragma clang diagnostic pop
148148}
149149
150150- (AVMutableVideoComposition *)getVideoCompositionWithTransform : (CGAffineTransform)transform
@@ -242,13 +242,13 @@ - (instancetype)initWithPlayerItem:(AVPlayerItem *)item
242242 _player = [AVPlayer playerWithPlayerItem: item];
243243 _player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
244244
245- // This is to fix a bug (https://github.com/flutter/flutter/issues/111457) in iOS 16 with blank
246- // video for encrypted video streams. An invisible AVPlayerLayer is used to overwrite the
247- // protection of pixel buffers in those streams.
248- if (@ available (iOS 16.0 , *)) {
249- _playerLayer = [AVPlayerLayer playerLayerWithPlayer: _player];
250- [ rootViewController ().view.layer addSublayer: _playerLayer ];
251- }
245+ // This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
246+ // (https://github.com/flutter/flutter/issues/111457) and 2. swapped width and height for some
247+ // video streams (not just iOS 16). (https://github.com/flutter/flutter/issues/109116). An
248+ // invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
249+ // for issue #1, and restore the correct width and height for issue #2.
250+ _playerLayer = [AVPlayerLayer playerLayerWithPlayer: _player ];
251+ [ rootViewController ().view.layer addSublayer: _playerLayer];
252252
253253 [self createVideoOutputAndDisplayLink: frameUpdater];
254254
@@ -481,9 +481,7 @@ - (FlutterError *_Nullable)onListenWithArguments:(id _Nullable)arguments
481481// / so the channel is going to die or is already dead.
482482- (void )disposeSansEventChannel {
483483 _disposed = YES ;
484- if (@available (iOS 16.0 , *)) {
485- [_playerLayer removeFromSuperlayer ];
486- }
484+ [_playerLayer removeFromSuperlayer ];
487485 [_displayLink invalidate ];
488486 AVPlayerItem *currentItem = self.player .currentItem ;
489487 [currentItem removeObserver: self forKeyPath: @" status" ];
0 commit comments