From fa0d181589afa7fbe03de560dd545032d2c2c8dd Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 24 Apr 2026 14:14:41 -0400 Subject: [PATCH 01/22] Restructure target layout --- .../video_player_avfoundation/Package.swift | 10 +++++++-- .../AVAssetTrackUtils.m | 0 .../FVPAVFactory.m | 2 +- .../FVPCADisplayLink.m | 0 .../FVPEventBridge.m | 2 +- .../FVPFrameUpdater.m | 2 +- .../FVPNativeVideoViewFactory.m | 0 .../FVPTextureBasedVideoPlayer.m | 4 ++-- .../FVPVideoPlayer.m | 6 ++--- .../FVPVideoPlayerPlugin.m | 22 +++++++++---------- .../FVPViewProvider.m | 2 +- .../AVAssetTrackUtils.h | 0 .../FVPAVFactory.h | 0 .../FVPAssetProvider.h | 0 .../FVPDisplayLink.h | 0 .../FVPEventBridge.h | 0 .../FVPFrameUpdater.h | 0 .../FVPNativeVideoView.h | 0 .../FVPNativeVideoViewFactory.h | 0 .../FVPTextureBasedVideoPlayer.h | 0 .../FVPTextureBasedVideoPlayer_Test.h | 0 .../FVPVideoEventListener.h | 0 .../FVPVideoPlayer.h | 0 .../FVPVideoPlayerPlugin.h | 0 .../FVPVideoPlayerPlugin_Test.h | 0 .../FVPVideoPlayer_Internal.h | 0 .../FVPViewProvider.h | 0 .../messages.g.h | 0 .../messages.g.m | 0 29 files changed, 28 insertions(+), 22 deletions(-) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/AVAssetTrackUtils.m (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPAVFactory.m (98%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPCADisplayLink.m (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPEventBridge.m (98%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPFrameUpdater.m (88%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPNativeVideoViewFactory.m (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPTextureBasedVideoPlayer.m (98%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPVideoPlayer.m (98%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPVideoPlayerPlugin.m (94%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/FVPViewProvider.m (91%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/AVAssetTrackUtils.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPAVFactory.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPAssetProvider.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPDisplayLink.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPEventBridge.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPFrameUpdater.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPNativeVideoView.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPNativeVideoViewFactory.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPTextureBasedVideoPlayer.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPTextureBasedVideoPlayer_Test.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPVideoEventListener.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPVideoPlayer.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPVideoPlayerPlugin.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPVideoPlayerPlugin_Test.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPVideoPlayer_Internal.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/FVPViewProvider.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation/include/video_player_avfoundation => video_player_avfoundation_objc/include/video_player_avfoundation_objc}/messages.g.h (100%) rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/{video_player_avfoundation => video_player_avfoundation_objc}/messages.g.m (100%) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift index 821310e0e12b..cd18e673fb75 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift @@ -20,11 +20,17 @@ let package = Package( .target( name: "video_player_avfoundation", dependencies: [ - .target(name: "video_player_avfoundation_ios", condition: .when(platforms: [.iOS])), - .target(name: "video_player_avfoundation_macos", condition: .when(platforms: [.macOS])), + "video_player_avfoundation_objc" ], resources: [ .process("Resources") + ] + ), + .target( + name: "video_player_avfoundation_objc", + dependencies: [ + .target(name: "video_player_avfoundation_ios", condition: .when(platforms: [.iOS])), + .target(name: "video_player_avfoundation_macos", condition: .when(platforms: [.macOS])), ], cSettings: [ .headerSearchPath("include/video_player_avfoundation") diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/AVAssetTrackUtils.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/AVAssetTrackUtils.m similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/AVAssetTrackUtils.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/AVAssetTrackUtils.m diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPAVFactory.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPAVFactory.m similarity index 98% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPAVFactory.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPAVFactory.m index 4cee990adb1f..4053bd0dbaae 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPAVFactory.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPAVFactory.m @@ -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 "./include/video_player_avfoundation/FVPAVFactory.h" +#import "./include/video_player_avfoundation_objc/FVPAVFactory.h" @import AVFoundation; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPCADisplayLink.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPCADisplayLink.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPEventBridge.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPEventBridge.m similarity index 98% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPEventBridge.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPEventBridge.m index 0df3569da9bd..ba8fd756e4f0 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPEventBridge.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPEventBridge.m @@ -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 "./include/video_player_avfoundation/FVPEventBridge.h" +#import "./include/video_player_avfoundation_objc/FVPEventBridge.h" @import Foundation; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPFrameUpdater.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPFrameUpdater.m similarity index 88% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPFrameUpdater.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPFrameUpdater.m index 0800cae41306..745010c8bcba 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPFrameUpdater.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPFrameUpdater.m @@ -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 "./include/video_player_avfoundation/FVPFrameUpdater.h" +#import "./include/video_player_avfoundation_objc/FVPFrameUpdater.h" @implementation FVPFrameUpdater - (FVPFrameUpdater *)initWithRegistry:(NSObject *)registry { diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPNativeVideoViewFactory.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPNativeVideoViewFactory.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPTextureBasedVideoPlayer.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.m similarity index 98% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPTextureBasedVideoPlayer.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.m index 1419da4d7743..ee5034d29cf9 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPTextureBasedVideoPlayer.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.m @@ -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 "./include/video_player_avfoundation/FVPTextureBasedVideoPlayer.h" -#import "./include/video_player_avfoundation/FVPTextureBasedVideoPlayer_Test.h" +#import "./include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.h" +#import "./include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer_Test.h" @interface FVPTextureBasedVideoPlayer () // The updater that drives callbacks to the engine to indicate that a new frame is ready. diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayer.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m similarity index 98% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayer.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m index 2270120378d5..04ce60e6a989 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayer.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayer.m @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "./include/video_player_avfoundation/FVPVideoPlayer.h" -#import "./include/video_player_avfoundation/FVPVideoPlayer_Internal.h" +#import "./include/video_player_avfoundation_objc/FVPVideoPlayer.h" +#import "./include/video_player_avfoundation_objc/FVPVideoPlayer_Internal.h" #import -#import "./include/video_player_avfoundation/AVAssetTrackUtils.h" +#import "./include/video_player_avfoundation_objc/AVAssetTrackUtils.h" static void *timeRangeContext = &timeRangeContext; static void *statusContext = &statusContext; 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_objc/FVPVideoPlayerPlugin.m similarity index 94% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPVideoPlayerPlugin.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayerPlugin.m index a420e8397401..a678657283e4 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_objc/FVPVideoPlayerPlugin.m @@ -2,22 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "./include/video_player_avfoundation/FVPVideoPlayerPlugin.h" -#import "./include/video_player_avfoundation/FVPVideoPlayerPlugin_Test.h" +#import "./include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h" +#import "./include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h" @import AVFoundation; -#import "./include/video_player_avfoundation/FVPAVFactory.h" -#import "./include/video_player_avfoundation/FVPAssetProvider.h" -#import "./include/video_player_avfoundation/FVPDisplayLink.h" -#import "./include/video_player_avfoundation/FVPEventBridge.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" +#import "./include/video_player_avfoundation_objc/FVPAVFactory.h" +#import "./include/video_player_avfoundation_objc/FVPAssetProvider.h" +#import "./include/video_player_avfoundation_objc/FVPDisplayLink.h" +#import "./include/video_player_avfoundation_objc/FVPEventBridge.h" +#import "./include/video_player_avfoundation_objc/FVPFrameUpdater.h" +#import "./include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h" +#import "./include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.h" +#import "./include/video_player_avfoundation_objc/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" +#import "./include/video_player_avfoundation_objc/messages.g.h" /// Non-test implementation of the diplay link factory. @interface FVPDefaultDisplayLinkFactory : NSObject diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPViewProvider.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPViewProvider.m similarity index 91% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPViewProvider.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPViewProvider.m index f72f86927cd8..d9ac02d1beeb 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPViewProvider.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPViewProvider.m @@ -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 "./include/video_player_avfoundation/FVPViewProvider.h" +#import "./include/video_player_avfoundation_objc/FVPViewProvider.h" #if TARGET_OS_OSX @import FlutterMacOS; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/AVAssetTrackUtils.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/AVAssetTrackUtils.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/AVAssetTrackUtils.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/AVAssetTrackUtils.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPAVFactory.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPAVFactory.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPAVFactory.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPAVFactory.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPAssetProvider.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPAssetProvider.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPAssetProvider.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPAssetProvider.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPDisplayLink.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPDisplayLink.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPEventBridge.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPEventBridge.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPFrameUpdater.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPFrameUpdater.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPFrameUpdater.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPFrameUpdater.h 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_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h 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_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoViewFactory.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPTextureBasedVideoPlayer.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPTextureBasedVideoPlayer.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPTextureBasedVideoPlayer_Test.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer_Test.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPTextureBasedVideoPlayer_Test.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer_Test.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoEventListener.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoEventListener.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayer.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayer.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayerPlugin.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayerPlugin.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayerPlugin_Test.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayerPlugin_Test.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayer_Internal.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer_Internal.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayer_Internal.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer_Internal.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPViewProvider.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPViewProvider.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPViewProvider.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPViewProvider.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/messages.g.m similarity index 100% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/messages.g.m From c0b50d04e7dd5fc8ea071b9d5f03be7a4f5975fd Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 24 Apr 2026 14:26:25 -0400 Subject: [PATCH 02/22] Split and regenerate Pigeon files --- .../VideoPlayerPluginMessages.g.swift | 440 +++++++++++ ...es.g.m => VideoPlayerInstanceMessages.g.m} | 400 ++++------ .../VideoPlayerInstanceMessages.g.h | 61 ++ .../lib/src/avfoundation_video_player.dart | 3 +- .../lib/src/messages.g.dart | 681 ------------------ .../src/video_player_instance_messages.g.dart | 405 +++++++++++ .../src/video_player_plugin_messages.g.dart | 377 ++++++++++ ...rt => video_player_instance_messages.dart} | 49 +- .../pigeons/video_player_plugin_messages.dart | 52 ++ .../video_player_avfoundation/pubspec.yaml | 2 +- .../test/avfoundation_video_player_test.dart | 3 +- .../avfoundation_video_player_test.mocks.dart | 32 +- 12 files changed, 1515 insertions(+), 990 deletions(-) create mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPluginMessages.g.swift rename packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/{messages.g.m => VideoPlayerInstanceMessages.g.m} (54%) create mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h delete mode 100644 packages/video_player/video_player_avfoundation/lib/src/messages.g.dart create mode 100644 packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart create mode 100644 packages/video_player/video_player_avfoundation/lib/src/video_player_plugin_messages.g.dart rename packages/video_player/video_player_avfoundation/pigeons/{messages.dart => video_player_instance_messages.dart} (51%) create mode 100644 packages/video_player/video_player_avfoundation/pigeons/video_player_plugin_messages.dart diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPluginMessages.g.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPluginMessages.g.swift new file mode 100644 index 000000000000..3cd23143abc7 --- /dev/null +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPluginMessages.g.swift @@ -0,0 +1,440 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Error class for passing custom error details to Dart side. +final class PigeonError: Error { + let code: String + let message: String? + let details: Sendable? + + init(code: String, message: String?, details: Sendable?) { + self.code = code + self.message = message + self.details = details + } + + var localizedDescription: String { + return + "PigeonError(code: \(code), message: \(message ?? ""), details: \(details ?? "")" + } +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(Swift.type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +private func doubleEqualsVideoPlayerPluginMessages(_ lhs: Double, _ rhs: Double) -> Bool { + return (lhs.isNaN && rhs.isNaN) || lhs == rhs +} + +private func doubleHashVideoPlayerPluginMessages(_ value: Double, _ hasher: inout Hasher) { + if value.isNaN { + hasher.combine(0x7FF8_0000_0000_0000) + } else { + // Normalize -0.0 to 0.0 + hasher.combine(value == 0 ? 0 : value) + } +} + +func deepEqualsVideoPlayerPluginMessages(_ lhs: Any?, _ rhs: Any?) -> Bool { + let cleanLhs = nilOrValue(lhs) as Any? + let cleanRhs = nilOrValue(rhs) as Any? + switch (cleanLhs, cleanRhs) { + case (nil, nil): + return true + + case (nil, _), (_, nil): + return false + + case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs: + return true + + case is (Void, Void): + return true + + case (let lhsArray, let rhsArray) as ([Any?], [Any?]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !deepEqualsVideoPlayerPluginMessages(element, rhsArray[index]) { + return false + } + } + return true + + case (let lhsArray, let rhsArray) as ([Double], [Double]): + guard lhsArray.count == rhsArray.count else { return false } + for (index, element) in lhsArray.enumerated() { + if !doubleEqualsVideoPlayerPluginMessages(element, rhsArray[index]) { + return false + } + } + return true + + case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]): + guard lhsDictionary.count == rhsDictionary.count else { return false } + for (lhsKey, lhsValue) in lhsDictionary { + var found = false + for (rhsKey, rhsValue) in rhsDictionary { + if deepEqualsVideoPlayerPluginMessages(lhsKey, rhsKey) { + if deepEqualsVideoPlayerPluginMessages(lhsValue, rhsValue) { + found = true + break + } else { + return false + } + } + } + if !found { return false } + } + return true + + case (let lhs as Double, let rhs as Double): + return doubleEqualsVideoPlayerPluginMessages(lhs, rhs) + + case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable): + return lhsHashable == rhsHashable + + default: + return false + } +} + +func deepHashVideoPlayerPluginMessages(value: Any?, hasher: inout Hasher) { + let cleanValue = nilOrValue(value) as Any? + if let cleanValue = cleanValue { + if let doubleValue = cleanValue as? Double { + doubleHashVideoPlayerPluginMessages(doubleValue, &hasher) + } else if let valueList = cleanValue as? [Any?] { + for item in valueList { + deepHashVideoPlayerPluginMessages(value: item, hasher: &hasher) + } + } else if let valueList = cleanValue as? [Double] { + for item in valueList { + doubleHashVideoPlayerPluginMessages(item, &hasher) + } + } else if let valueDict = cleanValue as? [AnyHashable: Any?] { + var result = 0 + for (key, value) in valueDict { + var entryKeyHasher = Hasher() + deepHashVideoPlayerPluginMessages(value: key, hasher: &entryKeyHasher) + var entryValueHasher = Hasher() + deepHashVideoPlayerPluginMessages(value: value, hasher: &entryValueHasher) + result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize()) + } + hasher.combine(result) + } else if let hashableValue = cleanValue as? AnyHashable { + hasher.combine(hashableValue) + } else { + hasher.combine(String(describing: cleanValue)) + } + } else { + hasher.combine(0) + } +} + +/// Information passed to the platform view creation. +/// +/// Generated class from Pigeon that represents data sent in messages. +struct PlatformVideoViewCreationParams: Hashable { + var playerId: Int64 + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> PlatformVideoViewCreationParams? { + let playerId = pigeonVar_list[0] as! Int64 + + return PlatformVideoViewCreationParams( + playerId: playerId + ) + } + func toList() -> [Any?] { + return [ + playerId + ] + } + static func == (lhs: PlatformVideoViewCreationParams, rhs: PlatformVideoViewCreationParams) + -> Bool + { + if Swift.type(of: lhs) != Swift.type(of: rhs) { + return false + } + return deepEqualsVideoPlayerPluginMessages(lhs.playerId, rhs.playerId) + } + + func hash(into hasher: inout Hasher) { + hasher.combine("PlatformVideoViewCreationParams") + deepHashVideoPlayerPluginMessages(value: playerId, hasher: &hasher) + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct CreationOptions: Hashable { + var uri: String + var httpHeaders: [String: String] + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> CreationOptions? { + let uri = pigeonVar_list[0] as! String + let httpHeaders = pigeonVar_list[1] as! [String: String] + + return CreationOptions( + uri: uri, + httpHeaders: httpHeaders + ) + } + func toList() -> [Any?] { + return [ + uri, + httpHeaders, + ] + } + static func == (lhs: CreationOptions, rhs: CreationOptions) -> Bool { + if Swift.type(of: lhs) != Swift.type(of: rhs) { + return false + } + return deepEqualsVideoPlayerPluginMessages(lhs.uri, rhs.uri) + && deepEqualsVideoPlayerPluginMessages(lhs.httpHeaders, rhs.httpHeaders) + } + + func hash(into hasher: inout Hasher) { + hasher.combine("CreationOptions") + deepHashVideoPlayerPluginMessages(value: uri, hasher: &hasher) + deepHashVideoPlayerPluginMessages(value: httpHeaders, hasher: &hasher) + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct TexturePlayerIds: Hashable { + var playerId: Int64 + var textureId: Int64 + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> TexturePlayerIds? { + let playerId = pigeonVar_list[0] as! Int64 + let textureId = pigeonVar_list[1] as! Int64 + + return TexturePlayerIds( + playerId: playerId, + textureId: textureId + ) + } + func toList() -> [Any?] { + return [ + playerId, + textureId, + ] + } + static func == (lhs: TexturePlayerIds, rhs: TexturePlayerIds) -> Bool { + if Swift.type(of: lhs) != Swift.type(of: rhs) { + return false + } + return deepEqualsVideoPlayerPluginMessages(lhs.playerId, rhs.playerId) + && deepEqualsVideoPlayerPluginMessages(lhs.textureId, rhs.textureId) + } + + func hash(into hasher: inout Hasher) { + hasher.combine("TexturePlayerIds") + deepHashVideoPlayerPluginMessages(value: playerId, hasher: &hasher) + deepHashVideoPlayerPluginMessages(value: textureId, hasher: &hasher) + } +} + +private class VideoPlayerPluginMessagesPigeonCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 129: + return PlatformVideoViewCreationParams.fromList(self.readValue() as! [Any?]) + case 130: + return CreationOptions.fromList(self.readValue() as! [Any?]) + case 131: + return TexturePlayerIds.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class VideoPlayerPluginMessagesPigeonCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? PlatformVideoViewCreationParams { + super.writeByte(129) + super.writeValue(value.toList()) + } else if let value = value as? CreationOptions { + super.writeByte(130) + super.writeValue(value.toList()) + } else if let value = value as? TexturePlayerIds { + super.writeByte(131) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class VideoPlayerPluginMessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return VideoPlayerPluginMessagesPigeonCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return VideoPlayerPluginMessagesPigeonCodecWriter(data: data) + } +} + +class VideoPlayerPluginMessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable { + static let shared = VideoPlayerPluginMessagesPigeonCodec( + readerWriter: VideoPlayerPluginMessagesPigeonCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol AVFoundationVideoPlayerApi { + func initialize() throws + func createPlatformViewPlayer(options params: CreationOptions) throws -> Int64 + func createTexturePlayer(options creationOptions: CreationOptions) throws -> TexturePlayerIds + func setMixWithOthers(_ mixWithOthers: Bool) throws + func fileURLForAsset(name asset: String, package: String?) throws -> String? +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class AVFoundationVideoPlayerApiSetup { + static var codec: FlutterStandardMessageCodec { VideoPlayerPluginMessagesPigeonCodec.shared } + /// Sets up an instance of `AVFoundationVideoPlayerApi` to handle messages through the `binaryMessenger`. + static func setUp( + binaryMessenger: FlutterBinaryMessenger, api: AVFoundationVideoPlayerApi?, + messageChannelSuffix: String = "" + ) { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let initializeChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + initializeChannel.setMessageHandler { _, reply in + do { + try api.initialize() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + initializeChannel.setMessageHandler(nil) + } + let createForPlatformViewChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForPlatformView\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + createForPlatformViewChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let paramsArg = args[0] as! CreationOptions + do { + let result = try api.createPlatformViewPlayer(options: paramsArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + createForPlatformViewChannel.setMessageHandler(nil) + } + let createForTextureViewChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForTextureView\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + createForTextureViewChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let creationOptionsArg = args[0] as! CreationOptions + do { + let result = try api.createTexturePlayer(options: creationOptionsArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + createForTextureViewChannel.setMessageHandler(nil) + } + let setMixWithOthersChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setMixWithOthersChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mixWithOthersArg = args[0] as! Bool + do { + try api.setMixWithOthers(mixWithOthersArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setMixWithOthersChannel.setMessageHandler(nil) + } + let getAssetUrlChannel = FlutterBasicMessageChannel( + name: + "dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getAssetUrl\(channelSuffix)", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAssetUrlChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let assetArg = args[0] as! String + let packageArg: String? = nilOrValue(args[1]) + do { + let result = try api.fileURLForAsset(name: assetArg, package: packageArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getAssetUrlChannel.setMessageHandler(nil) + } + } +} diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/messages.g.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m similarity index 54% rename from packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/messages.g.m rename to packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m index abb8efbad50d..0c2cfc987374 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/messages.g.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m @@ -1,10 +1,10 @@ // Copyright 2013 The Flutter Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.7), do not edit directly. +// Autogenerated from Pigeon (v26.3.4), do not edit directly. // See also: https://pub.dev/packages/pigeon -#import "./include/video_player_avfoundation/messages.g.h" +#import "./include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h" #if TARGET_OS_OSX @import FlutterMacOS; @@ -12,6 +12,97 @@ @import Flutter; #endif +static BOOL __attribute__((unused)) FLTPigeonDeepEquals(id _Nullable a, id _Nullable b) { + if (a == b) { + return YES; + } + if (a == nil) { + return b == [NSNull null]; + } + if (b == nil) { + return a == [NSNull null]; + } + if ([a isKindOfClass:[NSNumber class]] && [b isKindOfClass:[NSNumber class]]) { + return + [a isEqual:b] || (isnan([(NSNumber *)a doubleValue]) && isnan([(NSNumber *)b doubleValue])); + } + if ([a isKindOfClass:[NSArray class]] && [b isKindOfClass:[NSArray class]]) { + NSArray *arrayA = (NSArray *)a; + NSArray *arrayB = (NSArray *)b; + if (arrayA.count != arrayB.count) { + return NO; + } + for (NSUInteger i = 0; i < arrayA.count; i++) { + if (!FLTPigeonDeepEquals(arrayA[i], arrayB[i])) { + return NO; + } + } + return YES; + } + if ([a isKindOfClass:[NSDictionary class]] && [b isKindOfClass:[NSDictionary class]]) { + NSDictionary *dictA = (NSDictionary *)a; + NSDictionary *dictB = (NSDictionary *)b; + if (dictA.count != dictB.count) { + return NO; + } + for (id keyA in dictA) { + id valueA = dictA[keyA]; + BOOL found = NO; + for (id keyB in dictB) { + if (FLTPigeonDeepEquals(keyA, keyB)) { + id valueB = dictB[keyB]; + if (FLTPigeonDeepEquals(valueA, valueB)) { + found = YES; + break; + } else { + return NO; + } + } + } + if (!found) { + return NO; + } + } + return YES; + } + return [a isEqual:b]; +} + +static NSUInteger __attribute__((unused)) FLTPigeonDeepHash(id _Nullable value) { + if (value == nil || value == (id)[NSNull null]) { + return 0; + } + if ([value isKindOfClass:[NSNumber class]]) { + NSNumber *n = (NSNumber *)value; + double d = n.doubleValue; + if (isnan(d)) { + // Normalize NaN to a consistent hash. + return (NSUInteger)0x7FF8000000000000; + } + if (d == 0.0) { + // Normalize -0.0 to 0.0 so they have the same hash code. + d = 0.0; + } + return @(d).hash; + } + if ([value isKindOfClass:[NSArray class]]) { + NSUInteger result = 1; + for (id item in (NSArray *)value) { + result = result * 31 + FLTPigeonDeepHash(item); + } + return result; + } + if ([value isKindOfClass:[NSDictionary class]]) { + NSUInteger result = 0; + NSDictionary *dict = (NSDictionary *)value; + for (id key in dict) { + result += ((FLTPigeonDeepHash(key) * 31) ^ FLTPigeonDeepHash(dict[key])); + } + return result; + } + return [value hash]; +} + static NSArray *wrapResult(id result, FlutterError *error) { if (error) { return @[ @@ -26,102 +117,12 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { return (result == [NSNull null]) ? nil : result; } -@interface FVPPlatformVideoViewCreationParams () -+ (FVPPlatformVideoViewCreationParams *)fromList:(NSArray *)list; -+ (nullable FVPPlatformVideoViewCreationParams *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface FVPCreationOptions () -+ (FVPCreationOptions *)fromList:(NSArray *)list; -+ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface FVPTexturePlayerIds () -+ (FVPTexturePlayerIds *)fromList:(NSArray *)list; -+ (nullable FVPTexturePlayerIds *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - @interface FVPMediaSelectionAudioTrackData () + (FVPMediaSelectionAudioTrackData *)fromList:(NSArray *)list; + (nullable FVPMediaSelectionAudioTrackData *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end -@implementation FVPPlatformVideoViewCreationParams -+ (instancetype)makeWithPlayerId:(NSInteger)playerId { - FVPPlatformVideoViewCreationParams *pigeonResult = - [[FVPPlatformVideoViewCreationParams alloc] init]; - pigeonResult.playerId = playerId; - return pigeonResult; -} -+ (FVPPlatformVideoViewCreationParams *)fromList:(NSArray *)list { - FVPPlatformVideoViewCreationParams *pigeonResult = - [[FVPPlatformVideoViewCreationParams alloc] init]; - pigeonResult.playerId = [GetNullableObjectAtIndex(list, 0) integerValue]; - return pigeonResult; -} -+ (nullable FVPPlatformVideoViewCreationParams *)nullableFromList:(NSArray *)list { - return (list) ? [FVPPlatformVideoViewCreationParams fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - @(self.playerId), - ]; -} -@end - -@implementation FVPCreationOptions -+ (instancetype)makeWithUri:(NSString *)uri - httpHeaders:(NSDictionary *)httpHeaders { - FVPCreationOptions *pigeonResult = [[FVPCreationOptions alloc] init]; - pigeonResult.uri = uri; - pigeonResult.httpHeaders = httpHeaders; - return pigeonResult; -} -+ (FVPCreationOptions *)fromList:(NSArray *)list { - FVPCreationOptions *pigeonResult = [[FVPCreationOptions alloc] init]; - pigeonResult.uri = GetNullableObjectAtIndex(list, 0); - pigeonResult.httpHeaders = GetNullableObjectAtIndex(list, 1); - return pigeonResult; -} -+ (nullable FVPCreationOptions *)nullableFromList:(NSArray *)list { - return (list) ? [FVPCreationOptions fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - self.uri ?: [NSNull null], - self.httpHeaders ?: [NSNull null], - ]; -} -@end - -@implementation FVPTexturePlayerIds -+ (instancetype)makeWithPlayerId:(NSInteger)playerId textureId:(NSInteger)textureId { - FVPTexturePlayerIds *pigeonResult = [[FVPTexturePlayerIds alloc] init]; - pigeonResult.playerId = playerId; - pigeonResult.textureId = textureId; - return pigeonResult; -} -+ (FVPTexturePlayerIds *)fromList:(NSArray *)list { - FVPTexturePlayerIds *pigeonResult = [[FVPTexturePlayerIds alloc] init]; - pigeonResult.playerId = [GetNullableObjectAtIndex(list, 0) integerValue]; - pigeonResult.textureId = [GetNullableObjectAtIndex(list, 1) integerValue]; - return pigeonResult; -} -+ (nullable FVPTexturePlayerIds *)nullableFromList:(NSArray *)list { - return (list) ? [FVPTexturePlayerIds fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - @(self.playerId), - @(self.textureId), - ]; -} -@end - @implementation FVPMediaSelectionAudioTrackData + (instancetype)makeWithIndex:(NSInteger)index displayName:(nullable NSString *)displayName @@ -157,20 +158,37 @@ + (nullable FVPMediaSelectionAudioTrackData *)nullableFromList:(NSArray *)li self.commonMetadataTitle ?: [NSNull null], ]; } +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[self class]]) { + return NO; + } + FVPMediaSelectionAudioTrackData *other = (FVPMediaSelectionAudioTrackData *)object; + return self.index == other.index && FLTPigeonDeepEquals(self.displayName, other.displayName) && + FLTPigeonDeepEquals(self.languageCode, other.languageCode) && + self.isSelected == other.isSelected && + FLTPigeonDeepEquals(self.commonMetadataTitle, other.commonMetadataTitle); +} + +- (NSUInteger)hash { + NSUInteger result = [self class].hash; + result = result * 31 + @(self.index).hash; + result = result * 31 + FLTPigeonDeepHash(self.displayName); + result = result * 31 + FLTPigeonDeepHash(self.languageCode); + result = result * 31 + @(self.isSelected).hash; + result = result * 31 + FLTPigeonDeepHash(self.commonMetadataTitle); + return result; +} @end -@interface FVPMessagesPigeonCodecReader : FlutterStandardReader +@interface FVPVideoPlayerInstanceMessagesPigeonCodecReader : FlutterStandardReader @end -@implementation FVPMessagesPigeonCodecReader +@implementation FVPVideoPlayerInstanceMessagesPigeonCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 129: - return [FVPPlatformVideoViewCreationParams fromList:[self readValue]]; - case 130: - return [FVPCreationOptions fromList:[self readValue]]; - case 131: - return [FVPTexturePlayerIds fromList:[self readValue]]; - case 132: return [FVPMediaSelectionAudioTrackData fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -178,182 +196,40 @@ - (nullable id)readValueOfType:(UInt8)type { } @end -@interface FVPMessagesPigeonCodecWriter : FlutterStandardWriter +@interface FVPVideoPlayerInstanceMessagesPigeonCodecWriter : FlutterStandardWriter @end -@implementation FVPMessagesPigeonCodecWriter +@implementation FVPVideoPlayerInstanceMessagesPigeonCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FVPPlatformVideoViewCreationParams class]]) { + if ([value isKindOfClass:[FVPMediaSelectionAudioTrackData class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FVPCreationOptions class]]) { - [self writeByte:130]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FVPTexturePlayerIds class]]) { - [self writeByte:131]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FVPMediaSelectionAudioTrackData class]]) { - [self writeByte:132]; - [self writeValue:[value toList]]; } else { [super writeValue:value]; } } @end -@interface FVPMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter +@interface FVPVideoPlayerInstanceMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter @end -@implementation FVPMessagesPigeonCodecReaderWriter +@implementation FVPVideoPlayerInstanceMessagesPigeonCodecReaderWriter - (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FVPMessagesPigeonCodecWriter alloc] initWithData:data]; + return [[FVPVideoPlayerInstanceMessagesPigeonCodecWriter alloc] initWithData:data]; } - (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FVPMessagesPigeonCodecReader alloc] initWithData:data]; + return [[FVPVideoPlayerInstanceMessagesPigeonCodecReader alloc] initWithData:data]; } @end -NSObject *FVPGetMessagesCodec(void) { +NSObject *FVPGetVideoPlayerInstanceMessagesCodec(void) { static FlutterStandardMessageCodec *sSharedObject = nil; static dispatch_once_t sPred = 0; dispatch_once(&sPred, ^{ - FVPMessagesPigeonCodecReaderWriter *readerWriter = - [[FVPMessagesPigeonCodecReaderWriter alloc] init]; + FVPVideoPlayerInstanceMessagesPigeonCodecReaderWriter *readerWriter = + [[FVPVideoPlayerInstanceMessagesPigeonCodecReaderWriter alloc] init]; sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; }); return sSharedObject; } -void SetUpFVPAVFoundationVideoPlayerApi(id binaryMessenger, - NSObject *api) { - SetUpFVPAVFoundationVideoPlayerApiWithSuffix(binaryMessenger, api, @""); -} - -void SetUpFVPAVFoundationVideoPlayerApiWithSuffix(id binaryMessenger, - NSObject *api, - NSString *messageChannelSuffix) { - messageChannelSuffix = messageChannelSuffix.length > 0 - ? [NSString stringWithFormat:@".%@", messageChannelSuffix] - : @""; - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.video_player_avfoundation." - @"AVFoundationVideoPlayerApi.initialize", - messageChannelSuffix] - binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(initialize:)], - @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to @selector(initialize:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - FlutterError *error; - [api initialize:&error]; - callback(wrapResult(nil, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.video_player_avfoundation." - @"AVFoundationVideoPlayerApi.createForPlatformView", - messageChannelSuffix] - binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(createPlatformViewPlayerWithOptions:error:)], - @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " - @"@selector(createPlatformViewPlayerWithOptions:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FVPCreationOptions *arg_params = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - NSNumber *output = [api createPlatformViewPlayerWithOptions:arg_params error:&error]; - callback(wrapResult(output, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString - stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.video_player_avfoundation." - @"AVFoundationVideoPlayerApi.createForTextureView", - messageChannelSuffix] - binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(createTexturePlayerWithOptions:error:)], - @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " - @"@selector(createTexturePlayerWithOptions:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - FVPCreationOptions *arg_creationOptions = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - FVPTexturePlayerIds *output = [api createTexturePlayerWithOptions:arg_creationOptions - error:&error]; - callback(wrapResult(output, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.video_player_avfoundation." - @"AVFoundationVideoPlayerApi.setMixWithOthers", - messageChannelSuffix] - binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(setMixWithOthers:error:)], - @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " - @"@selector(setMixWithOthers:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - BOOL arg_mixWithOthers = [GetNullableObjectAtIndex(args, 0) boolValue]; - FlutterError *error; - [api setMixWithOthers:arg_mixWithOthers error:&error]; - callback(wrapResult(nil, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:[NSString stringWithFormat:@"%@%@", - @"dev.flutter.pigeon.video_player_avfoundation." - @"AVFoundationVideoPlayerApi.getAssetUrl", - messageChannelSuffix] - binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(fileURLForAssetWithName:package:error:)], - @"FVPAVFoundationVideoPlayerApi api (%@) doesn't respond to " - @"@selector(fileURLForAssetWithName:package:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_asset = GetNullableObjectAtIndex(args, 0); - NSString *arg_package = GetNullableObjectAtIndex(args, 1); - FlutterError *error; - NSString *output = [api fileURLForAssetWithName:arg_asset package:arg_package error:&error]; - callback(wrapResult(output, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } -} void SetUpFVPVideoPlayerInstanceApi(id binaryMessenger, NSObject *api) { SetUpFVPVideoPlayerInstanceApiWithSuffix(binaryMessenger, api, @""); @@ -372,7 +248,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.setLooping", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(setLooping:error:)], @@ -396,7 +272,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.setVolume", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(setVolume:error:)], @@ -420,7 +296,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.setPlaybackSpeed", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(setPlaybackSpeed:error:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to " @@ -444,7 +320,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.play", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(playWithError:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to @selector(playWithError:)", @@ -465,7 +341,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.getPosition", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(position:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to @selector(position:)", api); @@ -485,7 +361,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.seekTo", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(seekTo:completion:)], @@ -510,7 +386,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.pause", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(pauseWithError:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to @selector(pauseWithError:)", @@ -531,7 +407,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.dispose", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert( [api respondsToSelector:@selector(disposeWithError:)], @@ -553,7 +429,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.getAudioTracks", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(getAudioTracks:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to @selector(getAudioTracks:)", @@ -574,7 +450,7 @@ void SetUpFVPVideoPlayerInstanceApiWithSuffix(id binaryM @"VideoPlayerInstanceApi.selectAudioTrack", messageChannelSuffix] binaryMessenger:binaryMessenger - codec:FVPGetMessagesCodec()]; + codec:FVPGetVideoPlayerInstanceMessagesCodec()]; if (api) { NSCAssert([api respondsToSelector:@selector(selectAudioTrackAtIndex:error:)], @"FVPVideoPlayerInstanceApi api (%@) doesn't respond to " diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h new file mode 100644 index 000000000000..b06b0357d2a1 --- /dev/null +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h @@ -0,0 +1,61 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +@import Foundation; + +@protocol FlutterBinaryMessenger; +@protocol FlutterMessageCodec; +@class FlutterError; +@class FlutterStandardTypedData; + +NS_ASSUME_NONNULL_BEGIN + +@class FVPMediaSelectionAudioTrackData; + +/// Raw audio track data from AVMediaSelectionOption (for HLS streams). +@interface FVPMediaSelectionAudioTrackData : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithIndex:(NSInteger)index + displayName:(nullable NSString *)displayName + languageCode:(nullable NSString *)languageCode + isSelected:(BOOL)isSelected + commonMetadataTitle:(nullable NSString *)commonMetadataTitle; +@property(nonatomic, assign) NSInteger index; +@property(nonatomic, copy, nullable) NSString *displayName; +@property(nonatomic, copy, nullable) NSString *languageCode; +@property(nonatomic, assign) BOOL isSelected; +@property(nonatomic, copy, nullable) NSString *commonMetadataTitle; +@end + +/// The codec used by all APIs. +NSObject *FVPGetVideoPlayerInstanceMessagesCodec(void); + +@protocol FVPVideoPlayerInstanceApi +- (void)setLooping:(BOOL)looping error:(FlutterError *_Nullable *_Nonnull)error; +- (void)setVolume:(double)volume error:(FlutterError *_Nullable *_Nonnull)error; +- (void)setPlaybackSpeed:(double)speed error:(FlutterError *_Nullable *_Nonnull)error; +- (void)playWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)position:(FlutterError *_Nullable *_Nonnull)error; +- (void)seekTo:(NSInteger)position completion:(void (^)(FlutterError *_Nullable))completion; +- (void)pauseWithError:(FlutterError *_Nullable *_Nonnull)error; +- (void)disposeWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSArray *)getAudioTracks: + (FlutterError *_Nullable *_Nonnull)error; +- (void)selectAudioTrackAtIndex:(NSInteger)trackIndex + error:(FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFVPVideoPlayerInstanceApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFVPVideoPlayerInstanceApiWithSuffix( + id binaryMessenger, NSObject *_Nullable api, + NSString *messageChannelSuffix); + +NS_ASSUME_NONNULL_END 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 6684d9c4c658..c9ab066711f0 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 @@ -8,7 +8,8 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; -import 'messages.g.dart'; +import 'video_player_instance_messages.g.dart'; +import 'video_player_plugin_messages.g.dart'; /// The non-test implementation of `_apiProvider`. VideoPlayerInstanceApi _productionApiProvider(int playerId) { diff --git a/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart b/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart deleted file mode 100644 index 24644d8f42d0..000000000000 --- a/packages/video_player/video_player_avfoundation/lib/src/messages.g.dart +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.7), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers - -import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; - -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; - -PlatformException _createConnectionError(String channelName) { - return PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel: "$channelName".', - ); -} - -bool _deepEquals(Object? a, Object? b) { - if (a is List && b is List) { - return a.length == b.length && - a.indexed.every( - ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), - ); - } - if (a is Map && b is Map) { - return a.length == b.length && - a.entries.every( - (MapEntry entry) => - (b as Map).containsKey(entry.key) && - _deepEquals(entry.value, b[entry.key]), - ); - } - return a == b; -} - -/// Information passed to the platform view creation. -class PlatformVideoViewCreationParams { - PlatformVideoViewCreationParams({required this.playerId}); - - int playerId; - - List _toList() { - return [playerId]; - } - - Object encode() { - return _toList(); - } - - static PlatformVideoViewCreationParams decode(Object result) { - result as List; - return PlatformVideoViewCreationParams(playerId: result[0]! as int); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - bool operator ==(Object other) { - if (other is! PlatformVideoViewCreationParams || - other.runtimeType != runtimeType) { - return false; - } - if (identical(this, other)) { - return true; - } - return _deepEquals(encode(), other.encode()); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); -} - -class CreationOptions { - CreationOptions({required this.uri, required this.httpHeaders}); - - String uri; - - Map httpHeaders; - - List _toList() { - return [uri, httpHeaders]; - } - - Object encode() { - return _toList(); - } - - static CreationOptions decode(Object result) { - result as List; - return CreationOptions( - uri: result[0]! as String, - httpHeaders: (result[1] as Map?)! - .cast(), - ); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - bool operator ==(Object other) { - if (other is! CreationOptions || other.runtimeType != runtimeType) { - return false; - } - if (identical(this, other)) { - return true; - } - return _deepEquals(encode(), other.encode()); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); -} - -class TexturePlayerIds { - TexturePlayerIds({required this.playerId, required this.textureId}); - - int playerId; - - int textureId; - - List _toList() { - return [playerId, textureId]; - } - - Object encode() { - return _toList(); - } - - static TexturePlayerIds decode(Object result) { - result as List; - return TexturePlayerIds( - playerId: result[0]! as int, - textureId: result[1]! as int, - ); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - bool operator ==(Object other) { - if (other is! TexturePlayerIds || other.runtimeType != runtimeType) { - return false; - } - if (identical(this, other)) { - return true; - } - return _deepEquals(encode(), other.encode()); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); -} - -/// Raw audio track data from AVMediaSelectionOption (for HLS streams). -class MediaSelectionAudioTrackData { - MediaSelectionAudioTrackData({ - required this.index, - this.displayName, - this.languageCode, - required this.isSelected, - this.commonMetadataTitle, - }); - - int index; - - String? displayName; - - String? languageCode; - - bool isSelected; - - String? commonMetadataTitle; - - List _toList() { - return [ - index, - displayName, - languageCode, - isSelected, - commonMetadataTitle, - ]; - } - - Object encode() { - return _toList(); - } - - static MediaSelectionAudioTrackData decode(Object result) { - result as List; - return MediaSelectionAudioTrackData( - index: result[0]! as int, - displayName: result[1] as String?, - languageCode: result[2] as String?, - isSelected: result[3]! as bool, - commonMetadataTitle: result[4] as String?, - ); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - bool operator ==(Object other) { - if (other is! MediaSelectionAudioTrackData || - other.runtimeType != runtimeType) { - return false; - } - if (identical(this, other)) { - return true; - } - return _deepEquals(encode(), other.encode()); - } - - @override - // ignore: avoid_equals_and_hash_code_on_mutable_classes - int get hashCode => Object.hashAll(_toList()); -} - -class _PigeonCodec extends StandardMessageCodec { - const _PigeonCodec(); - @override - void writeValue(WriteBuffer buffer, Object? value) { - if (value is int) { - buffer.putUint8(4); - buffer.putInt64(value); - } else if (value is PlatformVideoViewCreationParams) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is CreationOptions) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is TexturePlayerIds) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is MediaSelectionAudioTrackData) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else { - super.writeValue(buffer, value); - } - } - - @override - Object? readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case 129: - return PlatformVideoViewCreationParams.decode(readValue(buffer)!); - case 130: - return CreationOptions.decode(readValue(buffer)!); - case 131: - return TexturePlayerIds.decode(readValue(buffer)!); - case 132: - return MediaSelectionAudioTrackData.decode(readValue(buffer)!); - default: - return super.readValueOfType(type, buffer); - } - } -} - -class AVFoundationVideoPlayerApi { - /// Constructor for [AVFoundationVideoPlayerApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - AVFoundationVideoPlayerApi({ - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; - final BinaryMessenger? pigeonVar_binaryMessenger; - - static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - - final String pigeonVar_messageChannelSuffix; - - Future initialize() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future createForPlatformView(CreationOptions params) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForPlatformView$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [params], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else if (pigeonVar_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (pigeonVar_replyList[0] as int?)!; - } - } - - Future createForTextureView( - CreationOptions creationOptions, - ) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForTextureView$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [creationOptions], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else if (pigeonVar_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (pigeonVar_replyList[0] as TexturePlayerIds?)!; - } - } - - Future setMixWithOthers(bool mixWithOthers) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [mixWithOthers], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future getAssetUrl(String asset, String? package) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getAssetUrl$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [asset, package], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return (pigeonVar_replyList[0] as String?); - } - } -} - -class VideoPlayerInstanceApi { - /// Constructor for [VideoPlayerInstanceApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - VideoPlayerInstanceApi({ - BinaryMessenger? binaryMessenger, - String messageChannelSuffix = '', - }) : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty - ? '.$messageChannelSuffix' - : ''; - final BinaryMessenger? pigeonVar_binaryMessenger; - - static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - - final String pigeonVar_messageChannelSuffix; - - Future setLooping(bool looping) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setLooping$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [looping], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future setVolume(double volume) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setVolume$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [volume], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future setPlaybackSpeed(double speed) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPlaybackSpeed$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [speed], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future play() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.play$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future getPosition() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getPosition$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else if (pigeonVar_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (pigeonVar_replyList[0] as int?)!; - } - } - - Future seekTo(int position) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.seekTo$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [position], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future pause() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.pause$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future dispose() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.dispose$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } - - Future> getAudioTracks() async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getAudioTracks$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else if (pigeonVar_replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (pigeonVar_replyList[0] as List?)! - .cast(); - } - } - - Future selectAudioTrack(int trackIndex) async { - final pigeonVar_channelName = - 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.selectAudioTrack$pigeonVar_messageChannelSuffix'; - final pigeonVar_channel = BasicMessageChannel( - pigeonVar_channelName, - pigeonChannelCodec, - binaryMessenger: pigeonVar_binaryMessenger, - ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [trackIndex], - ); - final pigeonVar_replyList = await pigeonVar_sendFuture as List?; - if (pigeonVar_replyList == null) { - throw _createConnectionError(pigeonVar_channelName); - } else if (pigeonVar_replyList.length > 1) { - throw PlatformException( - code: pigeonVar_replyList[0]! as String, - message: pigeonVar_replyList[1] as String?, - details: pigeonVar_replyList[2], - ); - } else { - return; - } - } -} diff --git a/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart b/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart new file mode 100644 index 000000000000..c10d9f31a0ce --- /dev/null +++ b/packages/video_player/video_player_avfoundation/lib/src/video_player_instance_messages.g.dart @@ -0,0 +1,405 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + +bool _deepEquals(Object? a, Object? b) { + if (identical(a, b)) { + return true; + } + if (a is double && b is double) { + if (a.isNaN && b.isNaN) { + return true; + } + return a == b; + } + if (a is List && b is List) { + return a.length == b.length && + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); + } + if (a is Map && b is Map) { + if (a.length != b.length) { + return false; + } + for (final MapEntry entryA in a.entries) { + bool found = false; + for (final MapEntry entryB in b.entries) { + if (_deepEquals(entryA.key, entryB.key)) { + if (_deepEquals(entryA.value, entryB.value)) { + found = true; + break; + } else { + return false; + } + } + } + if (!found) { + return false; + } + } + return true; + } + return a == b; +} + +int _deepHash(Object? value) { + if (value is List) { + return Object.hashAll(value.map(_deepHash)); + } + if (value is Map) { + int result = 0; + for (final MapEntry entry in value.entries) { + result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value); + } + return result; + } + if (value is double && value.isNaN) { + // Normalize NaN to a consistent hash. + return 0x7FF8000000000000.hashCode; + } + if (value is double && value == 0.0) { + // Normalize -0.0 to 0.0 so they have the same hash code. + return 0.0.hashCode; + } + return value.hashCode; +} + +/// Raw audio track data from AVMediaSelectionOption (for HLS streams). +class MediaSelectionAudioTrackData { + MediaSelectionAudioTrackData({ + required this.index, + this.displayName, + this.languageCode, + required this.isSelected, + this.commonMetadataTitle, + }); + + int index; + + String? displayName; + + String? languageCode; + + bool isSelected; + + String? commonMetadataTitle; + + List _toList() { + return [ + index, + displayName, + languageCode, + isSelected, + commonMetadataTitle, + ]; + } + + Object encode() { + return _toList(); + } + + static MediaSelectionAudioTrackData decode(Object result) { + result as List; + return MediaSelectionAudioTrackData( + index: result[0]! as int, + displayName: result[1] as String?, + languageCode: result[2] as String?, + isSelected: result[3]! as bool, + commonMetadataTitle: result[4] as String?, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! MediaSelectionAudioTrackData || + other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(index, other.index) && + _deepEquals(displayName, other.displayName) && + _deepEquals(languageCode, other.languageCode) && + _deepEquals(isSelected, other.isSelected) && + _deepEquals(commonMetadataTitle, other.commonMetadataTitle); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => _deepHash([runtimeType, ..._toList()]); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is MediaSelectionAudioTrackData) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + return MediaSelectionAudioTrackData.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class VideoPlayerInstanceApi { + /// Constructor for [VideoPlayerInstanceApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + VideoPlayerInstanceApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future setLooping(bool looping) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setLooping$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [looping], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future setVolume(double volume) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setVolume$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [volume], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future setPlaybackSpeed(double speed) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.setPlaybackSpeed$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [speed], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future play() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.play$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future getPosition() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getPosition$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as int; + } + + Future seekTo(int position) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.seekTo$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [position], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future pause() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.pause$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future dispose() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.dispose$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future> getAudioTracks() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.getAudioTracks$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return (pigeonVar_replyValue! as List) + .cast(); + } + + Future selectAudioTrack(int trackIndex) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.VideoPlayerInstanceApi.selectAudioTrack$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [trackIndex], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } +} diff --git a/packages/video_player/video_player_avfoundation/lib/src/video_player_plugin_messages.g.dart b/packages/video_player/video_player_avfoundation/lib/src/video_player_plugin_messages.g.dart new file mode 100644 index 000000000000..e1d4dbaa2136 --- /dev/null +++ b/packages/video_player/video_player_avfoundation/lib/src/video_player_plugin_messages.g.dart @@ -0,0 +1,377 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow( + List? replyList, + String channelName, { + required bool isNullValid, +}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + +bool _deepEquals(Object? a, Object? b) { + if (identical(a, b)) { + return true; + } + if (a is double && b is double) { + if (a.isNaN && b.isNaN) { + return true; + } + return a == b; + } + if (a is List && b is List) { + return a.length == b.length && + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); + } + if (a is Map && b is Map) { + if (a.length != b.length) { + return false; + } + for (final MapEntry entryA in a.entries) { + bool found = false; + for (final MapEntry entryB in b.entries) { + if (_deepEquals(entryA.key, entryB.key)) { + if (_deepEquals(entryA.value, entryB.value)) { + found = true; + break; + } else { + return false; + } + } + } + if (!found) { + return false; + } + } + return true; + } + return a == b; +} + +int _deepHash(Object? value) { + if (value is List) { + return Object.hashAll(value.map(_deepHash)); + } + if (value is Map) { + int result = 0; + for (final MapEntry entry in value.entries) { + result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value); + } + return result; + } + if (value is double && value.isNaN) { + // Normalize NaN to a consistent hash. + return 0x7FF8000000000000.hashCode; + } + if (value is double && value == 0.0) { + // Normalize -0.0 to 0.0 so they have the same hash code. + return 0.0.hashCode; + } + return value.hashCode; +} + +/// Information passed to the platform view creation. +class PlatformVideoViewCreationParams { + PlatformVideoViewCreationParams({required this.playerId}); + + int playerId; + + List _toList() { + return [playerId]; + } + + Object encode() { + return _toList(); + } + + static PlatformVideoViewCreationParams decode(Object result) { + result as List; + return PlatformVideoViewCreationParams(playerId: result[0]! as int); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! PlatformVideoViewCreationParams || + other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(playerId, other.playerId); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => _deepHash([runtimeType, ..._toList()]); +} + +class CreationOptions { + CreationOptions({required this.uri, required this.httpHeaders}); + + String uri; + + Map httpHeaders; + + List _toList() { + return [uri, httpHeaders]; + } + + Object encode() { + return _toList(); + } + + static CreationOptions decode(Object result) { + result as List; + return CreationOptions( + uri: result[0]! as String, + httpHeaders: (result[1]! as Map).cast(), + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! CreationOptions || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(uri, other.uri) && + _deepEquals(httpHeaders, other.httpHeaders); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => _deepHash([runtimeType, ..._toList()]); +} + +class TexturePlayerIds { + TexturePlayerIds({required this.playerId, required this.textureId}); + + int playerId; + + int textureId; + + List _toList() { + return [playerId, textureId]; + } + + Object encode() { + return _toList(); + } + + static TexturePlayerIds decode(Object result) { + result as List; + return TexturePlayerIds( + playerId: result[0]! as int, + textureId: result[1]! as int, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! TexturePlayerIds || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(playerId, other.playerId) && + _deepEquals(textureId, other.textureId); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => _deepHash([runtimeType, ..._toList()]); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else if (value is PlatformVideoViewCreationParams) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is CreationOptions) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is TexturePlayerIds) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + return PlatformVideoViewCreationParams.decode(readValue(buffer)!); + case 130: + return CreationOptions.decode(readValue(buffer)!); + case 131: + return TexturePlayerIds.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class AVFoundationVideoPlayerApi { + /// Constructor for [AVFoundationVideoPlayerApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + AVFoundationVideoPlayerApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future initialize() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.initialize$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future createForPlatformView(CreationOptions params) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForPlatformView$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [params], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as int; + } + + Future createForTextureView( + CreationOptions creationOptions, + ) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.createForTextureView$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [creationOptions], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as TexturePlayerIds; + } + + Future setMixWithOthers(bool mixWithOthers) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.setMixWithOthers$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [mixWithOthers], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + } + + Future getAssetUrl(String asset, String? package) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.video_player_avfoundation.AVFoundationVideoPlayerApi.getAssetUrl$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [asset, package], + ); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: true, + ); + return pigeonVar_replyValue as String?; + } +} diff --git a/packages/video_player/video_player_avfoundation/pigeons/messages.dart b/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart similarity index 51% rename from packages/video_player/video_player_avfoundation/pigeons/messages.dart rename to packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart index f49b46005307..354d2357b7ca 100644 --- a/packages/video_player/video_player_avfoundation/pigeons/messages.dart +++ b/packages/video_player/video_player_avfoundation/pigeons/video_player_instance_messages.dart @@ -2,43 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Contains player-instance-level APIs. + import 'package:pigeon/pigeon.dart'; @ConfigurePigeon( PigeonOptions( - dartOut: 'lib/src/messages.g.dart', + dartOut: 'lib/src/video_player_instance_messages.g.dart', objcHeaderOut: - 'darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/messages.g.h', + 'darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h', objcSourceOut: - 'darwin/video_player_avfoundation/Sources/video_player_avfoundation/messages.g.m', + 'darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.m', objcOptions: ObjcOptions( prefix: 'FVP', - headerIncludePath: './include/video_player_avfoundation/messages.g.h', + headerIncludePath: + './include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h', ), copyrightHeader: 'pigeons/copyright.txt', ), ) -/// Information passed to the platform view creation. -class PlatformVideoViewCreationParams { - const PlatformVideoViewCreationParams({required this.playerId}); - - final int playerId; -} - -class CreationOptions { - CreationOptions({required this.uri, required this.httpHeaders}); - - String uri; - Map httpHeaders; -} - -class TexturePlayerIds { - TexturePlayerIds({required this.playerId, required this.textureId}); - - final int playerId; - final int textureId; -} - /// Raw audio track data from AVMediaSelectionOption (for HLS streams). class MediaSelectionAudioTrackData { MediaSelectionAudioTrackData({ @@ -56,23 +38,6 @@ class MediaSelectionAudioTrackData { String? commonMetadataTitle; } -@HostApi() -abstract class AVFoundationVideoPlayerApi { - @ObjCSelector('initialize') - void initialize(); - // Creates a new player using a platform view for rendering and returns its - // ID. - @ObjCSelector('createPlatformViewPlayerWithOptions:') - int createForPlatformView(CreationOptions params); - // Creates a new player using a texture for rendering and returns its IDs. - @ObjCSelector('createTexturePlayerWithOptions:') - TexturePlayerIds createForTextureView(CreationOptions creationOptions); - @ObjCSelector('setMixWithOthers:') - void setMixWithOthers(bool mixWithOthers); - @ObjCSelector('fileURLForAssetWithName:package:') - String? getAssetUrl(String asset, String? package); -} - @HostApi() abstract class VideoPlayerInstanceApi { @ObjCSelector('setLooping:') diff --git a/packages/video_player/video_player_avfoundation/pigeons/video_player_plugin_messages.dart b/packages/video_player/video_player_avfoundation/pigeons/video_player_plugin_messages.dart new file mode 100644 index 000000000000..91f4fc80cbda --- /dev/null +++ b/packages/video_player/video_player_avfoundation/pigeons/video_player_plugin_messages.dart @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Contains plugin-class-level APIs. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/src/video_player_plugin_messages.g.dart', + swiftOut: + 'darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPluginMessages.g.swift', + copyrightHeader: 'pigeons/copyright.txt', + ), +) +/// Information passed to the platform view creation. +class PlatformVideoViewCreationParams { + const PlatformVideoViewCreationParams({required this.playerId}); + + final int playerId; +} + +class CreationOptions { + CreationOptions({required this.uri, required this.httpHeaders}); + + String uri; + Map httpHeaders; +} + +class TexturePlayerIds { + TexturePlayerIds({required this.playerId, required this.textureId}); + + final int playerId; + final int textureId; +} + +@HostApi() +abstract class AVFoundationVideoPlayerApi { + void initialize(); + // Creates a new player using a platform view for rendering and returns its + // ID. + @SwiftFunction('createPlatformViewPlayer(options:)') + int createForPlatformView(CreationOptions params); + // Creates a new player using a texture for rendering and returns its IDs. + @SwiftFunction('createTexturePlayer(options:)') + TexturePlayerIds createForTextureView(CreationOptions creationOptions); + @SwiftFunction('setMixWithOthers(_:)') + void setMixWithOthers(bool mixWithOthers); + @SwiftFunction('fileURLForAsset(name:package:)') + String? getAssetUrl(String asset, String? package); +} diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index f14fefb73326..a901ef5dc867 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -31,7 +31,7 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.4.4 - pigeon: ^26.1.7 + pigeon: ^26.3.4 topics: - video 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 c16d5bcb08e9..dcec5e6ee107 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 @@ -7,7 +7,8 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:video_player_avfoundation/src/messages.g.dart'; +import 'package:video_player_avfoundation/src/video_player_instance_messages.g.dart'; +import 'package:video_player_avfoundation/src/video_player_plugin_messages.g.dart'; import 'package:video_player_avfoundation/video_player_avfoundation.dart'; import 'package:video_player_platform_interface/video_player_platform_interface.dart'; diff --git a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart index 8caf6ad8dc43..2871affc2596 100644 --- a/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart +++ b/packages/video_player/video_player_avfoundation/test/avfoundation_video_player_test.mocks.dart @@ -7,7 +7,10 @@ import 'dart:async' as _i4; import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i3; -import 'package:video_player_avfoundation/src/messages.g.dart' as _i2; +import 'package:video_player_avfoundation/src/video_player_instance_messages.g.dart' + as _i5; +import 'package:video_player_avfoundation/src/video_player_plugin_messages.g.dart' + as _i2; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -22,6 +25,7 @@ import 'package:video_player_avfoundation/src/messages.g.dart' as _i2; // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member class _FakeTexturePlayerIds_0 extends _i1.SmartFake implements _i2.TexturePlayerIds { @@ -111,7 +115,7 @@ class MockAVFoundationVideoPlayerApi extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockVideoPlayerInstanceApi extends _i1.Mock - implements _i2.VideoPlayerInstanceApi { + implements _i5.VideoPlayerInstanceApi { @override String get pigeonVar_messageChannelSuffix => (super.noSuchMethod( @@ -198,4 +202,28 @@ class MockVideoPlayerInstanceApi extends _i1.Mock returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + + @override + _i4.Future> getAudioTracks() => + (super.noSuchMethod( + Invocation.method(#getAudioTracks, []), + returnValue: + _i4.Future>.value( + <_i5.MediaSelectionAudioTrackData>[], + ), + returnValueForMissingStub: + _i4.Future>.value( + <_i5.MediaSelectionAudioTrackData>[], + ), + ) + as _i4.Future>); + + @override + _i4.Future selectAudioTrack(int? trackIndex) => + (super.noSuchMethod( + Invocation.method(#selectAudioTrack, [trackIndex]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); } From 63185b88889ffd63fba262c9c28721161a30b290 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 24 Apr 2026 15:07:37 -0400 Subject: [PATCH 03/22] Gemini conversion --- .../VideoPlayerPlugin.swift | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift new file mode 100644 index 000000000000..586cbc5b792d --- /dev/null +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -0,0 +1,275 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import AVFoundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +/// Non-test implementation of the display link factory. +class DefaultDisplayLinkFactory: NSObject, FVPDisplayLinkFactory { + func displayLink( + with viewProvider: FVPViewProvider, + callback: @escaping () -> Void + ) -> FVPDisplayLink { + #if os(iOS) + return FVPCADisplayLink(viewProvider: viewProvider, callback: callback) + #elseif os(macOS) + if #available(macOS 14.0, *) { + return FVPCADisplayLink(viewProvider: viewProvider, callback: callback) + } + return FVPCoreVideoDisplayLink(viewProvider: viewProvider, callback: callback) + #endif + } +} + +/// Non-test implementation of FVPAssetProvider, wrapping a Flutter plugin +/// registrar. +class DefaultAssetProvider: NSObject, FVPAssetProvider { + private weak var registrar: FlutterPluginRegistrar? + + init(registrar: FlutterPluginRegistrar) { + self.registrar = registrar + super.init() + } + + func lookupKey(forAsset asset: String) -> String { + return registrar?.lookupKey(forAsset: asset) ?? "" + } + + func lookupKey(forAsset asset: String, fromPackage package: String) -> String { + return registrar?.lookupKey(forAsset: asset, fromPackage: package) ?? "" + } +} + +class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { + private let binaryMessenger: FlutterBinaryMessenger + private let textureRegistry: FlutterTextureRegistry + private let displayLinkFactory: FVPDisplayLinkFactory + private let avFactory: FVPAVFactory + private let viewProvider: FVPViewProvider + private let assetProvider: FVPAssetProvider + private var nextPlayerIdentifier: Int64 = 1 + var playersByIdentifier: [Int64: FVPVideoPlayer] = [:] + + static func register(with registrar: FlutterPluginRegistrar) { + let instance = VideoPlayerPlugin(registrar: registrar) + registrar.publish(instance) + + let factory = FVPNativeVideoViewFactory( + messenger: registrar.messenger, + playerByIdentifierProvider: { [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in + return instance?.playersByIdentifier[playerIdentifier.int64Value] + } + ) + registrar.register(factory, withId: "plugins.flutter.dev/video_player_ios") + + AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: registrar.messenger, api: instance) + } + + convenience init(registrar: FlutterPluginRegistrar) { + self.init( + avFactory: FVPDefaultAVFactory(), + displayLinkFactory: DefaultDisplayLinkFactory(), + binaryMessenger: registrar.messenger, + textureRegistry: registrar.textures, + viewProvider: FVPDefaultViewProvider(registrar: registrar), + assetProvider: DefaultAssetProvider(registrar: registrar) + ) + } + + init( + avFactory: FVPAVFactory, + displayLinkFactory: FVPDisplayLinkFactory, + binaryMessenger: FlutterBinaryMessenger, + textureRegistry: FlutterTextureRegistry, + viewProvider: FVPViewProvider, + assetProvider: FVPAssetProvider + ) { + self.binaryMessenger = binaryMessenger + self.textureRegistry = textureRegistry + self.assetProvider = assetProvider + self.viewProvider = viewProvider + self.displayLinkFactory = displayLinkFactory + self.avFactory = avFactory + super.init() + } + + func detachFromEngine(for registrar: FlutterPluginRegistrar) { + for player in playersByIdentifier.values { + player.onDisposed = nil + player.eventListener = nil + var error: FlutterError? + player.disposeWithError(&error) + } + playersByIdentifier.removeAll() + AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: registrar.messenger, api: nil) + } + + func initialize() throws { + #if os(iOS) + // Allow audio playback when the Ring/Silent switch is set to silent + upgradeAudioSessionCategory( + session: avFactory.sharedAudioSession(), + requestedCategory: .playback, + options: [], + clearOptions: [] + ) + #endif + + for player in playersByIdentifier.values { + var error: FlutterError? + player.disposeWithError(&error) + } + playersByIdentifier.removeAll() + } + + func createPlatformViewPlayer(options params: CreationOptions) throws -> Int64 { + let item = try playerItem(with: params) + let player = FVPVideoPlayer(playerItem: item, avFactory: avFactory, viewProvider: viewProvider) + return configurePlayer(player, extraDisposeHandler: nil) + } + + func createTexturePlayer(options creationOptions: CreationOptions) throws -> TexturePlayerIds { + let item = try playerItem(with: creationOptions) + let frameUpdater = FVPFrameUpdater(registry: textureRegistry) + let displayLink = displayLinkFactory.displayLink(with: viewProvider) { + frameUpdater?.displayLinkFired() + } + + let player = FVPTextureBasedVideoPlayer( + playerItem: item, + frameUpdater: frameUpdater, + displayLink: displayLink, + avFactory: avFactory, + viewProvider: viewProvider + ) + + guard let textureId = textureRegistry.register(player) else { + throw PigeonError(code: "video_player", message: "Failed to register texture", details: nil) + } + player.setTextureIdentifier(textureId) + + let playerId = configurePlayer(player) { [weak self] in + self?.textureRegistry.unregisterTexture(textureId) + } + + return TexturePlayerIds(playerId: playerId, textureId: textureId) + } + + func setMixWithOthers(_ mixWithOthers: Bool) throws { + #if os(iOS) + let session = avFactory.sharedAudioSession() + if mixWithOthers { + upgradeAudioSessionCategory( + session: session, + requestedCategory: session.category, + options: .mixWithOthers, + clearOptions: [] + ) + } else { + upgradeAudioSessionCategory( + session: session, + requestedCategory: session.category, + options: [], + clearOptions: .mixWithOthers + ) + } + #endif + } + + func fileURLForAsset(name asset: String, package: String?) throws -> String? { + let resource = package == nil + ? assetProvider.lookupKey(forAsset: asset) + : assetProvider.lookupKey(forAsset: asset, fromPackage: package!) + + var path = Bundle.main.path(forResource: resource, ofType: nil) + #if os(macOS) + // See https://github.com/flutter/flutter/issues/135302 + if path == nil { + path = URL(string: resource, relativeTo: Bundle.main.bundleURL)?.path + } + #endif + + guard let validPath = path else { + return nil + } + return URL(fileURLWithPath: validPath).absoluteString + } + + // MARK: - Private + + private func configurePlayer(_ player: FVPVideoPlayer, extraDisposeHandler: (() -> Void)?) -> Int64 { + let playerId = nextPlayerIdentifier + nextPlayerIdentifier += 1 + playersByIdentifier[playerId] = player + + let channelSuffix = "\(playerId)" + // Set up the player-specific API handler, and its onDispose unregistration. + SetUpFVPVideoPlayerInstanceApiWithSuffix(binaryMessenger, player, channelSuffix) + + player.onDisposed = { [weak self] in + SetUpFVPVideoPlayerInstanceApiWithSuffix(self?.binaryMessenger, nil, channelSuffix) + extraDisposeHandler?() + self?.playersByIdentifier.removeValue(forKey: playerId) + } + + // Set up the event channel. + let eventBridge = FVPEventBridge( + messenger: binaryMessenger, + channelName: "flutter.dev/videoPlayer/videoEvents\(channelSuffix)" + ) + player.eventListener = eventBridge + + return playerId + } + + private func playerItem(with options: CreationOptions) throws -> FVPAVPlayerItem { + let headers = options.httpHeaders + let itemOptions = headers.isEmpty ? nil : ["AVURLAssetHTTPHeaderFieldsKey": headers] + guard let url = URL(string: options.uri) else { + throw PigeonError(code: "video_player", message: "Invalid URI", details: nil) + } + let asset = avFactory.urlAsset(with: url, options: itemOptions) + return avFactory.playerItem(with: asset) + } +} + +#if os(iOS) + private func upgradeAudioSessionCategory( + session: FVPAVAudioSession, + requestedCategory: AVAudioSession.Category, + options: AVAudioSession.CategoryOptions, + clearOptions: AVAudioSession.CategoryOptions + ) { + let playCategories: Set = [.playback, .playAndRecord] + let recordCategories: Set = [.record, .playAndRecord] + let requiredCategories: Set = [requestedCategory, session.category] + + let requiresPlay = !requiredCategories.isDisjoint(with: playCategories) + let requiresRecord = !requiredCategories.isDisjoint(with: recordCategories) + + var finalCategory = requestedCategory + if requiresPlay && requiresRecord { + finalCategory = .playAndRecord + } else if requiresPlay { + finalCategory = .playback + } else if requiresRecord { + finalCategory = .record + } + + let newOptions = session.categoryOptions.subtracting(clearOptions).union(options) + + if finalCategory == session.category && newOptions == session.categoryOptions { + return + } + + try? session.setCategory(finalCategory, with: newOptions) + } +#endif From 67d7b55e99775b98594dcbbcb7c0d77f03a07d6f Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 24 Apr 2026 15:17:05 -0400 Subject: [PATCH 04/22] Update podspec --- .../darwin/video_player_avfoundation.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec index ca7a63e97258..8fac0f82e7f5 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec @@ -14,10 +14,10 @@ Downloaded by pub (not CocoaPods). s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation' } s.documentation_url = 'https://pub.dev/packages/video_player' - s.source_files = 'video_player_avfoundation/Sources/video_player_avfoundation/**/*.{h,m}' + s.source_files = 'video_player_avfoundation/Sources/video_player_avfoundation{,_objc}/**/*.{h,m,swift}' s.ios.source_files = 'video_player_avfoundation/Sources/video_player_avfoundation_ios/*' s.osx.source_files = 'video_player_avfoundation/Sources/video_player_avfoundation_macos/*' - s.public_header_files = 'video_player_avfoundation/Sources/video_player_avfoundation/include/**/*.h' + s.public_header_files = 'video_player_avfoundation/Sources/video_player_avfoundation_objc/include/**/*.h' s.ios.dependency 'Flutter' s.osx.dependency 'FlutterMacOS' s.ios.deployment_target = '13.0' From 4968e4de5254865bae511594d3f30dc0e7947df6 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 24 Apr 2026 16:05:30 -0400 Subject: [PATCH 05/22] Manual audit of Gemini conversion, misc fixup --- .../video_player_avfoundation/Package.swift | 4 +- .../VideoPlayerPlugin.swift | 77 ++++- .../FVPNativeVideoView.m | 2 +- .../FVPCoreVideoDisplayLink.m | 2 +- .../FVPNativeVideoView.m | 2 +- .../FVPCADisplayLink.m | 2 +- .../FVPNativeVideoViewFactory.m | 8 +- .../FVPVideoPlayerPlugin.m | 317 ------------------ .../FVPDisplayLink.h | 4 + .../FVPEventBridge.h | 4 + .../FVPNativeVideoView.h | 5 + .../FVPNativeVideoViewFactory.h | 6 +- .../FVPVideoEventListener.h | 4 + .../FVPVideoPlayer.h | 2 +- .../FVPVideoPlayerPlugin.h | 17 - .../FVPVideoPlayerPlugin_Test.h | 44 --- .../messages.g.h | 112 ------- .../ios/Runner.xcodeproj/project.pbxproj | 10 +- 18 files changed, 99 insertions(+), 523 deletions(-) delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayerPlugin.m delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift index cd18e673fb75..26031b0426c8 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift @@ -39,13 +39,13 @@ let package = Package( .target( name: "video_player_avfoundation_ios", cSettings: [ - .headerSearchPath("../video_player_avfoundation/include/video_player_avfoundation") + .headerSearchPath("../video_player_avfoundation_objc/include/video_player_avfoundation_objc") ] ), .target( name: "video_player_avfoundation_macos", cSettings: [ - .headerSearchPath("../video_player_avfoundation/include/video_player_avfoundation") + .headerSearchPath("../video_player_avfoundation_objc/include/video_player_avfoundation_objc") ] ), ] diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index 586cbc5b792d..aeaef4b2167d 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -12,8 +12,20 @@ import AVFoundation #error("Unsupported platform.") #endif +#if canImport(video_player_avfoundation_objc) +import video_player_avfoundation_objc +#endif + +// Protocol for an display link factory. Used for injecting display links in tests. +protocol DisplayLinkFactory { + func displayLink( + with viewProvider: FVPViewProvider, + callback: @escaping () -> Void + ) -> FVPDisplayLink +} + /// Non-test implementation of the display link factory. -class DefaultDisplayLinkFactory: NSObject, FVPDisplayLinkFactory { +class DefaultDisplayLinkFactory: NSObject, DisplayLinkFactory { func displayLink( with viewProvider: FVPViewProvider, callback: @escaping () -> Void @@ -39,19 +51,19 @@ class DefaultAssetProvider: NSObject, FVPAssetProvider { super.init() } - func lookupKey(forAsset asset: String) -> String { - return registrar?.lookupKey(forAsset: asset) ?? "" + func lookupKey(forAsset asset: String) -> String? { + return registrar?.lookupKey(forAsset: asset) } - func lookupKey(forAsset asset: String, fromPackage package: String) -> String { - return registrar?.lookupKey(forAsset: asset, fromPackage: package) ?? "" + func lookupKey(forAsset asset: String, fromPackage package: String) -> String? { + return registrar?.lookupKey(forAsset: asset, fromPackage: package) } } class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { private let binaryMessenger: FlutterBinaryMessenger private let textureRegistry: FlutterTextureRegistry - private let displayLinkFactory: FVPDisplayLinkFactory + private let displayLinkFactory: DisplayLinkFactory private let avFactory: FVPAVFactory private let viewProvider: FVPViewProvider private let assetProvider: FVPAssetProvider @@ -60,25 +72,38 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { static func register(with registrar: FlutterPluginRegistrar) { let instance = VideoPlayerPlugin(registrar: registrar) + // Publish the instance so that it receives detachFromEngine. registrar.publish(instance) +#if os(iOS) + let messenger = registrar.messenger() +#else + let messenger = registrar.messenger +#endif let factory = FVPNativeVideoViewFactory( - messenger: registrar.messenger, + messenger: messenger, playerByIdentifierProvider: { [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in return instance?.playersByIdentifier[playerIdentifier.int64Value] } ) registrar.register(factory, withId: "plugins.flutter.dev/video_player_ios") - AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: registrar.messenger, api: instance) + AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: messenger, api: instance) } convenience init(registrar: FlutterPluginRegistrar) { +#if os(iOS) + let messenger = registrar.messenger() + let textures = registrar.textures() +#else + let messenger = registrar.messenger + let textures = registrar.textures +#endif self.init( avFactory: FVPDefaultAVFactory(), displayLinkFactory: DefaultDisplayLinkFactory(), - binaryMessenger: registrar.messenger, - textureRegistry: registrar.textures, + binaryMessenger: messenger, + textureRegistry: textures, viewProvider: FVPDefaultViewProvider(registrar: registrar), assetProvider: DefaultAssetProvider(registrar: registrar) ) @@ -86,7 +111,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { init( avFactory: FVPAVFactory, - displayLinkFactory: FVPDisplayLinkFactory, + displayLinkFactory: DisplayLinkFactory, binaryMessenger: FlutterBinaryMessenger, textureRegistry: FlutterTextureRegistry, viewProvider: FVPViewProvider, @@ -103,13 +128,20 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { func detachFromEngine(for registrar: FlutterPluginRegistrar) { for player in playersByIdentifier.values { + // Remove the channel and texture cleanup, and the event listener, to ensure that the player + // doesn't message the engine that is no longer connected. player.onDisposed = nil player.eventListener = nil var error: FlutterError? player.disposeWithError(&error) } playersByIdentifier.removeAll() - AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: registrar.messenger, api: nil) +#if os(iOS) + let messenger = registrar.messenger() +#else + let messenger = registrar.messenger +#endif + AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: messenger, api: nil) } func initialize() throws { @@ -140,7 +172,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { let item = try playerItem(with: creationOptions) let frameUpdater = FVPFrameUpdater(registry: textureRegistry) let displayLink = displayLinkFactory.displayLink(with: viewProvider) { - frameUpdater?.displayLinkFired() + frameUpdater.displayLinkFired() } let player = FVPTextureBasedVideoPlayer( @@ -151,9 +183,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { viewProvider: viewProvider ) - guard let textureId = textureRegistry.register(player) else { - throw PigeonError(code: "video_player", message: "Failed to register texture", details: nil) - } + let textureId = textureRegistry.register(player) player.setTextureIdentifier(textureId) let playerId = configurePlayer(player) { [weak self] in @@ -182,6 +212,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { ) } #endif + // AVAudioSession doesn't exist on macOS, and audio always mixes, so just no-op. } func fileURLForAsset(name asset: String, package: String?) throws -> String? { @@ -192,6 +223,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { var path = Bundle.main.path(forResource: resource, ofType: nil) #if os(macOS) // See https://github.com/flutter/flutter/issues/135302 + // TODO(stuartmorgan): Remove this if the asset APIs are adjusted to work better for macOS. if path == nil { path = URL(string: resource, relativeTo: Bundle.main.bundleURL)?.path } @@ -215,9 +247,10 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { SetUpFVPVideoPlayerInstanceApiWithSuffix(binaryMessenger, player, channelSuffix) player.onDisposed = { [weak self] in - SetUpFVPVideoPlayerInstanceApiWithSuffix(self?.binaryMessenger, nil, channelSuffix) + guard let strongSelf = self else { return } + SetUpFVPVideoPlayerInstanceApiWithSuffix(strongSelf.binaryMessenger, nil, channelSuffix) extraDisposeHandler?() - self?.playersByIdentifier.removeValue(forKey: playerId) + strongSelf.playersByIdentifier.removeValue(forKey: playerId) } // Set up the event channel. @@ -242,6 +275,14 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { } #if os(iOS) + // This function, although slightly modified, is also in camera_avfoundation. + // Both need to do the same thing and run on the same thread (for example main thread). + // Do not overwrite PlayAndRecord with Playback which causes inability to record + // audio, do not overwrite all options. + // Only change category if it is considered an upgrade which means it can only enable + // ability to play in silent mode or ability to record audio but never disables it, + // that could affect other plugins which depend on this global state. Only change + // category or options if there is change to prevent unnecessary lags and silence. private func upgradeAudioSessionCategory( session: FVPAVAudioSession, requestedCategory: AVAudioSession.Category, diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoView.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoView.m index 6c20d144d5aa..606183241c8f 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoView.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_ios/FVPNativeVideoView.m @@ -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 "../video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h" #import diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPCoreVideoDisplayLink.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPCoreVideoDisplayLink.m index 55c3a11996a5..f6b4241bba8a 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPCoreVideoDisplayLink.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_macos/FVPCoreVideoDisplayLink.m @@ -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 "../video_player_avfoundation/include/video_player_avfoundation/FVPDisplayLink.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h" #import #import 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 index 78c68a8b0477..ec2a2a986552 100644 --- 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 @@ -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 "../video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h" #import #import diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m index 3bfa0d63c313..ef5e96dc7d85 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPCADisplayLink.m @@ -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 "../video_player_avfoundation/include/video_player_avfoundation/FVPDisplayLink.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h" @import Foundation; @import QuartzCore; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m index 21d7c4bf6752..dbff03a40ba4 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m @@ -2,11 +2,11 @@ // 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/FVPNativeVideoViewFactory.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h" -#import "../video_player_avfoundation/include/video_player_avfoundation/FVPNativeVideoView.h" -#import "../video_player_avfoundation/include/video_player_avfoundation/FVPVideoPlayer.h" -#import "../video_player_avfoundation/include/video_player_avfoundation/messages.g.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h" +#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h" @interface FVPNativeVideoViewFactory () @property(nonatomic, strong) NSObject *messenger; diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayerPlugin.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayerPlugin.m deleted file mode 100644 index a678657283e4..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPVideoPlayerPlugin.m +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "./include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h" -#import "./include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h" - -@import AVFoundation; - -#import "./include/video_player_avfoundation_objc/FVPAVFactory.h" -#import "./include/video_player_avfoundation_objc/FVPAssetProvider.h" -#import "./include/video_player_avfoundation_objc/FVPDisplayLink.h" -#import "./include/video_player_avfoundation_objc/FVPEventBridge.h" -#import "./include/video_player_avfoundation_objc/FVPFrameUpdater.h" -#import "./include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h" -#import "./include/video_player_avfoundation_objc/FVPTextureBasedVideoPlayer.h" -#import "./include/video_player_avfoundation_objc/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_objc/messages.g.h" - -/// Non-test implementation of the diplay link factory. -@interface FVPDefaultDisplayLinkFactory : NSObject -@end - -@implementation FVPDefaultDisplayLinkFactory -- (NSObject *)displayLinkWithViewProvider:(NSObject *)viewProvider - callback:(void (^)(void))callback { -#if TARGET_OS_IOS - return [[FVPCADisplayLink alloc] initWithViewProvider:viewProvider callback:callback]; -#else - if (@available(macOS 14.0, *)) { - return [[FVPCADisplayLink alloc] initWithViewProvider:viewProvider callback:callback]; - } - return [[FVPCoreVideoDisplayLink alloc] initWithViewProvider:viewProvider callback:callback]; -#endif -} - -@end - -#pragma mark - - -/// Non-test implementation of FVPAssetProvider, wrapping a Flutter plugin -/// registrar. -@interface FVPDefaultAssetProvider : NSObject -@property(weak, nonatomic) NSObject *registrar; - -- (instancetype)initWithRegistrar:(NSObject *)registrar; -@end - -@implementation FVPDefaultAssetProvider - -- (instancetype)initWithRegistrar:(NSObject *)registrar { - self = [super init]; - if (self) { - _registrar = registrar; - } - return self; -} - -- (NSString *)lookupKeyForAsset:(NSString *)asset { - return [self.registrar lookupKeyForAsset:asset]; -} - -- (NSString *)lookupKeyForAsset:(NSString *)asset fromPackage:(NSString *)package { - return [self.registrar lookupKeyForAsset:asset fromPackage:package]; -} - -@end - -#pragma mark - - -@interface FVPVideoPlayerPlugin () -@property(nonatomic, strong) NSObject *binaryMessenger; -@property(nonatomic, strong) NSObject *textureRegistry; -@property(nonatomic, strong) id displayLinkFactory; -@property(nonatomic, strong) id avFactory; -@property(nonatomic, strong) NSObject *viewProvider; -@property(nonatomic, strong) NSObject *assetProvider; -@property(nonatomic, assign) int64_t nextPlayerIdentifier; -@end - -@implementation FVPVideoPlayerPlugin -+ (void)registerWithRegistrar:(NSObject *)registrar { - FVPVideoPlayerPlugin *instance = [[FVPVideoPlayerPlugin alloc] initWithRegistrar:registrar]; - // Publish the instance so that it receives detachFromEngineForRegistrar:. - [registrar publish:instance]; - 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"]; - SetUpFVPAVFoundationVideoPlayerApi(registrar.messenger, instance); -} - -- (instancetype)initWithRegistrar:(NSObject *)registrar { - return [self initWithAVFactory:[[FVPDefaultAVFactory alloc] init] - displayLinkFactory:[[FVPDefaultDisplayLinkFactory alloc] init] - binaryMessenger:registrar.messenger - textureRegistry:registrar.textures - viewProvider:[[FVPDefaultViewProvider alloc] initWithRegistrar:registrar] - assetProvider:[[FVPDefaultAssetProvider alloc] initWithRegistrar:registrar]]; -} - -- (instancetype)initWithAVFactory:(id)avFactory - displayLinkFactory:(id)displayLinkFactory - binaryMessenger:(NSObject *)binaryMessenger - textureRegistry:(NSObject *)textureRegistry - viewProvider:(NSObject *)viewProvider - assetProvider:(NSObject *)assetProvider { - self = [super init]; - NSAssert(self, @"super init cannot be nil"); - _binaryMessenger = binaryMessenger; - _textureRegistry = textureRegistry; - _assetProvider = assetProvider; - _viewProvider = viewProvider; - _displayLinkFactory = displayLinkFactory ?: [[FVPDefaultDisplayLinkFactory alloc] init]; - _avFactory = avFactory ?: [[FVPDefaultAVFactory alloc] init]; - _playersByIdentifier = [NSMutableDictionary dictionaryWithCapacity:1]; - _nextPlayerIdentifier = 1; - return self; -} - -- (void)detachFromEngineForRegistrar:(NSObject *)registrar { - FlutterError *error; - for (FVPVideoPlayer *player in self.playersByIdentifier.allValues) { - // Remove the channel and texture cleanup, and the event listener, to ensure that the player - // doesn't message the engine that is no longer connected. - player.onDisposed = nil; - player.eventListener = nil; - [player disposeWithError:&error]; - } - [self.playersByIdentifier removeAllObjects]; - SetUpFVPAVFoundationVideoPlayerApi(registrar.messenger, nil); -} - -- (int64_t)configurePlayer:(FVPVideoPlayer *)player - withExtraDisposeHandler:(nullable void (^)(void))extraDisposeHandler { - int64_t playerIdentifier = self.nextPlayerIdentifier++; - self.playersByIdentifier[@(playerIdentifier)] = player; - - NSObject *messenger = self.binaryMessenger; - NSString *channelSuffix = [NSString stringWithFormat:@"%lld", playerIdentifier]; - // Set up the player-specific API handler, and its onDispose unregistration. - SetUpFVPVideoPlayerInstanceApiWithSuffix(messenger, player, channelSuffix); - __weak typeof(self) weakSelf = self; - player.onDisposed = ^() { - SetUpFVPVideoPlayerInstanceApiWithSuffix(messenger, nil, channelSuffix); - if (extraDisposeHandler) { - extraDisposeHandler(); - } - [weakSelf.playersByIdentifier removeObjectForKey:@(playerIdentifier)]; - }; - // Set up the event channel. - FVPEventBridge *eventBridge = [[FVPEventBridge alloc] - initWithMessenger:messenger - channelName:[NSString stringWithFormat:@"flutter.dev/videoPlayer/videoEvents%@", - channelSuffix]]; - player.eventListener = eventBridge; - - return playerIdentifier; -} - -// This function, although slightly modified, is also in camera_avfoundation. -// Both need to do the same thing and run on the same thread (for example main thread). -// Do not overwrite PlayAndRecord with Playback which causes inability to record -// audio, do not overwrite all options. -// Only change category if it is considered an upgrade which means it can only enable -// ability to play in silent mode or ability to record audio but never disables it, -// that could affect other plugins which depend on this global state. Only change -// category or options if there is change to prevent unnecessary lags and silence. -#if TARGET_OS_IOS -static void upgradeAudioSessionCategory(NSObject *session, - AVAudioSessionCategory requestedCategory, - AVAudioSessionCategoryOptions options, - AVAudioSessionCategoryOptions clearOptions) { - NSSet *playCategories = [NSSet - setWithObjects:AVAudioSessionCategoryPlayback, AVAudioSessionCategoryPlayAndRecord, nil]; - NSSet *recordCategories = - [NSSet setWithObjects:AVAudioSessionCategoryRecord, AVAudioSessionCategoryPlayAndRecord, nil]; - NSSet *requiredCategories = [NSSet setWithObjects:requestedCategory, session.category, nil]; - BOOL requiresPlay = [requiredCategories intersectsSet:playCategories]; - BOOL requiresRecord = [requiredCategories intersectsSet:recordCategories]; - if (requiresPlay && requiresRecord) { - requestedCategory = AVAudioSessionCategoryPlayAndRecord; - } else if (requiresPlay) { - requestedCategory = AVAudioSessionCategoryPlayback; - } else if (requiresRecord) { - requestedCategory = AVAudioSessionCategoryRecord; - } - options = (session.categoryOptions & ~clearOptions) | options; - if ([requestedCategory isEqualToString:session.category] && options == session.categoryOptions) { - return; - } - [session setCategory:requestedCategory withOptions:options error:nil]; -} -#endif - -- (void)initialize:(FlutterError *__autoreleasing *)error { -#if TARGET_OS_IOS - // Allow audio playback when the Ring/Silent switch is set to silent - upgradeAudioSessionCategory(self.avFactory.sharedAudioSession, AVAudioSessionCategoryPlayback, - /* options */ 0, - /* clearOptions */ 0); -#endif - - FlutterError *disposeError; - // Disposing a player removes it from the dictionary, so iterate over a copy. - NSArray *players = [self.playersByIdentifier.allValues copy]; - for (FVPVideoPlayer *player in players) { - [player disposeWithError:&disposeError]; - } - [self.playersByIdentifier removeAllObjects]; -} - -- (nullable NSNumber *)createPlatformViewPlayerWithOptions:(nonnull FVPCreationOptions *)options - error:(FlutterError **)error { - @try { - NSObject *item = [self playerItemWithCreationOptions:options]; - - // FVPVideoPlayer contains all required logic for platform views. - FVPVideoPlayer *player = [[FVPVideoPlayer alloc] initWithPlayerItem:item - avFactory:self.avFactory - viewProvider:self.viewProvider]; - - return @([self configurePlayer:player withExtraDisposeHandler:nil]); - } @catch (NSException *exception) { - *error = [FlutterError errorWithCode:@"video_player" message:exception.reason details:nil]; - return nil; - } -} - -- (nullable FVPTexturePlayerIds *)createTexturePlayerWithOptions: - (nonnull FVPCreationOptions *)options - error:(FlutterError **)error { - @try { - NSObject *item = [self playerItemWithCreationOptions:options]; - FVPFrameUpdater *frameUpdater = [[FVPFrameUpdater alloc] initWithRegistry:self.textureRegistry]; - NSObject *displayLink = - [self.displayLinkFactory displayLinkWithViewProvider:self.viewProvider - callback:^() { - [frameUpdater displayLinkFired]; - }]; - - FVPTextureBasedVideoPlayer *player = - [[FVPTextureBasedVideoPlayer alloc] initWithPlayerItem:item - frameUpdater:frameUpdater - displayLink:displayLink - avFactory:self.avFactory - viewProvider:self.viewProvider]; - - int64_t textureIdentifier = [self.textureRegistry registerTexture:player]; - [player setTextureIdentifier:textureIdentifier]; - __weak typeof(self) weakSelf = self; - int64_t playerIdentifier = [self configurePlayer:player - withExtraDisposeHandler:^() { - [weakSelf.textureRegistry unregisterTexture:textureIdentifier]; - }]; - return [FVPTexturePlayerIds makeWithPlayerId:playerIdentifier textureId:textureIdentifier]; - } @catch (NSException *exception) { - *error = [FlutterError errorWithCode:@"video_player" message:exception.reason details:nil]; - return nil; - } -} - -- (void)setMixWithOthers:(BOOL)mixWithOthers - error:(FlutterError *_Nullable __autoreleasing *)error { -#if TARGET_OS_OSX - // AVAudioSession doesn't exist on macOS, and audio always mixes, so just no-op. -#else - NSObject *session = self.avFactory.sharedAudioSession; - if (mixWithOthers) { - upgradeAudioSessionCategory(session, session.category, - /* options */ AVAudioSessionCategoryOptionMixWithOthers, - /* clearOptions */ 0); - } else { - upgradeAudioSessionCategory(session, session.category, /* options */ 0, - /* clearOptions */ AVAudioSessionCategoryOptionMixWithOthers); - } -#endif -} - -- (nullable NSString *)fileURLForAssetWithName:(NSString *)asset - package:(nullable NSString *)package - error:(FlutterError *_Nullable *_Nonnull)error { - NSString *resource = package == nil - ? [self.assetProvider lookupKeyForAsset:asset] - : [self.assetProvider lookupKeyForAsset:asset fromPackage:package]; - - NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:nil]; -#if TARGET_OS_OSX - // See https://github.com/flutter/flutter/issues/135302 - // TODO(stuartmorgan): Remove this if the asset APIs are adjusted to work better for macOS. - if (!path) { - path = [NSURL URLWithString:resource relativeToURL:NSBundle.mainBundle.bundleURL].path; - } -#endif - - if (!path) { - return nil; - } - return [NSURL fileURLWithPath:path].absoluteString; -} - -/// Returns the AVPlayerItem corresponding to the given player creation options. -- (nonnull NSObject *)playerItemWithCreationOptions: - (nonnull FVPCreationOptions *)options { - NSDictionary *headers = options.httpHeaders; - NSDictionary *itemOptions = - headers.count == 0 ? nil : @{@"AVURLAssetHTTPHeaderFieldsKey" : headers}; - NSObject *asset = [self.avFactory URLAssetWithURL:[NSURL URLWithString:options.uri] - options:itemOptions]; - return [self.avFactory playerItemWithAsset:asset]; -} - -@end diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h index 7646669069a4..3e4835b24aea 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPDisplayLink.h @@ -6,6 +6,8 @@ #import "FVPViewProvider.h" +NS_ASSUME_NONNULL_BEGIN + // A cross-platform display link abstraction. @protocol FVPDisplayLink @@ -49,3 +51,5 @@ API_AVAILABLE(ios(4.0), macos(14.0)) @end #endif + +NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h index 873361e53d2e..4205e89037e8 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPEventBridge.h @@ -6,6 +6,8 @@ #import "FVPVideoEventListener.h" +NS_ASSUME_NONNULL_BEGIN + #if TARGET_OS_OSX @import FlutterMacOS; #else @@ -20,3 +22,5 @@ channelName:(NSString *)channelName; @end + +NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h index 627195470f6e..ecfdad6035eb 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h @@ -10,6 +10,8 @@ @import Flutter; #endif +NS_ASSUME_NONNULL_BEGIN + /// A class used to create a native video view that can be embedded in a Flutter app. /// This class wraps an AVPlayer instance and displays its video content. #if TARGET_OS_IOS @@ -21,3 +23,6 @@ /// It creates a video view instance and sets the provided AVPlayer instance to it. - (instancetype)initWithPlayer:(AVPlayer *)player; @end + + +NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h index d20d68e64993..485d2dfab4fc 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h @@ -12,11 +12,15 @@ @import Flutter; #endif +NS_ASSUME_NONNULL_BEGIN + /// A factory class responsible for creating native video views that can be embedded in a /// Flutter app. @interface FVPNativeVideoViewFactory : NSObject /// Initializes a new instance of FVPNativeVideoViewFactory with the given messenger and /// a block that provides video players associated with their identifiers. - (instancetype)initWithMessenger:(NSObject *)messenger - playerByIdentifierProvider:(FVPVideoPlayer * (^)(NSNumber *))playerByIdentifierProvider; + playerByIdentifierProvider:(FVPVideoPlayer * _Nullable (^)(NSNumber *))playerByIdentifierProvider; @end + +NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h index a267adbb902b..4787b1111dbe 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoEventListener.h @@ -4,6 +4,8 @@ @import Foundation; +NS_ASSUME_NONNULL_BEGIN + /// Handles event/status callbacks from FVPVideoPlayer. /// /// This is an abstraction around the event channel to avoid coupling FVPVideoPlayer directly to @@ -30,3 +32,5 @@ /// Called when the video player has been disposed on the Dart side. - (void)videoPlayerWasDisposed; @end + +NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h index 02954d7a3680..96f786d49a92 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h @@ -4,7 +4,7 @@ @import AVFoundation; -#import "./messages.g.h" +#import "./VideoPlayerInstanceMessages.g.h" #import "FVPAVFactory.h" #import "FVPVideoEventListener.h" #import "FVPViewProvider.h" diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h deleted file mode 100644 index 447d38731380..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if TARGET_OS_OSX -@import FlutterMacOS; -#else -@import Flutter; -#endif - -NS_ASSUME_NONNULL_BEGIN - -@interface FVPVideoPlayerPlugin : NSObject -- (instancetype)initWithRegistrar:(NSObject *)registrar; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h deleted file mode 100644 index b9ba034edc8d..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayerPlugin_Test.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FVPVideoPlayerPlugin.h" - -#if TARGET_OS_OSX -@import FlutterMacOS; -#else -@import Flutter; -#endif - -#import "FVPAVFactory.h" -#import "FVPAssetProvider.h" -#import "FVPDisplayLink.h" -#import "FVPVideoPlayer.h" -#import "FVPViewProvider.h" -#import "messages.g.h" - -NS_ASSUME_NONNULL_BEGIN - -// Protocol for an AVPlayer instance factory. Used for injecting display links in tests. -@protocol FVPDisplayLinkFactory -- (NSObject *)displayLinkWithViewProvider:(NSObject *)viewProvider - callback:(void (^)(void))callback; -@end - -#pragma mark - - -@interface FVPVideoPlayerPlugin () - -@property(readonly, strong, nonatomic) - NSMutableDictionary *playersByIdentifier; - -- (instancetype)initWithAVFactory:(id)avFactory - displayLinkFactory:(id)displayLinkFactory - binaryMessenger:(NSObject *)binaryMessenger - textureRegistry:(NSObject *)textureRegistry - viewProvider:(NSObject *)viewProvider - assetProvider:(NSObject *)assetProvider; - -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h deleted file mode 100644 index 3b2dd3952245..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/messages.g.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Autogenerated from Pigeon (v26.1.7), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -@import Foundation; - -@protocol FlutterBinaryMessenger; -@protocol FlutterMessageCodec; -@class FlutterError; -@class FlutterStandardTypedData; - -NS_ASSUME_NONNULL_BEGIN - -@class FVPPlatformVideoViewCreationParams; -@class FVPCreationOptions; -@class FVPTexturePlayerIds; -@class FVPMediaSelectionAudioTrackData; - -/// Information passed to the platform view creation. -@interface FVPPlatformVideoViewCreationParams : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithPlayerId:(NSInteger)playerId; -@property(nonatomic, assign) NSInteger playerId; -@end - -@interface FVPCreationOptions : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithUri:(NSString *)uri - httpHeaders:(NSDictionary *)httpHeaders; -@property(nonatomic, copy) NSString *uri; -@property(nonatomic, copy) NSDictionary *httpHeaders; -@end - -@interface FVPTexturePlayerIds : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithPlayerId:(NSInteger)playerId textureId:(NSInteger)textureId; -@property(nonatomic, assign) NSInteger playerId; -@property(nonatomic, assign) NSInteger textureId; -@end - -/// Raw audio track data from AVMediaSelectionOption (for HLS streams). -@interface FVPMediaSelectionAudioTrackData : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithIndex:(NSInteger)index - displayName:(nullable NSString *)displayName - languageCode:(nullable NSString *)languageCode - isSelected:(BOOL)isSelected - commonMetadataTitle:(nullable NSString *)commonMetadataTitle; -@property(nonatomic, assign) NSInteger index; -@property(nonatomic, copy, nullable) NSString *displayName; -@property(nonatomic, copy, nullable) NSString *languageCode; -@property(nonatomic, assign) BOOL isSelected; -@property(nonatomic, copy, nullable) NSString *commonMetadataTitle; -@end - -/// The codec used by all APIs. -NSObject *FVPGetMessagesCodec(void); - -@protocol FVPAVFoundationVideoPlayerApi -- (void)initialize:(FlutterError *_Nullable *_Nonnull)error; -/// @return `nil` only when `error != nil`. -- (nullable NSNumber *)createPlatformViewPlayerWithOptions:(FVPCreationOptions *)params - error:(FlutterError *_Nullable *_Nonnull)error; -/// @return `nil` only when `error != nil`. -- (nullable FVPTexturePlayerIds *) - createTexturePlayerWithOptions:(FVPCreationOptions *)creationOptions - error:(FlutterError *_Nullable *_Nonnull)error; -- (void)setMixWithOthers:(BOOL)mixWithOthers error:(FlutterError *_Nullable *_Nonnull)error; -- (nullable NSString *)fileURLForAssetWithName:(NSString *)asset - package:(nullable NSString *)package - error:(FlutterError *_Nullable *_Nonnull)error; -@end - -extern void SetUpFVPAVFoundationVideoPlayerApi( - id binaryMessenger, - NSObject *_Nullable api); - -extern void SetUpFVPAVFoundationVideoPlayerApiWithSuffix( - id binaryMessenger, - NSObject *_Nullable api, NSString *messageChannelSuffix); - -@protocol FVPVideoPlayerInstanceApi -- (void)setLooping:(BOOL)looping error:(FlutterError *_Nullable *_Nonnull)error; -- (void)setVolume:(double)volume error:(FlutterError *_Nullable *_Nonnull)error; -- (void)setPlaybackSpeed:(double)speed error:(FlutterError *_Nullable *_Nonnull)error; -- (void)playWithError:(FlutterError *_Nullable *_Nonnull)error; -/// @return `nil` only when `error != nil`. -- (nullable NSNumber *)position:(FlutterError *_Nullable *_Nonnull)error; -- (void)seekTo:(NSInteger)position completion:(void (^)(FlutterError *_Nullable))completion; -- (void)pauseWithError:(FlutterError *_Nullable *_Nonnull)error; -- (void)disposeWithError:(FlutterError *_Nullable *_Nonnull)error; -/// @return `nil` only when `error != nil`. -- (nullable NSArray *)getAudioTracks: - (FlutterError *_Nullable *_Nonnull)error; -- (void)selectAudioTrackAtIndex:(NSInteger)trackIndex - error:(FlutterError *_Nullable *_Nonnull)error; -@end - -extern void SetUpFVPVideoPlayerInstanceApi(id binaryMessenger, - NSObject *_Nullable api); - -extern void SetUpFVPVideoPlayerInstanceApiWithSuffix( - id binaryMessenger, NSObject *_Nullable api, - NSString *messageChannelSuffix); - -NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj index a17db2baa66b..6dc0318beeb6 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 60; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -53,8 +53,8 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3300E9FA2F69AA5200842B27 /* TestClasses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestClasses.swift; path = ../../../darwin/RunnerTests/TestClasses.swift; sourceTree = ""; }; - 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoPlayerTests.swift; path = ../../../darwin/RunnerTests/VideoPlayerTests.swift; sourceTree = ""; }; + 3300E9FA2F69AA5200842B27 /* TestClasses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestClasses.swift; path = ../../darwin/RunnerTests/TestClasses.swift; sourceTree = SOURCE_ROOT; }; + 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoPlayerTests.swift; path = ../../darwin/RunnerTests/VideoPlayerTests.swift; sourceTree = SOURCE_ROOT; }; 3300EA022F69AA9500842B27 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3300EA152F69AB0B00842B27 /* VideoPlayerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerUITests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -71,6 +71,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; + 78DABEA22ED26510000E7860 /* video_player_avfoundation */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = video_player_avfoundation; path = ../../darwin/video_player_avfoundation; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -112,6 +114,8 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78DABEA22ED26510000E7860 /* video_player_avfoundation */, + 784666492D4C4C64000A1A5F /* FlutterFramework */, 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, From 86ff3146536852ea0df1a05768e552ac484a6467 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:16:36 -0400 Subject: [PATCH 06/22] Convert native view factory --- .../NativeVideoViewFactory.swift | 65 +++++++++++++++++++ .../FVPNativeVideoViewFactory.m | 47 -------------- .../FVPNativeVideoViewFactory.h | 26 -------- .../FVPVideoPlayer.h | 2 +- 4 files changed, 66 insertions(+), 74 deletions(-) create mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m delete mode 100644 packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift new file mode 100644 index 000000000000..87e3f3640019 --- /dev/null +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +#if canImport(video_player_avfoundation_objc) +import video_player_avfoundation_objc +#endif + +/// A factory class responsible for creating native video views that can be embedded in a +/// Flutter app. +class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { + private let messenger: FlutterBinaryMessenger + private let playerByIdentifierProvider: (NSNumber) -> FVPVideoPlayer? + + /// Initializes a new instance of NativeVideoViewFactory with the given messenger and + /// a block that provides video players associated with their identifiers. + init( + messenger: FlutterBinaryMessenger, + playerByIdentifierProvider: @escaping (NSNumber) -> FVPVideoPlayer? + ) { + self.messenger = messenger + self.playerByIdentifierProvider = playerByIdentifierProvider + super.init() + } + + #if os(macOS) + func create( + withViewIdentifier viewId: Int64, + arguments args: Any? + ) -> NSView { + return createNativeVideoView(arguments: args as! PlatformVideoViewCreationParams) + } + #elseif os(iOS) + func create( + withFrame frame: CGRect, + viewIdentifier viewId: Int64, + arguments args: Any? + ) -> FlutterPlatformView { + return createNativeVideoView(arguments: args as! PlatformVideoViewCreationParams) + } + #endif + + func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { + return VideoPlayerPluginMessagesPigeonCodec.shared + } + + /// Creates a native video view for the given arguments. + private func createNativeVideoView(arguments args: PlatformVideoViewCreationParams) -> FVPNativeVideoView { + let playerIdentifier = NSNumber(value: args.playerId) + // The Dart code should never attempt to create a platform view for a player that doesn't exist, + // and there's no mechanism to report an error, so just force-unwrap. + let player = playerByIdentifierProvider(playerIdentifier)! + return FVPNativeVideoView(player: player.player) + } +} diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m deleted file mode 100644 index dbff03a40ba4..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/FVPNativeVideoViewFactory.m +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h" - -#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h" -#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h" -#import "../video_player_avfoundation_objc/include/video_player_avfoundation_objc/VideoPlayerInstanceMessages.g.h" - -@interface FVPNativeVideoViewFactory () -@property(nonatomic, strong) NSObject *messenger; -@property(nonatomic, copy) FVPVideoPlayer * (^playerByIdProvider)(NSNumber *); -@end - -@implementation FVPNativeVideoViewFactory - -- (instancetype)initWithMessenger:(NSObject *)messenger - playerByIdentifierProvider:(FVPVideoPlayer * (^)(NSNumber *))playerByIdProvider { - self = [super init]; - if (self) { - _messenger = messenger; - _playerByIdProvider = [playerByIdProvider copy]; - } - 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]; -} - -- (NSObject *)createArgsCodec { - return FVPGetMessagesCodec(); -} - -@end diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h deleted file mode 100644 index 485d2dfab4fc..000000000000 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoViewFactory.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -@import Foundation; - -#import "FVPVideoPlayer.h" - -#if TARGET_OS_OSX -@import FlutterMacOS; -#else -@import Flutter; -#endif - -NS_ASSUME_NONNULL_BEGIN - -/// A factory class responsible for creating native video views that can be embedded in a -/// Flutter app. -@interface FVPNativeVideoViewFactory : NSObject -/// Initializes a new instance of FVPNativeVideoViewFactory with the given messenger and -/// a block that provides video players associated with their identifiers. -- (instancetype)initWithMessenger:(NSObject *)messenger - playerByIdentifierProvider:(FVPVideoPlayer * _Nullable (^)(NSNumber *))playerByIdentifierProvider; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h index 96f786d49a92..be10a3317e97 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPVideoPlayer.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN /// FVPVideoPlayer manages video playback using AVPlayer. /// It provides methods for controlling playback, adjusting volume, and handling seeking. /// This class contains all functionalities needed to manage video playback in platform views and is -/// typically used alongside FVPNativeVideoViewFactory. If you need to display a video using a +/// typically used alongside NativeVideoViewFactory. If you need to display a video using a /// texture, use FVPTextureBasedVideoPlayer instead. @interface FVPVideoPlayer : NSObject /// The AVPlayer instance used for video playback. From e2d9cc9881355d0188e94a9409d524730134ca7a Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:35:28 -0400 Subject: [PATCH 07/22] More compilation fixes --- .../video_player_avfoundation/VideoPlayerPlugin.swift | 8 ++++---- .../video_player/video_player_avfoundation/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index aeaef4b2167d..10973b1d2570 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -60,7 +60,7 @@ class DefaultAssetProvider: NSObject, FVPAssetProvider { } } -class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { +public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { private let binaryMessenger: FlutterBinaryMessenger private let textureRegistry: FlutterTextureRegistry private let displayLinkFactory: DisplayLinkFactory @@ -70,7 +70,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { private var nextPlayerIdentifier: Int64 = 1 var playersByIdentifier: [Int64: FVPVideoPlayer] = [:] - static func register(with registrar: FlutterPluginRegistrar) { + public static func register(with registrar: FlutterPluginRegistrar) { let instance = VideoPlayerPlugin(registrar: registrar) // Publish the instance so that it receives detachFromEngine. registrar.publish(instance) @@ -80,7 +80,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { #else let messenger = registrar.messenger #endif - let factory = FVPNativeVideoViewFactory( + let factory = NativeVideoViewFactory( messenger: messenger, playerByIdentifierProvider: { [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in return instance?.playersByIdentifier[playerIdentifier.int64Value] @@ -126,7 +126,7 @@ class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideoPlayerApi { super.init() } - func detachFromEngine(for registrar: FlutterPluginRegistrar) { + public func detachFromEngine(for registrar: FlutterPluginRegistrar) { for player in playersByIdentifier.values { // Remove the channel and texture cleanup, and the event listener, to ensure that the player // doesn't message the engine that is no longer connected. diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index a901ef5dc867..ad24deeaa2b8 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -14,11 +14,11 @@ flutter: platforms: ios: dartPluginClass: AVFoundationVideoPlayer - pluginClass: FVPVideoPlayerPlugin + pluginClass: VideoPlayerPlugin sharedDarwinSource: true macos: dartPluginClass: AVFoundationVideoPlayer - pluginClass: FVPVideoPlayerPlugin + pluginClass: VideoPlayerPlugin sharedDarwinSource: true dependencies: From 412a03b1fcfca028ae22dc0819e8158aac10799c Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:35:58 -0400 Subject: [PATCH 08/22] autoformat --- .../video_player_avfoundation/Package.swift | 6 +- .../NativeVideoViewFactory.swift | 6 +- .../VideoPlayerPlugin.swift | 62 ++++++++++--------- .../FVPNativeVideoView.h | 1 - 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift index 26031b0426c8..54155f14693b 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Package.swift @@ -39,13 +39,15 @@ let package = Package( .target( name: "video_player_avfoundation_ios", cSettings: [ - .headerSearchPath("../video_player_avfoundation_objc/include/video_player_avfoundation_objc") + .headerSearchPath( + "../video_player_avfoundation_objc/include/video_player_avfoundation_objc") ] ), .target( name: "video_player_avfoundation_macos", cSettings: [ - .headerSearchPath("../video_player_avfoundation_objc/include/video_player_avfoundation_objc") + .headerSearchPath( + "../video_player_avfoundation_objc/include/video_player_avfoundation_objc") ] ), ] diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift index 87e3f3640019..7c31e0556d1c 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift @@ -13,7 +13,7 @@ import Foundation #endif #if canImport(video_player_avfoundation_objc) -import video_player_avfoundation_objc + import video_player_avfoundation_objc #endif /// A factory class responsible for creating native video views that can be embedded in a @@ -55,7 +55,9 @@ class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { } /// Creates a native video view for the given arguments. - private func createNativeVideoView(arguments args: PlatformVideoViewCreationParams) -> FVPNativeVideoView { + private func createNativeVideoView(arguments args: PlatformVideoViewCreationParams) + -> FVPNativeVideoView + { let playerIdentifier = NSNumber(value: args.playerId) // The Dart code should never attempt to create a platform view for a player that doesn't exist, // and there's no mechanism to report an error, so just force-unwrap. diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index 10973b1d2570..4d80b9294956 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -13,7 +13,7 @@ import AVFoundation #endif #if canImport(video_player_avfoundation_objc) -import video_player_avfoundation_objc + import video_player_avfoundation_objc #endif // Protocol for an display link factory. Used for injecting display links in tests. @@ -74,31 +74,32 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo let instance = VideoPlayerPlugin(registrar: registrar) // Publish the instance so that it receives detachFromEngine. registrar.publish(instance) - -#if os(iOS) - let messenger = registrar.messenger() -#else - let messenger = registrar.messenger -#endif + + #if os(iOS) + let messenger = registrar.messenger() + #else + let messenger = registrar.messenger + #endif let factory = NativeVideoViewFactory( messenger: messenger, - playerByIdentifierProvider: { [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in + playerByIdentifierProvider: { + [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in return instance?.playersByIdentifier[playerIdentifier.int64Value] } ) registrar.register(factory, withId: "plugins.flutter.dev/video_player_ios") - + AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: messenger, api: instance) } convenience init(registrar: FlutterPluginRegistrar) { -#if os(iOS) - let messenger = registrar.messenger() - let textures = registrar.textures() -#else - let messenger = registrar.messenger - let textures = registrar.textures -#endif + #if os(iOS) + let messenger = registrar.messenger() + let textures = registrar.textures() + #else + let messenger = registrar.messenger + let textures = registrar.textures + #endif self.init( avFactory: FVPDefaultAVFactory(), displayLinkFactory: DefaultDisplayLinkFactory(), @@ -136,11 +137,11 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo player.disposeWithError(&error) } playersByIdentifier.removeAll() -#if os(iOS) - let messenger = registrar.messenger() -#else - let messenger = registrar.messenger -#endif + #if os(iOS) + let messenger = registrar.messenger() + #else + let messenger = registrar.messenger + #endif AVFoundationVideoPlayerApiSetup.setUp(binaryMessenger: messenger, api: nil) } @@ -216,7 +217,8 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo } func fileURLForAsset(name asset: String, package: String?) throws -> String? { - let resource = package == nil + let resource = + package == nil ? assetProvider.lookupKey(forAsset: asset) : assetProvider.lookupKey(forAsset: asset, fromPackage: package!) @@ -237,7 +239,9 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo // MARK: - Private - private func configurePlayer(_ player: FVPVideoPlayer, extraDisposeHandler: (() -> Void)?) -> Int64 { + private func configurePlayer(_ player: FVPVideoPlayer, extraDisposeHandler: (() -> Void)?) + -> Int64 + { let playerId = nextPlayerIdentifier nextPlayerIdentifier += 1 playersByIdentifier[playerId] = player @@ -245,7 +249,7 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo let channelSuffix = "\(playerId)" // Set up the player-specific API handler, and its onDispose unregistration. SetUpFVPVideoPlayerInstanceApiWithSuffix(binaryMessenger, player, channelSuffix) - + player.onDisposed = { [weak self] in guard let strongSelf = self else { return } SetUpFVPVideoPlayerInstanceApiWithSuffix(strongSelf.binaryMessenger, nil, channelSuffix) @@ -292,10 +296,10 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo let playCategories: Set = [.playback, .playAndRecord] let recordCategories: Set = [.record, .playAndRecord] let requiredCategories: Set = [requestedCategory, session.category] - + let requiresPlay = !requiredCategories.isDisjoint(with: playCategories) let requiresRecord = !requiredCategories.isDisjoint(with: recordCategories) - + var finalCategory = requestedCategory if requiresPlay && requiresRecord { finalCategory = .playAndRecord @@ -304,13 +308,13 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo } else if requiresRecord { finalCategory = .record } - + let newOptions = session.categoryOptions.subtracting(clearOptions).union(options) - + if finalCategory == session.category && newOptions == session.categoryOptions { return } - + try? session.setCategory(finalCategory, with: newOptions) } #endif diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h index ecfdad6035eb..23aabe08214f 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation_objc/include/video_player_avfoundation_objc/FVPNativeVideoView.h @@ -24,5 +24,4 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithPlayer:(AVPlayer *)player; @end - NS_ASSUME_NONNULL_END From 2d73daa8bfc8862235124d5af2167d7abdb74f03 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:38:50 -0400 Subject: [PATCH 09/22] Manual Swift style --- .../video_player_avfoundation/NativeVideoViewFactory.swift | 6 +++--- .../video_player_avfoundation/VideoPlayerPlugin.swift | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift index 7c31e0556d1c..b3546d62f9ba 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift @@ -55,9 +55,9 @@ class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { } /// Creates a native video view for the given arguments. - private func createNativeVideoView(arguments args: PlatformVideoViewCreationParams) - -> FVPNativeVideoView - { + private func createNativeVideoView( + arguments args: PlatformVideoViewCreationParams + ) -> FVPNativeVideoView { let playerIdentifier = NSNumber(value: args.playerId) // The Dart code should never attempt to create a platform view for a player that doesn't exist, // and there's no mechanism to report an error, so just force-unwrap. diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index 4d80b9294956..35341c14804a 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -239,9 +239,10 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo // MARK: - Private - private func configurePlayer(_ player: FVPVideoPlayer, extraDisposeHandler: (() -> Void)?) - -> Int64 - { + private func configurePlayer( + _ player: FVPVideoPlayer, + extraDisposeHandler: (() -> Void)? + ) -> Int64 { let playerId = nextPlayerIdentifier nextPlayerIdentifier += 1 playersByIdentifier[playerId] = player From 6e6cbbca50b575eece2937fbd399ccc09005e374 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:50:34 -0400 Subject: [PATCH 10/22] Eliminate NSNumber --- .../video_player_avfoundation/NativeVideoViewFactory.swift | 7 +++---- .../video_player_avfoundation/VideoPlayerPlugin.swift | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift index b3546d62f9ba..d3dac3a23776 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift @@ -20,13 +20,13 @@ import Foundation /// Flutter app. class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { private let messenger: FlutterBinaryMessenger - private let playerByIdentifierProvider: (NSNumber) -> FVPVideoPlayer? + private let playerByIdentifierProvider: (Int64) -> FVPVideoPlayer? /// Initializes a new instance of NativeVideoViewFactory with the given messenger and /// a block that provides video players associated with their identifiers. init( messenger: FlutterBinaryMessenger, - playerByIdentifierProvider: @escaping (NSNumber) -> FVPVideoPlayer? + playerByIdentifierProvider: @escaping (Int64) -> FVPVideoPlayer? ) { self.messenger = messenger self.playerByIdentifierProvider = playerByIdentifierProvider @@ -58,10 +58,9 @@ class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { private func createNativeVideoView( arguments args: PlatformVideoViewCreationParams ) -> FVPNativeVideoView { - let playerIdentifier = NSNumber(value: args.playerId) // The Dart code should never attempt to create a platform view for a player that doesn't exist, // and there's no mechanism to report an error, so just force-unwrap. - let player = playerByIdentifierProvider(playerIdentifier)! + let player = playerByIdentifierProvider(args.playerId)! return FVPNativeVideoView(player: player.player) } } diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index 35341c14804a..c63df7dde2a8 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -83,8 +83,8 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo let factory = NativeVideoViewFactory( messenger: messenger, playerByIdentifierProvider: { - [weak instance] (playerIdentifier: NSNumber) -> FVPVideoPlayer? in - return instance?.playersByIdentifier[playerIdentifier.int64Value] + [weak instance] (playerIdentifier: Int64) -> FVPVideoPlayer? in + return instance?.playersByIdentifier[playerIdentifier] } ) registrar.register(factory, withId: "plugins.flutter.dev/video_player_ios") From b8d7dba9ffccccaf4842fad5edfffe426910c9ad Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:53:59 -0400 Subject: [PATCH 11/22] Replace force unwrap with if let idiom --- .../video_player_avfoundation/VideoPlayerPlugin.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index c63df7dde2a8..f39986740257 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -218,9 +218,11 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo func fileURLForAsset(name asset: String, package: String?) throws -> String? { let resource = - package == nil - ? assetProvider.lookupKey(forAsset: asset) - : assetProvider.lookupKey(forAsset: asset, fromPackage: package!) + if let package = package { + assetProvider.lookupKey(forAsset: asset, fromPackage: package) + } else { + assetProvider.lookupKey(forAsset: asset) + } var path = Bundle.main.path(forResource: resource, ofType: nil) #if os(macOS) From 5cbd7a45591d5df7b9d1d3e433413723122193b5 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 11:57:34 -0400 Subject: [PATCH 12/22] Minor class declaration cleanup --- .../Sources/video_player_avfoundation/VideoPlayerPlugin.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index f39986740257..7851b1198aae 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -25,7 +25,7 @@ protocol DisplayLinkFactory { } /// Non-test implementation of the display link factory. -class DefaultDisplayLinkFactory: NSObject, DisplayLinkFactory { +final class DefaultDisplayLinkFactory: DisplayLinkFactory { func displayLink( with viewProvider: FVPViewProvider, callback: @escaping () -> Void @@ -43,7 +43,7 @@ class DefaultDisplayLinkFactory: NSObject, DisplayLinkFactory { /// Non-test implementation of FVPAssetProvider, wrapping a Flutter plugin /// registrar. -class DefaultAssetProvider: NSObject, FVPAssetProvider { +final class DefaultAssetProvider: NSObject, FVPAssetProvider { private weak var registrar: FlutterPluginRegistrar? init(registrar: FlutterPluginRegistrar) { From 702638b0ed50e54f4764d55fc9658381b29e3a85 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 12:02:44 -0400 Subject: [PATCH 13/22] Test fixup WIP --- .../darwin/RunnerTests/TestClasses.swift | 5 ++- .../darwin/RunnerTests/VideoPlayerTests.swift | 41 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift index 3856995b855c..e34b40e3059e 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift @@ -4,7 +4,8 @@ import AVFoundation import Testing -import video_player_avfoundation +@testable import video_player_avfoundation +import video_player_avfoundation_objc #if os(iOS) import Flutter @@ -249,7 +250,7 @@ final class StubFVPDisplayLink: NSObject, FVPDisplayLink { } } -final class StubFVPDisplayLinkFactory: NSObject, FVPDisplayLinkFactory { +final class StubFVPDisplayLinkFactory: DisplayLinkFactory { let displayLink = StubFVPDisplayLink() var fireDisplayLink: (() -> Void)? diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift index c965a70a8430..ffa10ddf8206 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift @@ -4,7 +4,8 @@ import AVFoundation import Testing -@preconcurrency import video_player_avfoundation +@preconcurrency @testable import video_player_avfoundation +import video_player_avfoundation_objc #if os(iOS) import Flutter @@ -46,7 +47,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let player = @@ -64,7 +65,7 @@ private let hlsAudioTestURI = var error: FlutterError? videoPlayerPlugin.createPlatformViewPlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error) #expect(error == nil) @@ -83,7 +84,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let player = @@ -119,7 +120,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) @@ -148,7 +149,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error) #expect(error == nil) let player = @@ -180,7 +181,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error) #expect(error == nil) let player = @@ -205,7 +206,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: hlsTestURI, httpHeaders: [:]), + with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), error: &error) #expect(error == nil) let player = @@ -225,7 +226,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer @@ -244,7 +245,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer @@ -460,7 +461,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) @@ -505,7 +506,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) @@ -538,7 +539,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: "", httpHeaders: [:]), error: &error) + with: CreationOptions(uri: "", httpHeaders: [:]), error: &error) #expect(error == nil) let player = videoPlayerPlugin.playersByIdentifier[identifiers!.playerId] as! FVPVideoPlayer @@ -588,7 +589,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let playerIdentifier = identifiers.playerId @@ -619,7 +620,7 @@ private let hlsAudioTestURI = var error: FlutterError? let identifiers = try #require( videoPlayerPlugin.createTexturePlayer( - with: FVPCreationOptions.make(withUri: mp4TestURI, httpHeaders: [:]), + with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), error: &error)) #expect(error == nil) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer @@ -808,22 +809,20 @@ private let hlsAudioTestURI = /// then initializes it. private func createInitializedPlugin( avFactory: FVPAVFactory = StubFVPAVFactory(), - displayLinkFactory: FVPDisplayLinkFactory = StubFVPDisplayLinkFactory(), + displayLinkFactory: DisplayLinkFactory = StubFVPDisplayLinkFactory(), binaryMessenger: FlutterBinaryMessenger = StubBinaryMessenger(), textureRegistry: FlutterTextureRegistry = TestTextureRegistry(), viewProvider: FVPViewProvider = StubViewProvider(), assetProvider: FVPAssetProvider = StubAssetProvider() - ) -> FVPVideoPlayerPlugin { - let plugin = FVPVideoPlayerPlugin( + ) throws -> VideoPlayerPlugin { + let plugin = VideoPlayerPlugin( avFactory: avFactory, displayLinkFactory: displayLinkFactory, binaryMessenger: binaryMessenger, textureRegistry: textureRegistry, viewProvider: viewProvider, assetProvider: assetProvider) - var error: FlutterError? - plugin.initialize(&error) - #expect(error == nil) + try plugin.initialize() return plugin } From 623c375a6c20857be77d14434abb23c0e126bef4 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 12:27:05 -0400 Subject: [PATCH 14/22] Update unit tests --- .../darwin/RunnerTests/TestClasses.swift | 3 +- .../darwin/RunnerTests/VideoPlayerTests.swift | 182 +++++++----------- 2 files changed, 69 insertions(+), 116 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift index e34b40e3059e..2dbef61b2f45 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/TestClasses.swift @@ -4,9 +4,10 @@ import AVFoundation import Testing -@testable import video_player_avfoundation import video_player_avfoundation_objc +@testable import video_player_avfoundation + #if os(iOS) import Flutter import UIKit diff --git a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift index ffa10ddf8206..7d776258c4cc 100644 --- a/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift +++ b/packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.swift @@ -42,32 +42,25 @@ private let hlsAudioTestURI = view.wantsLayer = true let viewProvider = StubViewProvider(view: view) #endif - let videoPlayerPlugin = createInitializedPlugin(viewProvider: viewProvider) + let videoPlayerPlugin = try createInitializedPlugin(viewProvider: viewProvider) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer #expect(player.playerLayer.superlayer == view.layer) } - @Test func playerForPlatformViewDoesNotRegisterTexture() { + @Test func playerForPlatformViewDoesNotRegisterTexture() throws { let textureRegistry = TestTextureRegistry() let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( displayLinkFactory: stubDisplayLinkFactory, textureRegistry: textureRegistry) - var error: FlutterError? - videoPlayerPlugin.createPlatformViewPlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error) - #expect(error == nil) + _ = try videoPlayerPlugin.createPlatformViewPlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) #expect(!textureRegistry.registeredTexture) } @@ -77,20 +70,17 @@ private let hlsAudioTestURI = let mockVideoOutput = TestPixelBufferSource() // Display link and frame updater wire-up is currently done in FVPVideoPlayerPlugin, so create // the player via the plugin instead of directly to include that logic in the test. - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( avFactory: StubFVPAVFactory(pixelBufferSource: mockVideoOutput), displayLinkFactory: stubDisplayLinkFactory) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer // Ensure that the video playback is paused before seeking. + var error: FlutterError? player.pauseWithError(&error) #expect(error == nil) @@ -113,16 +103,12 @@ private let hlsAudioTestURI = @Test func initStartsDisplayLinkTemporarily() throws { let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() let mockVideoOutput = TestPixelBufferSource() - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( avFactory: StubFVPAVFactory(pixelBufferSource: mockVideoOutput), displayLinkFactory: stubDisplayLinkFactory) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) // Init should start the display link temporarily. #expect(stubDisplayLinkFactory.displayLink.running) @@ -140,22 +126,20 @@ private let hlsAudioTestURI = #expect(!stubDisplayLinkFactory.displayLink.running) } - @Test func seekToWhilePlayingDoesNotStopDisplayLink() async { + @Test func seekToWhilePlayingDoesNotStopDisplayLink() async throws { let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() let mockVideoOutput = TestPixelBufferSource() - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( avFactory: StubFVPAVFactory(pixelBufferSource: mockVideoOutput), displayLinkFactory: stubDisplayLinkFactory) - var error: FlutterError? - let identifiers = videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) let player = - videoPlayerPlugin.playersByIdentifier[identifiers!.playerId] as! FVPTextureBasedVideoPlayer + videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer // Ensure that the video is playing before seeking. + var error: FlutterError? player.playWithError(&error) #expect(error == nil) @@ -173,21 +157,19 @@ private let hlsAudioTestURI = #expect(stubDisplayLinkFactory.displayLink.running) } - @Test func pauseWhileWaitingForFrameDoesNotStopDisplayLink() { + @Test func pauseWhileWaitingForFrameDoesNotStopDisplayLink() throws { let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() // Display link and frame updater wire-up is currently done in FVPVideoPlayerPlugin, so create // the player via the plugin instead of directly to include that logic in the test. - let videoPlayerPlugin = createInitializedPlugin(displayLinkFactory: stubDisplayLinkFactory) + let videoPlayerPlugin = try createInitializedPlugin(displayLinkFactory: stubDisplayLinkFactory) - var error: FlutterError? - let identifiers = videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) let player = - videoPlayerPlugin.playersByIdentifier[identifiers!.playerId] as! FVPTextureBasedVideoPlayer + videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer // Run a play/pause cycle to force the pause codepath to run completely. + var error: FlutterError? player.playWithError(&error) #expect(error == nil) player.pauseWithError(&error) @@ -197,20 +179,18 @@ private let hlsAudioTestURI = #expect(stubDisplayLinkFactory.displayLink.running) } - @Test func disposeWhilePlayingStopsDisplayLink() async { + @Test func disposeWhilePlayingStopsDisplayLink() async throws { let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() let mockVideoOutput = TestPixelBufferSource() - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( avFactory: StubFVPAVFactory(pixelBufferSource: mockVideoOutput), displayLinkFactory: stubDisplayLinkFactory) var error: FlutterError? - let identifiers = videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: hlsTestURI, httpHeaders: [:]), - error: &error) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: hlsTestURI, httpHeaders: [:])) let player = - videoPlayerPlugin.playersByIdentifier[identifiers!.playerId] as! FVPTextureBasedVideoPlayer + videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer player.playWithError(&error) #expect(error == nil) @@ -221,16 +201,13 @@ private let hlsAudioTestURI = } @Test func deregistersFromPlayer() throws { - let videoPlayerPlugin = createInitializedPlugin() + let videoPlayerPlugin = try createInitializedPlugin() - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) - let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) + let player = try #require(videoPlayerPlugin.playersByIdentifier[identifiers.playerId]) + var error: FlutterError? player.disposeWithError(&error) #expect(error == nil) #expect(videoPlayerPlugin.playersByIdentifier.count == 0) @@ -240,15 +217,11 @@ private let hlsAudioTestURI = // TODO(stuartmorgan): Rewrite this test to use stubs, instead of running for 10 // seconds with a real player and hoping to get buffer status updates. let realObjectFactory = FVPDefaultAVFactory() - let videoPlayerPlugin = createInitializedPlugin(avFactory: realObjectFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: realObjectFactory) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) - let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) + let player = try #require(videoPlayerPlugin.playersByIdentifier[identifiers.playerId]) let avPlayer = player.player avPlayer.play() @@ -456,16 +429,13 @@ private let hlsAudioTestURI = // Autoreleasepool is needed to simulate conditions of FVPVideoPlayer deallocation. try autoreleasepool { - let videoPlayerPlugin = createInitializedPlugin(avFactory: realObjectFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: realObjectFactory) var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) - let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer + let player = try #require(videoPlayerPlugin.playersByIdentifier[identifiers.playerId]) weakPlayer = player avPlayer = player.player @@ -501,14 +471,10 @@ private let hlsAudioTestURI = // Autoreleasepool is needed to simulate conditions of FVPVideoPlayer deallocation. try autoreleasepool { - let videoPlayerPlugin = createInitializedPlugin(avFactory: StubFVPAVFactory()) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: StubFVPAVFactory()) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPTextureBasedVideoPlayer @@ -516,8 +482,7 @@ private let hlsAudioTestURI = player.onTextureUnregistered(StubTexture()) - videoPlayerPlugin.initialize(&error) - #expect(error == nil) + try videoPlayerPlugin.initialize() } // Wait for the weak pointer to be invalidated, indicating that the player has been deallocated. @@ -532,16 +497,15 @@ private let hlsAudioTestURI = // No assertions needed. Lack of crash is a success. } - @Test func failedToLoadVideoEventShouldBeAlwaysSent() async { + @Test func failedToLoadVideoEventShouldBeAlwaysSent() async throws { // Use real objects to test a real failure flow. let realObjectFactory = FVPDefaultAVFactory() - let videoPlayerPlugin = createInitializedPlugin(avFactory: realObjectFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: realObjectFactory) - var error: FlutterError? - let identifiers = videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: "", httpHeaders: [:]), error: &error) - #expect(error == nil) - let player = videoPlayerPlugin.playersByIdentifier[identifiers!.playerId] as! FVPVideoPlayer + // Provide a URI that is a valid URI, but not a video, to trigger a failure inside AVPlayer. + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: "https://flutter.dev", httpHeaders: [:])) + let player = try #require(videoPlayerPlugin.playersByIdentifier[identifiers.playerId]) await withCheckedContinuation { continuation in // TODO(stuartmorgan): Update this test to instead use a mock listener, and add separate unit @@ -581,17 +545,13 @@ private let hlsAudioTestURI = let textureRegistry = TestTextureRegistry() let stubDisplayLinkFactory = StubFVPDisplayLinkFactory() let mockVideoOutput = TestPixelBufferSource() - let videoPlayerPlugin = createInitializedPlugin( + let videoPlayerPlugin = try createInitializedPlugin( avFactory: StubFVPAVFactory(pixelBufferSource: mockVideoOutput), displayLinkFactory: stubDisplayLinkFactory, textureRegistry: textureRegistry) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) let playerIdentifier = identifiers.playerId let player = videoPlayerPlugin.playersByIdentifier[playerIdentifier] as! FVPTextureBasedVideoPlayer @@ -615,15 +575,11 @@ private let hlsAudioTestURI = @Test func videoOutputIsAddedWhenAVPlayerIsInitialized() async throws { let realObjectFactory = FVPDefaultAVFactory() - let videoPlayerPlugin = createInitializedPlugin(avFactory: realObjectFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: realObjectFactory) - var error: FlutterError? - let identifiers = try #require( - videoPlayerPlugin.createTexturePlayer( - with: CreationOptions(uri: mp4TestURI, httpHeaders: [:]), - error: &error)) - #expect(error == nil) - let player = videoPlayerPlugin.playersByIdentifier[identifiers.playerId] as! FVPVideoPlayer + let identifiers = try videoPlayerPlugin.createTexturePlayer( + options: CreationOptions(uri: mp4TestURI, httpHeaders: [:])) + let player = try #require(videoPlayerPlugin.playersByIdentifier[identifiers.playerId]) let listener = StubEventListener() await withCheckedContinuation { continuation in @@ -637,33 +593,29 @@ private let hlsAudioTestURI = } #if os(iOS) - @Test func videoPlayerShouldNotOverwritePlayAndRecordNorDefaultToSpeaker() { + @Test func videoPlayerShouldNotOverwritePlayAndRecordNorDefaultToSpeaker() throws { let stubFactory = StubFVPAVFactory() let audioSession = TestAudioSession() stubFactory.audioSession = audioSession audioSession.category = .playAndRecord audioSession.categoryOptions = .defaultToSpeaker - let videoPlayerPlugin = createInitializedPlugin(avFactory: stubFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: stubFactory) - var error: FlutterError? - videoPlayerPlugin.setMixWithOthers(true, error: &error) - #expect(error == nil) + try videoPlayerPlugin.setMixWithOthers(true) #expect(audioSession.category == .playAndRecord) #expect(audioSession.categoryOptions.contains(.defaultToSpeaker)) #expect(audioSession.categoryOptions.contains(.mixWithOthers)) } - @Test func setMixWithOthersShouldNoOpWhenNoChangesAreRequired() { + @Test func setMixWithOthersShouldNoOpWhenNoChangesAreRequired() throws { let stubFactory = StubFVPAVFactory() let audioSession = TestAudioSession() stubFactory.audioSession = audioSession audioSession.category = .playAndRecord audioSession.categoryOptions = [.mixWithOthers, .defaultToSpeaker] - let videoPlayerPlugin = createInitializedPlugin(avFactory: stubFactory) + let videoPlayerPlugin = try createInitializedPlugin(avFactory: stubFactory) - var error: FlutterError? - videoPlayerPlugin.setMixWithOthers(true, error: &error) - #expect(error == nil) + try videoPlayerPlugin.setMixWithOthers(true) #expect(!audioSession.setCategoryCalled) } #endif From 0c20da54b5c8d58c0e2c43e5ca0ef3e2c3a5f451 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 13:38:38 -0400 Subject: [PATCH 15/22] Fix macOS optionality handling --- .../Sources/video_player_avfoundation/VideoPlayerPlugin.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift index 7851b1198aae..951f3bcfed67 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/VideoPlayerPlugin.swift @@ -228,7 +228,7 @@ public final class VideoPlayerPlugin: NSObject, FlutterPlugin, AVFoundationVideo #if os(macOS) // See https://github.com/flutter/flutter/issues/135302 // TODO(stuartmorgan): Remove this if the asset APIs are adjusted to work better for macOS. - if path == nil { + if path == nil, let resource = resource { path = URL(string: resource, relativeTo: Bundle.main.bundleURL)?.path } #endif From a9d7f3d60bd0e28dc0c86bc967cfe1bae22bebdc Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 13:42:24 -0400 Subject: [PATCH 16/22] Version bump --- packages/video_player/video_player_avfoundation/CHANGELOG.md | 4 ++++ .../example/macos/Runner.xcodeproj/project.pbxproj | 2 +- packages/video_player/video_player_avfoundation/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md index 1508c0bbfe22..42a8ea8b0a26 100644 --- a/packages/video_player/video_player_avfoundation/CHANGELOG.md +++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.9.5 + +* Converts portions of the native code to Swift for improved maintainability. + ## 2.9.4 * Ensures that the display link does not continue requesting frames after a player is disposed. diff --git a/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj index adcd95672227..be61fa896ebe 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 60; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index ad24deeaa2b8..9e6a8dcfa46d 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.9.4 +version: 2.9.5 environment: sdk: ^3.10.0 From 7207a9de2ad5b5db7fad8d0c23eb43b2f18eabe7 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 13:54:14 -0400 Subject: [PATCH 17/22] Revert incidental project change from building --- .../example/ios/Flutter/Debug.xcconfig | 1 + .../example/ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 122 +++++++++++++++++- .../contents.xcworkspacedata | 3 + .../macos/Flutter/Flutter-Debug.xcconfig | 1 + .../macos/Flutter/Flutter-Release.xcconfig | 1 + .../macos/Runner.xcodeproj/project.pbxproj | 2 +- 7 files changed, 124 insertions(+), 7 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig index 592ceee85b89..ec97fc6f3021 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig index 592ceee85b89..c4855bfe2000 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj index 6dc0318beeb6..510634e13929 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2B2331B0DCF5C9DE826AE4AE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */; }; 3300E9FC2F69AA5200842B27 /* TestClasses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300E9FA2F69AA5200842B27 /* TestClasses.swift */; }; 3300E9FD2F69AA5200842B27 /* VideoPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */; }; 3300EA1A2F69AB0B00842B27 /* VideoPlayerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300EA152F69AB0B00842B27 /* VideoPlayerUITests.swift */; }; @@ -18,6 +19,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + BAE1F70AACA38E87C7212ED2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A77052BBA99787E1564A5920 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -51,19 +53,27 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 2D05C2911DD61BE6B3A0C0E7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3300E9FA2F69AA5200842B27 /* TestClasses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestClasses.swift; path = ../../darwin/RunnerTests/TestClasses.swift; sourceTree = SOURCE_ROOT; }; 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoPlayerTests.swift; path = ../../darwin/RunnerTests/VideoPlayerTests.swift; sourceTree = SOURCE_ROOT; }; 3300EA022F69AA9500842B27 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3300EA152F69AB0B00842B27 /* VideoPlayerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerUITests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 611B0FCE3CD39649391110BF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 78DABEA22ED26510000E7860 /* video_player_avfoundation */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = video_player_avfoundation; path = ../../darwin/video_player_avfoundation; sourceTree = ""; }; 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 907E8A244FFE06143C52C754 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -71,8 +81,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; - 78DABEA22ED26510000E7860 /* video_player_avfoundation */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = video_player_avfoundation; path = ../../darwin/video_player_avfoundation; sourceTree = ""; }; + A77052BBA99787E1564A5920 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,6 +98,15 @@ buildActionMask = 2147483647; files = ( 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + BAE1F70AACA38E87C7212ED2 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8666A13ABEDBB85EF214615 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B2331B0DCF5C9DE826AE4AE /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -111,6 +130,20 @@ path = RunnerTests; sourceTree = ""; }; + 78E6C4C672418F816AD1151B /* Pods */ = { + isa = PBXGroup; + children = ( + 2D05C2911DD61BE6B3A0C0E7 /* Pods-Runner.debug.xcconfig */, + 907E8A244FFE06143C52C754 /* Pods-Runner.release.xcconfig */, + 611B0FCE3CD39649391110BF /* Pods-Runner.profile.xcconfig */, + E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */, + 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */, + 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -133,6 +166,8 @@ 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, 3300EA162F69AB0B00842B27 /* RunnerUITests */, + 78E6C4C672418F816AD1151B /* Pods */, + BEF19F0C8AF7D72171D0F01C /* Frameworks */, ); sourceTree = ""; }; @@ -162,6 +197,15 @@ path = Runner; sourceTree = ""; }; + BEF19F0C8AF7D72171D0F01C /* Frameworks */ = { + isa = PBXGroup; + children = ( + A77052BBA99787E1564A5920 /* Pods_Runner.framework */, + 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -179,8 +223,6 @@ 3300EA092F69AA9500842B27 /* PBXTargetDependency */, ); name = RunnerUITests; - packageProductDependencies = ( - ); productName = RunnerUITests; productReference = 3300EA022F69AA9500842B27 /* RunnerUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -189,8 +231,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 39E9E3BDE0A57095C4D1003C /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + E8666A13ABEDBB85EF214615 /* Frameworks */, ); buildRules = ( ); @@ -206,12 +250,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + CB7DDF42E600F5D50568129D /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 9D0A52E2A788D630AA7DAF31 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -260,7 +306,7 @@ ); mainGroup = 97C146E51CF9000F007C117D; packageReferences = ( - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; @@ -302,6 +348,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 39E9E3BDE0A57095C4D1003C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -333,6 +401,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + 9D0A52E2A788D630AA7DAF31 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + CB7DDF42E600F5D50568129D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -523,6 +630,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -540,6 +648,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -555,6 +664,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -768,7 +878,7 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { isa = XCLocalSwiftPackageReference; relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; }; diff --git a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..21a3cc14c74e 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b608ba..4b81f9b2d200 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig index c2efd0b608ba..5caa9d1579e4 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj index be61fa896ebe..adcd95672227 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player_avfoundation/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 60; objects = { /* Begin PBXAggregateTarget section */ From 07909894125ca6c2e02fc7c7e05d79ada68fdf7d Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 13:58:02 -0400 Subject: [PATCH 18/22] Add the Swift podspec entries --- .../darwin/video_player_avfoundation.podspec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec index 8fac0f82e7f5..416a4461570c 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation.podspec @@ -23,5 +23,9 @@ Downloaded by pub (not CocoaPods). s.ios.deployment_target = '13.0' s.osx.deployment_target = '10.15' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.xcconfig = { + 'LIBRARY_SEARCH_PATHS' => '$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift', + 'LD_RUNPATH_SEARCH_PATHS' => '/usr/lib/swift', + } s.resource_bundles = {'video_player_avfoundation_privacy' => ['video_player_avfoundation/Sources/video_player_avfoundation/Resources/PrivacyInfo.xcprivacy']} end From 476d7a7ac09d1886e7198ac8db7f0862b27ae07a Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 14:04:05 -0400 Subject: [PATCH 19/22] Remove accidentally auto-added podspec entries --- .../example/macos/Flutter/Flutter-Debug.xcconfig | 1 - .../example/macos/Flutter/Flutter-Release.xcconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig index 4b81f9b2d200..c2efd0b608ba 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Debug.xcconfig @@ -1,2 +1 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig index 5caa9d1579e4..c2efd0b608ba 100644 --- a/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/macos/Flutter/Flutter-Release.xcconfig @@ -1,2 +1 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" From 7ff22df12f7ea38480da48654f83127584e58676 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 6 May 2026 14:17:46 -0400 Subject: [PATCH 20/22] Pods :/ --- .../example/ios/Flutter/Debug.xcconfig | 1 - .../example/ios/Flutter/Release.xcconfig | 1 - .../ios/Runner.xcodeproj/project.pbxproj | 124 +----------------- .../contents.xcworkspacedata | 3 - 4 files changed, 5 insertions(+), 124 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig index ec97fc6f3021..592ceee85b89 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig index c4855bfe2000..592ceee85b89 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig +++ b/packages/video_player/video_player_avfoundation/example/ios/Flutter/Release.xcconfig @@ -1,2 +1 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj index 510634e13929..a047a7cbeb4d 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,12 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2B2331B0DCF5C9DE826AE4AE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */; }; 3300E9FC2F69AA5200842B27 /* TestClasses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300E9FA2F69AA5200842B27 /* TestClasses.swift */; }; 3300E9FD2F69AA5200842B27 /* VideoPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */; }; 3300EA1A2F69AB0B00842B27 /* VideoPlayerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3300EA152F69AB0B00842B27 /* VideoPlayerUITests.swift */; }; @@ -19,7 +18,6 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - BAE1F70AACA38E87C7212ED2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A77052BBA99787E1564A5920 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -53,27 +51,19 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 2D05C2911DD61BE6B3A0C0E7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3300E9FA2F69AA5200842B27 /* TestClasses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestClasses.swift; path = ../../darwin/RunnerTests/TestClasses.swift; sourceTree = SOURCE_ROOT; }; 3300E9FB2F69AA5200842B27 /* VideoPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoPlayerTests.swift; path = ../../darwin/RunnerTests/VideoPlayerTests.swift; sourceTree = SOURCE_ROOT; }; 3300EA022F69AA9500842B27 /* RunnerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3300EA152F69AB0B00842B27 /* VideoPlayerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerUITests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - 611B0FCE3CD39649391110BF /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 78DABEA22ED26510000E7860 /* video_player_avfoundation */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = video_player_avfoundation; path = ../../darwin/video_player_avfoundation; sourceTree = ""; }; 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 907E8A244FFE06143C52C754 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -81,8 +71,6 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - A77052BBA99787E1564A5920 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,15 +86,6 @@ buildActionMask = 2147483647; files = ( 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, - BAE1F70AACA38E87C7212ED2 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E8666A13ABEDBB85EF214615 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2B2331B0DCF5C9DE826AE4AE /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -130,25 +109,9 @@ path = RunnerTests; sourceTree = ""; }; - 78E6C4C672418F816AD1151B /* Pods */ = { - isa = PBXGroup; - children = ( - 2D05C2911DD61BE6B3A0C0E7 /* Pods-Runner.debug.xcconfig */, - 907E8A244FFE06143C52C754 /* Pods-Runner.release.xcconfig */, - 611B0FCE3CD39649391110BF /* Pods-Runner.profile.xcconfig */, - E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */, - 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */, - 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 78DABEA22ED26510000E7860 /* video_player_avfoundation */, - 784666492D4C4C64000A1A5F /* FlutterFramework */, 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, @@ -166,8 +129,6 @@ 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, 3300EA162F69AB0B00842B27 /* RunnerUITests */, - 78E6C4C672418F816AD1151B /* Pods */, - BEF19F0C8AF7D72171D0F01C /* Frameworks */, ); sourceTree = ""; }; @@ -197,15 +158,6 @@ path = Runner; sourceTree = ""; }; - BEF19F0C8AF7D72171D0F01C /* Frameworks */ = { - isa = PBXGroup; - children = ( - A77052BBA99787E1564A5920 /* Pods_Runner.framework */, - 04D0239282942B6FA08E753E /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -223,6 +175,8 @@ 3300EA092F69AA9500842B27 /* PBXTargetDependency */, ); name = RunnerUITests; + packageProductDependencies = ( + ); productName = RunnerUITests; productReference = 3300EA022F69AA9500842B27 /* RunnerUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -231,10 +185,8 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 39E9E3BDE0A57095C4D1003C /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, - E8666A13ABEDBB85EF214615 /* Frameworks */, ); buildRules = ( ); @@ -250,14 +202,12 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - CB7DDF42E600F5D50568129D /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 9D0A52E2A788D630AA7DAF31 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -306,7 +256,7 @@ ); mainGroup = 97C146E51CF9000F007C117D; packageReferences = ( - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; @@ -348,28 +298,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 39E9E3BDE0A57095C4D1003C /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -401,45 +329,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 9D0A52E2A788D630AA7DAF31 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - CB7DDF42E600F5D50568129D /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -630,7 +519,6 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E94F35EEFB3F6FACF8504CFE /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -648,7 +536,6 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 189D01CE5E49D90438C5B1B6 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -664,7 +551,6 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6048B6FB8ECA2ACDB478D3EA /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -878,7 +764,7 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { isa = XCLocalSwiftPackageReference; relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; }; diff --git a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 21a3cc14c74e..1d526a16ed0f 100644 --- a/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/video_player/video_player_avfoundation/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,7 +4,4 @@ - - From d0516d74bce32ac72f395a8a8b19d05e21d9a521 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 7 May 2026 16:34:25 -0400 Subject: [PATCH 21/22] Review feedback --- .../NativeVideoViewFactory.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift index d3dac3a23776..f5dbaddd0843 100644 --- a/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift +++ b/packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/NativeVideoViewFactory.swift @@ -18,7 +18,7 @@ import Foundation /// A factory class responsible for creating native video views that can be embedded in a /// Flutter app. -class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { +final class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { private let messenger: FlutterBinaryMessenger private let playerByIdentifierProvider: (Int64) -> FVPVideoPlayer? @@ -35,18 +35,18 @@ class NativeVideoViewFactory: NSObject, FlutterPlatformViewFactory { #if os(macOS) func create( - withViewIdentifier viewId: Int64, - arguments args: Any? + withViewIdentifier viewIdentifier: Int64, + arguments: Any? ) -> NSView { - return createNativeVideoView(arguments: args as! PlatformVideoViewCreationParams) + return createNativeVideoView(arguments: arguments as! PlatformVideoViewCreationParams) } #elseif os(iOS) func create( withFrame frame: CGRect, - viewIdentifier viewId: Int64, - arguments args: Any? + viewIdentifier: Int64, + arguments: Any? ) -> FlutterPlatformView { - return createNativeVideoView(arguments: args as! PlatformVideoViewCreationParams) + return createNativeVideoView(arguments: arguments as! PlatformVideoViewCreationParams) } #endif From 3d72e03b49ab8298cc1a8d7c16e0ed143cd76826 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 7 May 2026 16:42:54 -0400 Subject: [PATCH 22/22] Add meta, for Pigeon --- packages/video_player/video_player_avfoundation/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml index 9e6a8dcfa46d..762d8d08eadd 100644 --- a/packages/video_player/video_player_avfoundation/pubspec.yaml +++ b/packages/video_player/video_player_avfoundation/pubspec.yaml @@ -24,6 +24,7 @@ flutter: dependencies: flutter: sdk: flutter + meta: ^1.10.0 video_player_platform_interface: ^6.6.0 dev_dependencies: