diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md index b069183f6aa..bccc6346903 100644 --- a/packages/video_player/video_player_avfoundation/CHANGELOG.md +++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.8.0 + +* Adds platform view support for macOS. + ## 2.7.3 * Restructures the communication between Dart and native code. diff --git a/packages/video_player/video_player_avfoundation/README.md b/packages/video_player/video_player_avfoundation/README.md index f46470ee2f5..1325daf0acf 100644 --- a/packages/video_player/video_player_avfoundation/README.md +++ b/packages/video_player/video_player_avfoundation/README.md @@ -13,7 +13,3 @@ should add it to your `pubspec.yaml` as usual. [1]: https://pub.dev/packages/video_player [2]: https://flutter.dev/to/endorsed-federated-plugin - -## Platform limitations - -On macOS, the plugin does not currently support platform views. Instead, a texture view is always used to display the video player, even if `VideoViewType.platformView` is specified as a parameter. \ No newline at end of file diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.m b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.m index 9a912db66d6..0dd84c55149 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.m +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.m @@ -8,13 +8,10 @@ #import #import +#import #import #import -#if TARGET_OS_IOS -#import -#endif - #if TARGET_OS_IOS @interface FakeAVAssetTrack : AVAssetTrack @property(readonly, nonatomic) CGAffineTransform preferredTransform; @@ -801,7 +798,6 @@ - (void)testHotReloadDoesNotCrash { handler:nil]; // No assertions needed. Lack of crash is a success. } -#if TARGET_OS_IOS - (void)testNativeVideoViewFactoryRegistration { NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); @@ -811,7 +807,6 @@ - (void)testNativeVideoViewFactoryRegistration { OCMVerifyAll(registrar); } -#endif - (void)testPublishesInRegistration { NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoViewFactory.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPNativeVideoViewFactory.m similarity index 88% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoViewFactory.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPNativeVideoViewFactory.m index 94ece09e11e..9314dda9d06 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoViewFactory.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPNativeVideoViewFactory.m @@ -25,9 +25,16 @@ - (instancetype)initWithMessenger:(NSObject *)messenger return self; } +#pragma mark - FlutterPlatformViewFactory + +#if TARGET_OS_OSX +- (NSView *)createWithViewIdentifier:(int64_t)viewIdentifier + arguments:(FVPPlatformVideoViewCreationParams *)args { +#else - (NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewIdentifier arguments:(FVPPlatformVideoViewCreationParams *)args { +#endif NSNumber *playerIdentifier = @(args.playerId); FVPVideoPlayer *player = self.playerByIdProvider(playerIdentifier); return [[FVPNativeVideoView alloc] initWithPlayer:player.player]; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayerPlugin.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayerPlugin.m index e73c80191cb..114bba8552a 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayerPlugin.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayerPlugin.m @@ -10,17 +10,13 @@ #import "./include/video_player_avfoundation/FVPAVFactory.h" #import "./include/video_player_avfoundation/FVPDisplayLink.h" #import "./include/video_player_avfoundation/FVPFrameUpdater.h" +#import "./include/video_player_avfoundation/FVPNativeVideoViewFactory.h" #import "./include/video_player_avfoundation/FVPTextureBasedVideoPlayer.h" #import "./include/video_player_avfoundation/FVPVideoPlayer.h" // Relative path is needed for messages.g.h. See // https://github.com/flutter/packages/pull/6675/#discussion_r1591210702 #import "./include/video_player_avfoundation/messages.g.h" -#if TARGET_OS_IOS -// Platform views are only supported on iOS as of now. -#import "./include/video_player_avfoundation/FVPNativeVideoViewFactory.h" -#endif - #if !__has_feature(objc_arc) #error Code Requires ARC. #endif @@ -61,15 +57,12 @@ @implementation FVPVideoPlayerPlugin + (void)registerWithRegistrar:(NSObject *)registrar { FVPVideoPlayerPlugin *instance = [[FVPVideoPlayerPlugin alloc] initWithRegistrar:registrar]; [registrar publish:instance]; -#if TARGET_OS_IOS - // Platform views are only supported on iOS as of now. FVPNativeVideoViewFactory *factory = [[FVPNativeVideoViewFactory alloc] initWithMessenger:registrar.messenger playerByIdentifierProvider:^FVPVideoPlayer *(NSNumber *playerIdentifier) { return instance->_playersByIdentifier[playerIdentifier]; }]; [registrar registerViewFactory:factory withId:@"plugins.flutter.dev/video_player_ios"]; -#endif SetUpFVPAVFoundationVideoPlayerApi(registrar.messenger, instance); } diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h index f05ebccf991..b974f10af03 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Platform views are only supported on iOS as of now. Ifdefs are used to avoid compilation errors. - #import #if TARGET_OS_OSX diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoViewFactory.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoViewFactory.h index 2872bebdfcf..df9c403b434 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoViewFactory.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoViewFactory.h @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Platform views are only supported on iOS as of now. Ifdef is used to avoid compilation errors. - #import #import "FVPVideoPlayer.h" diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPNativeVideoView.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPNativeVideoView.m new file mode 100644 index 00000000000..466ef06f549 --- /dev/null +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPNativeVideoView.m @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "../video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h" + +#import +#import + +@implementation FVPNativeVideoView + +- (instancetype)initWithPlayer:(AVPlayer *)player { + self = [super init]; + if (self) { + self.wantsLayer = YES; + ((AVPlayerLayer *)self.layer).player = player; + } + return self; +} + +- (CALayer *)makeBackingLayer { + return [[AVPlayerLayer alloc] init]; +} + +@end diff --git a/packages/video_player/video_player_avfoundation/example/lib/main.dart b/packages/video_player/video_player_avfoundation/example/lib/main.dart index 6fc41eca1b9..f98516b2003 100644 --- a/packages/video_player/video_player_avfoundation/example/lib/main.dart +++ b/packages/video_player/video_player_avfoundation/example/lib/main.dart @@ -4,8 +4,6 @@ // ignore_for_file: public_member_api_docs -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; @@ -44,27 +42,20 @@ class _App extends StatelessWidget { ), ), body: TabBarView( - children: Platform.isIOS - ? [ - _ViewTypeTabBar( - builder: (VideoViewType viewType) => - _BumbleBeeRemoteVideo(viewType), - ), - _ViewTypeTabBar( - builder: (VideoViewType viewType) => - _BumbleBeeEncryptedLiveStream(viewType), - ), - _ViewTypeTabBar( - builder: (VideoViewType viewType) => - _ButterFlyAssetVideo(viewType), - ), - ] - // Platform views are only supported on iOS as of now. - : const [ - _BumbleBeeRemoteVideo(VideoViewType.textureView), - _BumbleBeeEncryptedLiveStream(VideoViewType.textureView), - _ButterFlyAssetVideo(VideoViewType.textureView), - ], + children: [ + _ViewTypeTabBar( + builder: (VideoViewType viewType) => + _BumbleBeeRemoteVideo(viewType), + ), + _ViewTypeTabBar( + builder: (VideoViewType viewType) => + _BumbleBeeEncryptedLiveStream(viewType), + ), + _ViewTypeTabBar( + builder: (VideoViewType viewType) => + _ButterFlyAssetVideo(viewType), + ), + ], ), ), ); diff --git a/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart b/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart index a991e3e594c..bd89408eeb7 100644 --- a/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart +++ b/packages/video_player/video_player_avfoundation/lib/src/avfoundation_video_player.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; @@ -73,10 +72,7 @@ class AVFoundationVideoPlayer extends VideoPlayerPlatform { @override Future createWithOptions(VideoCreationOptions options) async { final DataSource dataSource = options.dataSource; - // Platform views are not supported on macOS yet. Use texture view instead. - final VideoViewType viewType = defaultTargetPlatform == TargetPlatform.macOS - ? VideoViewType.textureView - : options.viewType; + final VideoViewType viewType = options.viewType; String? asset; String? packageName; diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index 89bc263053a..1482e8a5457 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_avfoundation description: iOS and macOS implementation of the video_player plugin. repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22 -version: 2.7.3 +version: 2.8.0 environment: sdk: ^3.6.0 diff --git a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart index 9e62654ebf5..6862e999616 100644 --- a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart +++ b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; @@ -293,8 +292,7 @@ void main() { const VideoPlayerTextureViewState(textureId: newPlayerId)); }); - test('createWithOptions with platform view on iOS', () async { - debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + test('createWithOptions with platform view', () async { final ( AVFoundationVideoPlayer player, MockAVFoundationVideoPlayerApi api, @@ -322,36 +320,6 @@ void main() { const VideoPlayerPlatformViewState()); }); - test('createWithOptions with platform view uses texture view on MacOS', - () async { - debugDefaultTargetPlatformOverride = TargetPlatform.macOS; - final ( - AVFoundationVideoPlayer player, - MockAVFoundationVideoPlayerApi api, - _, - ) = setUpMockPlayer(playerId: 1); - const int newPlayerId = 2; - when(api.create(any)).thenAnswer((_) async => newPlayerId); - - final int? playerId = await player.createWithOptions( - VideoCreationOptions( - dataSource: DataSource( - sourceType: DataSourceType.file, - uri: 'file:///foo/bar', - ), - viewType: VideoViewType.platformView, - ), - ); - - final VerificationResult verification = verify(api.create(captureAny)); - final CreationOptions creationOptions = - verification.captured[0] as CreationOptions; - expect(creationOptions.viewType, PlatformVideoViewType.textureView); - expect(playerId, newPlayerId); - expect(player.playerViewStates[newPlayerId], - const VideoPlayerTextureViewState(textureId: newPlayerId)); - }); - test('setLooping', () async { final ( AVFoundationVideoPlayer player,