Skip to content

Commit

Permalink
[video_player] Update iOS prefixes (flutter#4994)
Browse files Browse the repository at this point in the history
Renames all classes and stand-alone functions to use the `FVP` prefix instead of `FLT`.

Because ollyde/flutter_macos_video_player#9 was never fixed, there are projects in the wild using macOS classes with all of the same names as our classes, but with different implementation/behavior. If we add macOS support to the plugin as-is, developers using that package will end up with two copies of classes with the same name, which has undefined behavior at runtime in Obj-C (and in this case would very likely result in exceptions and/or crashes).

While a third-party should never have published code using the Flutter team's code prefixes, since we wanted to change prefixes anyway we can do so before adding macOS support and just avoid the issue entirely.

Since this involved regenerating Pigeon anyway, this also includes a Pigeon update.

Part of flutter#102601
  • Loading branch information
stuartmorgan authored Sep 26, 2023
1 parent 32c0b3a commit 63daefb
Show file tree
Hide file tree
Showing 13 changed files with 378 additions and 337 deletions.
5 changes: 5 additions & 0 deletions packages/video_player/video_player_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.4.11

* Updates Pigeon.
* Changes Objective-C class prefixes to avoid future collisions.

## 2.4.10

* Adds pub topics to package metadata.
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
* Note: https://stackoverflow.com/questions/64161544
* `AVAssetTrack.preferredTransform` can have wrong `tx` and `ty`.
*/
CGAffineTransform FLTGetStandardizedTransformForTrack(AVAssetTrack* track);
CGAffineTransform FVPGetStandardizedTransformForTrack(AVAssetTrack* track);
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#import <AVFoundation/AVFoundation.h>

CGAffineTransform FLTGetStandardizedTransformForTrack(AVAssetTrack *track) {
CGAffineTransform FVPGetStandardizedTransformForTrack(AVAssetTrack *track) {
CGAffineTransform t = track.preferredTransform;
CGSize size = track.naturalSize;
// Each case of control flows corresponds to a specific
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

#import <Flutter/Flutter.h>

@interface FLTVideoPlayerPlugin : NSObject <FlutterPlugin>
@interface FVPVideoPlayerPlugin : NSObject <FlutterPlugin>
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar;
@end
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "FLTVideoPlayerPlugin.h"
#import "FLTVideoPlayerPlugin_Test.h"
#import "FVPVideoPlayerPlugin.h"
#import "FVPVideoPlayerPlugin_Test.h"

#import <AVFoundation/AVFoundation.h>
#import <GLKit/GLKit.h>
Expand All @@ -15,14 +15,14 @@
#error Code Requires ARC.
#endif

@interface FLTFrameUpdater : NSObject
@interface FVPFrameUpdater : NSObject
@property(nonatomic) int64_t textureId;
@property(nonatomic, weak, readonly) NSObject<FlutterTextureRegistry> *registry;
- (void)onDisplayLink:(CADisplayLink *)link;
@end

@implementation FLTFrameUpdater
- (FLTFrameUpdater *)initWithRegistry:(NSObject<FlutterTextureRegistry> *)registry {
@implementation FVPFrameUpdater
- (FVPFrameUpdater *)initWithRegistry:(NSObject<FlutterTextureRegistry> *)registry {
NSAssert(self, @"super init cannot be nil");
if (self == nil) return nil;
_registry = registry;
Expand All @@ -44,7 +44,7 @@ - (AVPlayer *)playerWithPlayerItem:(AVPlayerItem *)playerItem {

@end

@interface FLTVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
@interface FVPVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
@property(readonly, nonatomic) AVPlayer *player;
@property(readonly, nonatomic) AVPlayerItemVideoOutput *videoOutput;
// This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
Expand All @@ -62,7 +62,7 @@ @interface FLTVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
@property(nonatomic) BOOL isLooping;
@property(nonatomic, readonly) BOOL isInitialized;
- (instancetype)initWithURL:(NSURL *)url
frameUpdater:(FLTFrameUpdater *)frameUpdater
frameUpdater:(FVPFrameUpdater *)frameUpdater
httpHeaders:(nonnull NSDictionary<NSString *, NSString *> *)headers
playerFactory:(id<FVPPlayerFactory>)playerFactory;
@end
Expand All @@ -74,9 +74,9 @@ - (instancetype)initWithURL:(NSURL *)url
static void *playbackLikelyToKeepUpContext = &playbackLikelyToKeepUpContext;
static void *rateContext = &rateContext;

@implementation FLTVideoPlayer
@implementation FVPVideoPlayer
- (instancetype)initWithAsset:(NSString *)asset
frameUpdater:(FLTFrameUpdater *)frameUpdater
frameUpdater:(FVPFrameUpdater *)frameUpdater
playerFactory:(id<FVPPlayerFactory>)playerFactory {
NSString *path = [[NSBundle mainBundle] pathForResource:asset ofType:nil];
return [self initWithURL:[NSURL fileURLWithPath:path]
Expand Down Expand Up @@ -134,7 +134,7 @@ - (void)itemDidPlayToEndTime:(NSNotification *)notification {

const int64_t TIME_UNSET = -9223372036854775807;

NS_INLINE int64_t FLTCMTimeToMillis(CMTime time) {
NS_INLINE int64_t FVPCMTimeToMillis(CMTime time) {
// When CMTIME_IS_INDEFINITE return a value that matches TIME_UNSET from ExoPlayer2 on Android.
// Fixes https://github.com/flutter/flutter/issues/48670
if (CMTIME_IS_INDEFINITE(time)) return TIME_UNSET;
Expand Down Expand Up @@ -195,7 +195,7 @@ - (AVMutableVideoComposition *)getVideoCompositionWithTransform:(CGAffineTransfo
return videoComposition;
}

- (void)createVideoOutputAndDisplayLink:(FLTFrameUpdater *)frameUpdater {
- (void)createVideoOutputAndDisplayLink:(FVPFrameUpdater *)frameUpdater {
NSDictionary *pixBuffAttributes = @{
(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA),
(id)kCVPixelBufferIOSurfacePropertiesKey : @{}
Expand All @@ -209,7 +209,7 @@ - (void)createVideoOutputAndDisplayLink:(FLTFrameUpdater *)frameUpdater {
}

- (instancetype)initWithURL:(NSURL *)url
frameUpdater:(FLTFrameUpdater *)frameUpdater
frameUpdater:(FVPFrameUpdater *)frameUpdater
httpHeaders:(nonnull NSDictionary<NSString *, NSString *> *)headers
playerFactory:(id<FVPPlayerFactory>)playerFactory {
NSDictionary<NSString *, id> *options = nil;
Expand All @@ -222,7 +222,7 @@ - (instancetype)initWithURL:(NSURL *)url
}

- (instancetype)initWithPlayerItem:(AVPlayerItem *)item
frameUpdater:(FLTFrameUpdater *)frameUpdater
frameUpdater:(FVPFrameUpdater *)frameUpdater
playerFactory:(id<FVPPlayerFactory>)playerFactory {
self = [super init];
NSAssert(self, @"super init cannot be nil");
Expand All @@ -238,7 +238,7 @@ - (instancetype)initWithPlayerItem:(AVPlayerItem *)item
if ([videoTrack statusOfValueForKey:@"preferredTransform"
error:nil] == AVKeyValueStatusLoaded) {
// Rotate the video by using a videoComposition and the preferredTransform
self->_preferredTransform = FLTGetStandardizedTransformForTrack(videoTrack);
self->_preferredTransform = FVPGetStandardizedTransformForTrack(videoTrack);
// Note:
// https://developer.apple.com/documentation/avfoundation/avplayeritem/1388818-videocomposition
// Video composition can only be used with file-based media and is not supported for
Expand Down Expand Up @@ -285,8 +285,8 @@ - (void)observeValueForKeyPath:(NSString *)path
NSMutableArray<NSArray<NSNumber *> *> *values = [[NSMutableArray alloc] init];
for (NSValue *rangeValue in [object loadedTimeRanges]) {
CMTimeRange range = [rangeValue CMTimeRangeValue];
int64_t start = FLTCMTimeToMillis(range.start);
[values addObject:@[ @(start), @(start + FLTCMTimeToMillis(range.duration)) ]];
int64_t start = FVPCMTimeToMillis(range.start);
[values addObject:@[ @(start), @(start + FVPCMTimeToMillis(range.duration)) ]];
}
_eventSink(@{@"event" : @"bufferingUpdate", @"values" : values});
}
Expand Down Expand Up @@ -414,14 +414,14 @@ - (void)pause {
}

- (int64_t)position {
return FLTCMTimeToMillis([_player currentTime]);
return FVPCMTimeToMillis([_player currentTime]);
}

- (int64_t)duration {
// Note: https://openradar.appspot.com/radar?id=4968600712511488
// `[AVPlayerItem duration]` can be `kCMTimeIndefinite`,
// use `[[AVPlayerItem asset] duration]` instead.
return FLTCMTimeToMillis([[[_player currentItem] asset] duration]);
return FVPCMTimeToMillis([[[_player currentItem] asset] duration]);
}

- (void)seekTo:(int)location completionHandler:(void (^)(BOOL))completionHandler {
Expand Down Expand Up @@ -507,8 +507,8 @@ - (FlutterError *_Nullable)onListenWithArguments:(id _Nullable)arguments
- (void)disposeSansEventChannel {
// This check prevents the crash caused by removing the KVO observers twice.
// When performing a Hot Restart, the leftover players are disposed once directly
// by [FLTVideoPlayerPlugin initialize:] method and then disposed again by
// [FLTVideoPlayer onTextureUnregistered:] call leading to possible over-release.
// by [FVPVideoPlayerPlugin initialize:] method and then disposed again by
// [FVPVideoPlayer onTextureUnregistered:] call leading to possible over-release.
if (_disposed) {
return;
}
Expand All @@ -535,20 +535,20 @@ - (void)dispose {

@end

@interface FLTVideoPlayerPlugin () <FLTAVFoundationVideoPlayerApi>
@interface FVPVideoPlayerPlugin () <FVPAVFoundationVideoPlayerApi>
@property(readonly, weak, nonatomic) NSObject<FlutterTextureRegistry> *registry;
@property(readonly, weak, nonatomic) NSObject<FlutterBinaryMessenger> *messenger;
@property(readonly, strong, nonatomic)
NSMutableDictionary<NSNumber *, FLTVideoPlayer *> *playersByTextureId;
NSMutableDictionary<NSNumber *, FVPVideoPlayer *> *playersByTextureId;
@property(readonly, strong, nonatomic) NSObject<FlutterPluginRegistrar> *registrar;
@property(nonatomic, strong) id<FVPPlayerFactory> playerFactory;
@end

@implementation FLTVideoPlayerPlugin
@implementation FVPVideoPlayerPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
FLTVideoPlayerPlugin *instance = [[FLTVideoPlayerPlugin alloc] initWithRegistrar:registrar];
FVPVideoPlayerPlugin *instance = [[FVPVideoPlayerPlugin alloc] initWithRegistrar:registrar];
[registrar publish:instance];
FLTAVFoundationVideoPlayerApiSetup(registrar.messenger, instance);
FVPAVFoundationVideoPlayerApiSetup(registrar.messenger, instance);
}

- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
Expand All @@ -573,11 +573,11 @@ - (void)detachFromEngineForRegistrar:(NSObject<FlutterPluginRegistrar> *)registr
// TODO(57151): This should be commented out when 57151's fix lands on stable.
// This is the correct behavior we never did it in the past and the engine
// doesn't currently support it.
// FLTAVFoundationVideoPlayerApiSetup(registrar.messenger, nil);
// FVPAVFoundationVideoPlayerApiSetup(registrar.messenger, nil);
}

- (FLTTextureMessage *)onPlayerSetup:(FLTVideoPlayer *)player
frameUpdater:(FLTFrameUpdater *)frameUpdater {
- (FVPTextureMessage *)onPlayerSetup:(FVPVideoPlayer *)player
frameUpdater:(FVPFrameUpdater *)frameUpdater {
int64_t textureId = [self.registry registerTexture:player];
frameUpdater.textureId = textureId;
FlutterEventChannel *eventChannel = [FlutterEventChannel
Expand All @@ -587,7 +587,7 @@ - (FLTTextureMessage *)onPlayerSetup:(FLTVideoPlayer *)player
[eventChannel setStreamHandler:player];
player.eventChannel = eventChannel;
self.playersByTextureId[@(textureId)] = player;
FLTTextureMessage *result = [FLTTextureMessage makeWithTextureId:@(textureId)];
FVPTextureMessage *result = [FVPTextureMessage makeWithTextureId:@(textureId)];
return result;
}

Expand All @@ -596,16 +596,16 @@ - (void)initialize:(FlutterError *__autoreleasing *)error {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

[self.playersByTextureId
enumerateKeysAndObjectsUsingBlock:^(NSNumber *textureId, FLTVideoPlayer *player, BOOL *stop) {
enumerateKeysAndObjectsUsingBlock:^(NSNumber *textureId, FVPVideoPlayer *player, BOOL *stop) {
[self.registry unregisterTexture:textureId.unsignedIntegerValue];
[player dispose];
}];
[self.playersByTextureId removeAllObjects];
}

- (FLTTextureMessage *)create:(FLTCreateMessage *)input error:(FlutterError **)error {
FLTFrameUpdater *frameUpdater = [[FLTFrameUpdater alloc] initWithRegistry:_registry];
FLTVideoPlayer *player;
- (FVPTextureMessage *)create:(FVPCreateMessage *)input error:(FlutterError **)error {
FVPFrameUpdater *frameUpdater = [[FVPFrameUpdater alloc] initWithRegistry:_registry];
FVPVideoPlayer *player;
if (input.asset) {
NSString *assetPath;
if (input.packageName) {
Expand All @@ -614,7 +614,7 @@ - (FLTTextureMessage *)create:(FLTCreateMessage *)input error:(FlutterError **)e
assetPath = [_registrar lookupKeyForAsset:input.asset];
}
@try {
player = [[FLTVideoPlayer alloc] initWithAsset:assetPath
player = [[FVPVideoPlayer alloc] initWithAsset:assetPath
frameUpdater:frameUpdater
playerFactory:_playerFactory];
return [self onPlayerSetup:player frameUpdater:frameUpdater];
Expand All @@ -623,7 +623,7 @@ - (FLTTextureMessage *)create:(FLTCreateMessage *)input error:(FlutterError **)e
return nil;
}
} else if (input.uri) {
player = [[FLTVideoPlayer alloc] initWithURL:[NSURL URLWithString:input.uri]
player = [[FVPVideoPlayer alloc] initWithURL:[NSURL URLWithString:input.uri]
frameUpdater:frameUpdater
httpHeaders:input.httpHeaders
playerFactory:_playerFactory];
Expand All @@ -634,8 +634,8 @@ - (FLTTextureMessage *)create:(FLTCreateMessage *)input error:(FlutterError **)e
}
}

- (void)dispose:(FLTTextureMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)dispose:(FVPTextureMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[self.registry unregisterTexture:input.textureId.intValue];
[self.playersByTextureId removeObjectForKey:input.textureId];
// If the Flutter contains https://github.com/flutter/engine/pull/12695,
Expand All @@ -656,36 +656,36 @@ - (void)dispose:(FLTTextureMessage *)input error:(FlutterError **)error {
});
}

- (void)setLooping:(FLTLoopingMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)setLooping:(FVPLoopingMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
player.isLooping = input.isLooping.boolValue;
}

- (void)setVolume:(FLTVolumeMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)setVolume:(FVPVolumeMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[player setVolume:input.volume.doubleValue];
}

- (void)setPlaybackSpeed:(FLTPlaybackSpeedMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)setPlaybackSpeed:(FVPPlaybackSpeedMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[player setPlaybackSpeed:input.speed.doubleValue];
}

- (void)play:(FLTTextureMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)play:(FVPTextureMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[player play];
}

- (FLTPositionMessage *)position:(FLTTextureMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
FLTPositionMessage *result = [FLTPositionMessage makeWithTextureId:input.textureId
- (FVPPositionMessage *)position:(FVPTextureMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
FVPPositionMessage *result = [FVPPositionMessage makeWithTextureId:input.textureId
position:@([player position])];
return result;
}

- (void)seekTo:(FLTPositionMessage *)input
- (void)seekTo:(FVPPositionMessage *)input
completion:(void (^)(FlutterError *_Nullable))completion {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[player seekTo:input.position.intValue
completionHandler:^(BOOL finished) {
dispatch_async(dispatch_get_main_queue(), ^{
Expand All @@ -695,12 +695,12 @@ - (void)seekTo:(FLTPositionMessage *)input
}];
}

- (void)pause:(FLTTextureMessage *)input error:(FlutterError **)error {
FLTVideoPlayer *player = self.playersByTextureId[input.textureId];
- (void)pause:(FVPTextureMessage *)input error:(FlutterError **)error {
FVPVideoPlayer *player = self.playersByTextureId[input.textureId];
[player pause];
}

- (void)setMixWithOthers:(FLTMixWithOthersMessage *)input
- (void)setMixWithOthers:(FVPMixWithOthersMessage *)input
error:(FlutterError *_Nullable __autoreleasing *)error {
if (input.mixWithOthers.boolValue) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "FLTVideoPlayerPlugin.h"
#import "FVPVideoPlayerPlugin.h"

#import <AVFoundation/AVFoundation.h>

Expand All @@ -11,7 +11,7 @@
- (AVPlayer *)playerWithPlayerItem:(AVPlayerItem *)playerItem;
@end

@interface FLTVideoPlayerPlugin ()
@interface FVPVideoPlayerPlugin ()

- (instancetype)initWithPlayerFactory:(id<FVPPlayerFactory>)playerFactory
registrar:(NSObject<FlutterPluginRegistrar> *)registrar;
Expand Down
Loading

0 comments on commit 63daefb

Please sign in to comment.