@@ -37,17 +37,13 @@ @interface FLTVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
3737@property (nonatomic ) FlutterEventChannel* eventChannel;
3838@property (nonatomic ) FlutterEventSink eventSink;
3939@property (nonatomic ) CGAffineTransform preferredTransform;
40- @property (nonatomic , readonly ) bool disposed;
41- @property (nonatomic , readonly ) bool isPlaying;
42- @property (nonatomic ) bool isLooping;
43- @property (nonatomic , readonly ) bool isInitialized;
40+ @property (nonatomic , readonly ) BOOL disposed;
41+ @property (nonatomic , readonly ) BOOL isPlaying;
42+ @property (nonatomic ) BOOL isLooping;
43+ @property (nonatomic , readonly ) BOOL isInitialized;
4444- (instancetype )initWithURL : (NSURL *)url
4545 frameUpdater : (FLTFrameUpdater*)frameUpdater
4646 httpHeaders : (NSDictionary <NSString*, NSString*>*)headers ;
47- - (void )play ;
48- - (void )pause ;
49- - (void )setIsLooping : (bool )isLooping ;
50- - (void )updatePlayingState ;
5147@end
5248
5349static void * timeRangeContext = &timeRangeContext;
@@ -114,22 +110,22 @@ - (void)itemDidPlayToEndTime:(NSNotification*)notification {
114110
115111const int64_t TIME_UNSET = -9223372036854775807 ;
116112
117- static inline int64_t FLTCMTimeToMillis (CMTime time) {
113+ NS_INLINE int64_t FLTCMTimeToMillis (CMTime time) {
118114 // When CMTIME_IS_INDEFINITE return a value that matches TIME_UNSET from ExoPlayer2 on Android.
119115 // Fixes https://github.com/flutter/flutter/issues/48670
120116 if (CMTIME_IS_INDEFINITE (time)) return TIME_UNSET;
121117 if (time.timescale == 0 ) return 0 ;
122118 return time.value * 1000 / time.timescale ;
123119}
124120
125- static inline CGFloat radiansToDegrees (CGFloat radians) {
121+ NS_INLINE CGFloat radiansToDegrees (CGFloat radians) {
126122 // Input range [-pi, pi] or [-180, 180]
127123 CGFloat degrees = GLKMathRadiansToDegrees ((float )radians);
128124 if (degrees < 0 ) {
129125 // Convert -90 to 270 and -180 to 180
130126 return degrees + 360 ;
131127 }
132- // Output degrees in between [0, 360[
128+ // Output degrees in between [0, 360]
133129 return degrees;
134130};
135131
@@ -217,9 +213,6 @@ - (CGAffineTransform)fixTransform:(AVAssetTrack*)videoTrack {
217213- (instancetype )initWithPlayerItem : (AVPlayerItem*)item frameUpdater : (FLTFrameUpdater*)frameUpdater {
218214 self = [super init ];
219215 NSAssert (self, @" super init cannot be nil" );
220- _isInitialized = false ;
221- _isPlaying = false ;
222- _disposed = false ;
223216
224217 AVAsset* asset = [item asset ];
225218 void (^assetCompletionHandler)(void ) = ^{
@@ -352,7 +345,7 @@ - (void)setupEventSinkIfReadyToPlay {
352345 return ;
353346 }
354347
355- _isInitialized = true ;
348+ _isInitialized = YES ;
356349 _eventSink (@{
357350 @" event" : @" initialized" ,
358351 @" duration" : @([self duration ]),
@@ -363,12 +356,12 @@ - (void)setupEventSinkIfReadyToPlay {
363356}
364357
365358- (void )play {
366- _isPlaying = true ;
359+ _isPlaying = YES ;
367360 [self updatePlayingState ];
368361}
369362
370363- (void )pause {
371- _isPlaying = false ;
364+ _isPlaying = NO ;
372365 [self updatePlayingState ];
373366}
374367
@@ -389,7 +382,7 @@ - (void)seekTo:(int)location {
389382 toleranceAfter: kCMTimeZero ];
390383}
391384
392- - (void )setIsLooping : (bool )isLooping {
385+ - (void )setIsLooping : (BOOL )isLooping {
393386 _isLooping = isLooping;
394387}
395388
@@ -457,22 +450,18 @@ - (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
457450// / is useful for the case where the Engine is in the process of deconstruction
458451// / so the channel is going to die or is already dead.
459452- (void )disposeSansEventChannel {
460- _disposed = true ;
453+ _disposed = YES ;
461454 [_displayLink invalidate ];
462- [[_player currentItem ] removeObserver: self forKeyPath: @" status" context: statusContext];
463- [[_player currentItem ] removeObserver: self
464- forKeyPath: @" loadedTimeRanges"
465- context: timeRangeContext];
466- [[_player currentItem ] removeObserver: self
467- forKeyPath: @" playbackLikelyToKeepUp"
468- context: playbackLikelyToKeepUpContext];
469- [[_player currentItem ] removeObserver: self
470- forKeyPath: @" playbackBufferEmpty"
471- context: playbackBufferEmptyContext];
472- [[_player currentItem ] removeObserver: self
473- forKeyPath: @" playbackBufferFull"
474- context: playbackBufferFullContext];
475- [_player replaceCurrentItemWithPlayerItem: nil ];
455+ AVPlayerItem* currentItem = self.player .currentItem ;
456+ [currentItem removeObserver: self forKeyPath: @" status" ];
457+ [currentItem removeObserver: self forKeyPath: @" loadedTimeRanges" ];
458+ [currentItem removeObserver: self forKeyPath: @" presentationSize" ];
459+ [currentItem removeObserver: self forKeyPath: @" duration" ];
460+ [currentItem removeObserver: self forKeyPath: @" playbackLikelyToKeepUp" ];
461+ [currentItem removeObserver: self forKeyPath: @" playbackBufferEmpty" ];
462+ [currentItem removeObserver: self forKeyPath: @" playbackBufferFull" ];
463+
464+ [self .player replaceCurrentItemWithPlayerItem: nil ];
476465 [[NSNotificationCenter defaultCenter ] removeObserver: self ];
477466}
478467
@@ -486,7 +475,8 @@ - (void)dispose {
486475@interface FLTVideoPlayerPlugin () <FLTVideoPlayerApi>
487476@property (readonly , weak , nonatomic ) NSObject <FlutterTextureRegistry>* registry;
488477@property (readonly , weak , nonatomic ) NSObject <FlutterBinaryMessenger>* messenger;
489- @property (readonly , strong , nonatomic ) NSMutableDictionary * players;
478+ @property (readonly , strong , nonatomic )
479+ NSMutableDictionary <NSNumber*, FLTVideoPlayer*>* playersByTextureId;
490480@property (readonly , strong , nonatomic ) NSObject <FlutterPluginRegistrar>* registrar;
491481@end
492482
@@ -503,16 +493,13 @@ - (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
503493 _registry = [registrar textures ];
504494 _messenger = [registrar messenger ];
505495 _registrar = registrar;
506- _players = [NSMutableDictionary dictionaryWithCapacity: 1 ];
496+ _playersByTextureId = [NSMutableDictionary dictionaryWithCapacity: 1 ];
507497 return self;
508498}
509499
510500- (void )detachFromEngineForRegistrar : (NSObject <FlutterPluginRegistrar>*)registrar {
511- for (NSNumber * textureId in _players.allKeys ) {
512- FLTVideoPlayer* player = _players[textureId];
513- [player disposeSansEventChannel ];
514- }
515- [_players removeAllObjects ];
501+ [self .playersByTextureId.allValues makeObjectsPerformSelector: @selector (disposeSansEventChannel )];
502+ [self .playersByTextureId removeAllObjects ];
516503 // TODO(57151): This should be commented out when 57151's fix lands on stable.
517504 // This is the correct behavior we never did it in the past and the engine
518505 // doesn't currently support it.
@@ -521,15 +508,15 @@ - (void)detachFromEngineForRegistrar:(NSObject<FlutterPluginRegistrar>*)registra
521508
522509- (FLTTextureMessage*)onPlayerSetup : (FLTVideoPlayer*)player
523510 frameUpdater : (FLTFrameUpdater*)frameUpdater {
524- int64_t textureId = [_registry registerTexture: player];
511+ int64_t textureId = [self .registry registerTexture: player];
525512 frameUpdater.textureId = textureId;
526513 FlutterEventChannel* eventChannel = [FlutterEventChannel
527514 eventChannelWithName: [NSString stringWithFormat: @" flutter.io/videoPlayer/videoEvents%lld " ,
528515 textureId]
529516 binaryMessenger: _messenger];
530517 [eventChannel setStreamHandler: player];
531518 player.eventChannel = eventChannel;
532- _players [@(textureId)] = player;
519+ self. playersByTextureId [@(textureId)] = player;
533520 FLTTextureMessage* result = [[FLTTextureMessage alloc ] init ];
534521 result.textureId = @(textureId);
535522 return result;
@@ -539,11 +526,12 @@ - (void)initialize:(FlutterError* __autoreleasing*)error {
539526 // Allow audio playback when the Ring/Silent switch is set to silent
540527 [[AVAudioSession sharedInstance ] setCategory: AVAudioSessionCategoryPlayback error: nil ];
541528
542- for (NSNumber * textureId in _players) {
543- [_registry unregisterTexture: [textureId unsignedIntegerValue ]];
544- [_players[textureId] dispose ];
545- }
546- [_players removeAllObjects ];
529+ [self .playersByTextureId
530+ enumerateKeysAndObjectsUsingBlock: ^(NSNumber * textureId, FLTVideoPlayer* player, BOOL * stop) {
531+ [self .registry unregisterTexture: textureId.unsignedIntegerValue];
532+ [player dispose ];
533+ }];
534+ [self .playersByTextureId removeAllObjects ];
547535}
548536
549537- (FLTTextureMessage*)create : (FLTCreateMessage*)input error : (FlutterError**)error {
@@ -570,9 +558,9 @@ - (FLTTextureMessage*)create:(FLTCreateMessage*)input error:(FlutterError**)erro
570558}
571559
572560- (void )dispose : (FLTTextureMessage*)input error : (FlutterError**)error {
573- FLTVideoPlayer* player = _players [input.textureId];
574- [_registry unregisterTexture: input.textureId.intValue];
575- [_players removeObjectForKey: input.textureId];
561+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
562+ [self .registry unregisterTexture: input.textureId.intValue];
563+ [self .playersByTextureId removeObjectForKey: input.textureId];
576564 // If the Flutter contains https://github.com/flutter/engine/pull/12695,
577565 // the `player` is disposed via `onTextureUnregistered` at the right time.
578566 // Without https://github.com/flutter/engine/pull/12695, there is no guarantee that the
@@ -592,46 +580,46 @@ - (void)dispose:(FLTTextureMessage*)input error:(FlutterError**)error {
592580}
593581
594582- (void )setLooping : (FLTLoopingMessage*)input error : (FlutterError**)error {
595- FLTVideoPlayer* player = _players [input.textureId];
596- [ player setIsLooping: [ input.isLooping boolValue ]] ;
583+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
584+ player. isLooping = input.isLooping . boolValue ;
597585}
598586
599587- (void )setVolume : (FLTVolumeMessage*)input error : (FlutterError**)error {
600- FLTVideoPlayer* player = _players [input.textureId];
601- [player setVolume: [ input.volume doubleValue ] ];
588+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
589+ [player setVolume: input.volume. doubleValue];
602590}
603591
604592- (void )setPlaybackSpeed : (FLTPlaybackSpeedMessage*)input error : (FlutterError**)error {
605- FLTVideoPlayer* player = _players [input.textureId];
606- [player setPlaybackSpeed: [ input.speed doubleValue ] ];
593+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
594+ [player setPlaybackSpeed: input.speed. doubleValue];
607595}
608596
609597- (void )play : (FLTTextureMessage*)input error : (FlutterError**)error {
610- FLTVideoPlayer* player = _players [input.textureId];
598+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
611599 [player play ];
612600}
613601
614602- (FLTPositionMessage*)position : (FLTTextureMessage*)input error : (FlutterError**)error {
615- FLTVideoPlayer* player = _players [input.textureId];
603+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
616604 FLTPositionMessage* result = [[FLTPositionMessage alloc ] init ];
617605 result.position = @([player position ]);
618606 return result;
619607}
620608
621609- (void )seekTo : (FLTPositionMessage*)input error : (FlutterError**)error {
622- FLTVideoPlayer* player = _players [input.textureId];
623- [player seekTo: [ input.position intValue ] ];
624- [_registry textureFrameAvailable: input.textureId.intValue];
610+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
611+ [player seekTo: input.position. intValue];
612+ [self .registry textureFrameAvailable: input.textureId.intValue];
625613}
626614
627615- (void )pause : (FLTTextureMessage*)input error : (FlutterError**)error {
628- FLTVideoPlayer* player = _players [input.textureId];
616+ FLTVideoPlayer* player = self. playersByTextureId [input.textureId];
629617 [player pause ];
630618}
631619
632620- (void )setMixWithOthers : (FLTMixWithOthersMessage*)input
633621 error : (FlutterError* _Nullable __autoreleasing*)error {
634- if ([ input.mixWithOthers boolValue ] ) {
622+ if (input.mixWithOthers . boolValue ) {
635623 [[AVAudioSession sharedInstance ] setCategory: AVAudioSessionCategoryPlayback
636624 withOptions: AVAudioSessionCategoryOptionMixWithOthers
637625 error: nil ];
0 commit comments