15 Commits

Author SHA1 Message Date
Juraldinio e9b5a88c27 Remove wrong commoted xcframework 2023-09-21 20:21:00 +03:00
Juraldinio 81092cf8e9 xcframework from build machine 2023-09-21 18:39:43 +03:00
Андрей Геращенко 64ae8f989c PSDK-983: Обновлен фреймворк Nutplayer 2023-09-21 18:28:48 +03:00
Андрей Геращенко d9da0e1ad2 PSDK-983: Исправил проблему импорта video_player_controller'a 2023-09-21 16:19:49 +03:00
Андрей Геращенко 8d9aa9159f PSDK-983: Добавил параметр в pubspec 2023-09-21 14:44:12 +03:00
Андрей Геращенко 5a41db2360 PSDK-983: Промежуточный коммит 2023-09-21 11:31:51 +03:00
Андрей Геращенко 7ce68d2768 Merge branch 'develop' into feature/PSDK-983/init_methods 2023-09-20 15:26:46 +03:00
Андрей Геращенко 80e603a1f9 PSDK-983: Добавил создание контекста и регистрацию сущности платформы 2023-09-20 15:26:04 +03:00
Андрей Геращенко e1bd9d8af7 PSDK-983: Удалил лишнее со стороны флаттера 2023-09-20 12:59:02 +03:00
Андрей Геращенко 9887ed6d11 PSDK-983: Правки со стороны платформы иос 2023-09-20 12:54:46 +03:00
Андрей Геращенко 9d0cfc59c6 PSDK-969: Переделано отображение проигрывателя 2023-09-20 02:41:18 +03:00
Андрей Геращенко 5c99970036 PSDK-983: Исправил идентификатор проигрывателя 2023-09-20 02:20:01 +03:00
Андрей Геращенко 93f9bd34aa PSDK-983: Добавлен запуск проигрывателя 2023-09-20 02:01:02 +03:00
Андрей Геращенко 544cb03e20 PSDK-983: Рефакторинг под новые методы универсального интерфейса 2023-09-20 01:25:11 +03:00
Андрей Геращенко 58df4000f8 PSDK-983: Промежуточный коммит, созданы методы и прокинуты связи, в процессе рефакторинг старого кода согласно новым требованиям 2023-09-19 21:57:28 +03:00
48 changed files with 17106 additions and 7389 deletions
+6 -6
View File
@@ -2,27 +2,27 @@ PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- nut_player (0.0.1):
- nut_player_ios (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- nut_player (from `.symlinks/plugins/nut_player/ios`)
- nut_player_ios (from `.symlinks/plugins/nut_player_ios/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
nut_player:
:path: ".symlinks/plugins/nut_player/ios"
nut_player_ios:
:path: ".symlinks/plugins/nut_player_ios/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
integration_test: 13825b8a9334a850581300559b8839134b124670
nut_player: fac5f2edd6e1927a28413a98d968ff8f67078da2
nut_player_ios: 4b33be9feaf24c953526324edf4c2e9e7f1ab5f3
PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189
PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5
COCOAPODS: 1.12.1
@@ -3,10 +3,13 @@ import 'package:nut_player_example/src/common/models/option_data.dart';
import 'package:nut_player_example/src/common/views/input_view.dart';
import 'package:nut_player_example/src/common/views/options_view.dart';
import 'package:nut_player_example/src/features/player_screen/presentation/player_button.dart';
import 'package:nut_player/nut_player.dart';
class PlayerView extends StatelessWidget {
PlayerView({super.key});
final controller = createPlayerController();
final List<OptionData> _playerAPIOptions = [
OptionData(key: const Key('PlaybackOptionVolumeID'), title: 'Громкость'),
OptionData(key: const Key('PlaybackOptionQualityID'), title: 'Качество'),
@@ -84,6 +87,7 @@ class PlayerView extends StatelessWidget {
// TODO: Встроить плеер
child: Container(
color: CupertinoColors.link,
child: VideoPlayer(controller),
)
),
@@ -171,4 +175,10 @@ class PlayerView extends StatelessWidget {
)
);
}
static VideoPlayerController createPlayerController() {
final controller = VideoPlayerController.network("https://cloud.nut.tech/index.php/s/CEb4Xd48wd98kj4/download/star-wars.mp4")
..initialize();
return controller;
}
}
+7
View File
@@ -137,6 +137,13 @@ packages:
relative: true
source: path
version: "0.0.1"
nut_player_ios:
dependency: transitive
description:
path: "../../nut_player_ios"
relative: true
source: path
version: "0.0.1"
nut_player_platform_interface:
dependency: transitive
description:
-1
View File
@@ -47,7 +47,6 @@ dev_dependencies:
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
+4 -1
View File
@@ -1,2 +1,5 @@
export 'src/legacy/closed_caption_file.dart';
export 'src/legacy/video_player_value.dart';
export 'src/legacy/video_player_value.dart';
export 'src/legacy/video_player_controller.dart';
export 'src/legacy/video_scrubber.dart';
export 'src/legacy/video_progress_indicator.dart';
+7
View File
@@ -99,6 +99,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
nut_player_ios:
dependency: "direct main"
description:
path: "../nut_player_ios"
relative: true
source: path
version: "0.0.1"
nut_player_platform_interface:
dependency: "direct main"
description:
+8
View File
@@ -8,12 +8,20 @@ environment:
sdk: '>=3.1.0 <4.0.0'
flutter: '>=3.3.0'
flutter:
plugin:
platforms:
ios:
default_package: nut_player_ios
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
nut_player_platform_interface:
path: ../nut_player_platform_interface
nut_player_ios:
path: ../nut_player_ios
dev_dependencies:
flutter_test:
@@ -16,10 +16,10 @@ void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('getPlatformVersion test', (WidgetTester tester) async {
final NutPlayerIos plugin = NutPlayerIos();
final String? version = await plugin.getPlatformVersion();
// final NutPlayerIos plugin = NutPlayerIos();
// final String? version = await plugin.getPlatformVersion();
// The version string depends on the host platform running the test, so
// just assert that some non-empty string is returned.
expect(version?.isNotEmpty, true);
// expect(version?.isNotEmpty, true);
});
}
+17 -28
View File
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nut_player_ios/nut_player_ios.dart';
void main() {
runApp(const MyApp());
@@ -37,12 +35,11 @@ class _MyHomePageState extends State<MyHomePage> {
double _duration = 0;
double _currentTime = 0;
String _playerState = "";
final url = "https://cloud.nut.tech/index.php/s/CEb4Xd48wd98kj4/download/star-wars.mp4";
late NutPlayerWidgetController controller;
late int _playerWidgetId;
// late NutPlayerWidgetController controller;
@override
Widget build(BuildContext context) {
Map<String, String> creationParams = <String, String>{"url": url};
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
@@ -56,27 +53,19 @@ class _MyHomePageState extends State<MyHomePage> {
'$_playerState',
style: Theme.of(context).textTheme.headlineMedium,
),
AspectRatio(aspectRatio: 16/10,
child: NutPlayerWidget(onNutPlayerWidgetCreated: (NutPlayerWidgetController newController) {
controller = newController;
controller.currentTime.addListener(() {
setState( () {
_currentTime = controller.currentTime.value;
});
});
controller.duration.addListener(() {
setState( () {
_duration = controller.duration.value;
});
});
controller.playerState.addListener(() {
setState( () {
_playerState = controller.playerState.value;
});
});
},
creationParams: creationParams)
),
// AspectRatio(aspectRatio: 16/10,
// child: NutPlayerWidget(onNutPlayerWidgetCreated: (NutPlayerWidgetController newController, int playerId) {
// controller = newController;
// _playerWidgetId = playerId;
// controller.init();
// var dataSource = DataSource(
// sourceType: DataSourceType.network,
// uri: "https://cloud.nut.tech/index.php/s/CEb4Xd48wd98kj4/download/star-wars.mp4",
// format: VideoFormat.mp4,
// );
// controller.create(dataSource);
// }, creationParams: {})
// ),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@@ -89,7 +78,7 @@ class _MyHomePageState extends State<MyHomePage> {
),
TextButton(
onPressed: () {
controller.play();
// controller.play(_playerWidgetId);
},
child: const Text(
'Старт',
@@ -101,7 +90,7 @@ class _MyHomePageState extends State<MyHomePage> {
)),
TextButton(
onPressed: () {
controller.pause();
// controller.pause(_playerWidgetId);
},
child: const Text(
'Пауза',
+10 -3
View File
@@ -137,6 +137,13 @@ packages:
relative: true
source: path
version: "0.0.1"
nut_player_platform_interface:
dependency: transitive
description:
path: "../../nut_player_platform_interface"
relative: true
source: path
version: "0.0.1"
path:
dependency: transitive
description:
@@ -157,10 +164,10 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
url: "https://pub.dev"
source: hosted
version: "2.1.5"
version: "2.1.6"
process:
dependency: transitive
description:
@@ -263,5 +270,5 @@ packages:
source: hosted
version: "3.0.2"
sdks:
dart: ">=3.1.0 <4.0.0"
dart: ">=3.1.2 <4.0.0"
flutter: ">=3.3.0"
@@ -12,11 +12,11 @@ import Combine
public class NutPlayerWidgetViewWrap: NSObject, FlutterPlatformView {
let viewId: Int64
let playerView: UIView
let messenger: FlutterBinaryMessenger
let channel: FlutterMethodChannel
private var player: NutPlayer
private var playerView: UIView
private var player: NutPlayer?
private var cancellables = Set<AnyCancellable>()
init(frame: CGRect,
@@ -29,130 +29,75 @@ public class NutPlayerWidgetViewWrap: NSObject, FlutterPlatformView {
let channel = FlutterMethodChannel(name: "NutPlayer/\(viewIdentifier)",
binaryMessenger: messenger)
self.channel = channel
self.player = NutPlayer()
self.playerView = Self.createPlayerView(from: self.player)
let blankView = UIView()
blankView.backgroundColor = .black
self.playerView = blankView
super.init()
self.setupPlayer(args: arguments)
self.setupPlayerSubscribers()
channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
self.setupChannelHandler(args: arguments)
}
public func view() -> UIView {
self.playerView
}
func play() {
self.player?.play()
}
func pause() {
self.player?.pause()
}
private func setupChannelHandler(args: Any?) {
self.channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
guard let self else { return }
switch call.method {
case "getCurrentTime":
result(self.player.currentTime.current)
case "getDuration":
result(self.player.duration.current)
case "getState":
let state = self.player.state.current
let mappedState = Self.mapStateToDictionary(state: state)
result(mappedState)
case "play":
case "nutplayer.input.initialize":
break
case "nutplayer.input.create":
let player = NutPlayer()
self.player = player
let newPlayerView = Self.createPlayerView(from: player)
newPlayerView.translatesAutoresizingMaskIntoConstraints = false
self.playerView.addSubview(newPlayerView)
NSLayoutConstraint.activate([
newPlayerView.topAnchor.constraint(equalTo: playerView.topAnchor),
newPlayerView.leftAnchor.constraint(equalTo: playerView.leftAnchor),
newPlayerView.rightAnchor.constraint(equalTo: playerView.rightAnchor),
newPlayerView.bottomAnchor.constraint(equalTo: playerView.bottomAnchor),
])
self.setupPlayer(args: call.arguments)
result(self.viewId)
case "nutplayer.input.dispose":
self.player?.stop()
self.player = nil
case "nutplayer.input.play":
self.play()
case "pause":
case "nutplayer.input.pause":
self.pause()
default:
result(FlutterMethodNotImplemented)
}
}
}
public func sendDuration(_ duration: Double) {
DispatchQueue.main.async {
NutPlayerIosPlugin.channel?.invokeMethod("sendDuration", arguments: duration)
}
}
public func sendCurrentTime(_ time: Double) {
DispatchQueue.main.async {
NutPlayerIosPlugin.channel?.invokeMethod("sendCurrentTime", arguments: time)
// TODO: Разобраться, почему не отправляет сообщения по каналу из конструктора и требуется использовать статичный канал плагина
// self.channel.invokeMethod("sendCurrentTime", arguments: time)
}
}
public func sendState(_ state: String) {
DispatchQueue.main.async {
NutPlayerIosPlugin.channel?.invokeMethod("sendState", arguments: state)
}
}
public func sendQuality(_ quality: PlayerQualityRecord) {
let qualityDict = Self.mapQualityToDictionary(quality: quality)
DispatchQueue.main.async {
NutPlayerIosPlugin.channel?.invokeMethod("sendQuality", arguments: qualityDict)
}
}
public func sendQualities(_ qualities: [PlayerQualityRecord]) {
let qualitiesDict = qualities.map { Self.mapQualityToDictionary(quality: $0) }
DispatchQueue.main.async {
NutPlayerIosPlugin.channel?.invokeMethod("sendQualities", arguments: qualitiesDict)
}
}
public func view() -> UIView { self.playerView }
func play() {
self.player.play()
}
func pause() {
self.player.pause()
}
private func setupPlayer(args: Any?) {
guard let argsDictionary = args as? [String: Any],
let link = argsDictionary["url"] as? String else { return }
guard let argsDictionary = args as? [String: Any] else { return }
if let link = argsDictionary["uri"] as? String,
let provider = Self.createProvider(from: link) {
self.player?.load(provider: provider)
return
}
let playlistTimeout = argsDictionary["playlistTimeout"] as? Double ?? 5_000
let trackTimeout = argsDictionary["trackTimeout"] as? Double ?? 3_000
let autoStart = argsDictionary["autoStart"] as? Bool ?? false
let position = argsDictionary["position"] as? Double ?? 0.0
let timeouts = PlayerTimeouts(playlist: playlistTimeout,
track: trackTimeout)
guard let provider = Self.createProvider(from: link) else { return }
self.player.load(provider: provider,
timeouts: timeouts,
autoplay: autoStart,
position: position,
quality: nil)
if let asset = argsDictionary["asset"] as? String,
let packageName = argsDictionary["packageName"] as? String {
// обработка ассета
return
}
}
private func setupPlayerSubscribers() {
self.player.currentTime
.receive(on: DispatchQueue.main)
.sink { [weak self] time in
guard let self else { return }
self.sendCurrentTime(time)
}
.store(in: &self.cancellables)
self.player.state
.receive(on: DispatchQueue.main)
.sink { [weak self] state in
guard let self else { return }
}
.store(in: &self.cancellables)
self.player.qualities
.receive(on: DispatchQueue.main)
.sink { [weak self] qualities in
guard let self else { return }
self.sendQualities(qualities)
}
.store(in: &self.cancellables)
self.player.currentQuality
.receive(on: DispatchQueue.main)
.sink { [weak self] quality in
guard let self, let quality else { return }
self.sendQuality(quality)
}
.store(in: &self.cancellables)
}
static func createPlayerView(from player: NutPlayer) -> NutPlayerView {
static private func createPlayerView(from player: NutPlayer) -> NutPlayerView {
let playerBuilder = NutPlayerViewBuilder()
// TODO: Здесь будет необходимо выполнить настройку плагинов
// let qualitySettings = NutQualityPlugin.Settings(mapper: self.viewModel.qualityTitleMapper)
@@ -164,73 +109,6 @@ public class NutPlayerWidgetViewWrap: NSObject, FlutterPlatformView {
return playerBuilder.build(with: player)
}
static func mapQualityToDictionary(quality: PlayerQualityRecord) -> [String: Any] {
[
"id": quality.id,
"bandwidth": quality.bandwidth,
"width": Double(quality.resolution.width),
"height": Double(quality.resolution.height),
]
}
static func mapStateToDictionary(state: PlayerState) -> [String: Any?] {
switch state {
case .idle:
return ["state": "idle"]
case .content(let content):
return ["state": "content",
"type": Self.mapContentToDictionary(content: content.content)]
case .loading:
return ["state": "loading"]
case .ready(let position, let duration):
return ["state": "ready",
"startPosition": position,
"duration": duration]
case .buffering:
return ["state": "buffering"]
case .playing:
return ["state": "playing"]
case .paused(let byUI):
return ["state": "paused",
"byUI": byUI]
case .completed:
return ["state": "completed"]
case .seeking(let seekPosition):
return ["state": "seeking",
"seekPosition": seekPosition]
case .error(let error):
return ["state": "error",
"error": error.localizedDescription]
case .uninitialized:
return ["state": "uninitialized"]
@unknown default:
return ["state": "unknown"]
}
}
static func mapContentToDictionary(content: ContentType) -> [String: Any?] {
switch content {
case .auto(let url):
return ["type": "auto",
"url": url.absoluteString]
case .hls(let url):
return ["type": "hls",
"url": url.absoluteString]
case .dash(let url):
return ["type": "dash",
"url": url.absoluteString]
case .mp4(let url, let loop):
return ["type": "mp4",
"url": url.absoluteString,
"loop": loop]
case .raw(let data):
return ["type": "raw",
"data": data]
@unknown default:
return ["type": "unknown"]
}
}
static func createProvider(from link: String, loop: Bool = false) -> Provider? {
guard let url = URL(string: link) else { return nil }
@@ -5,6 +5,8 @@
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>NutPlayer.framework/NutPlayer</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
@@ -17,6 +19,8 @@
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>NutPlayer.framework/NutPlayer</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
@@ -1,6 +1,6 @@
#if 0
#elif defined(__arm64__) && __arm64__
// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
// Generated by Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
#ifndef NUTPLAYER_SWIFT_H
#define NUTPLAYER_SWIFT_H
#pragma clang diagnostic push
@@ -42,12 +42,18 @@
#include <string.h>
#endif
#if defined(__cplusplus)
#if __has_include(<ptrauth.h>)
#if defined(__arm64e__) && __has_include(<ptrauth.h>)
# include <ptrauth.h>
#else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
# ifndef __ptrauth_swift_value_witness_function_pointer
# define __ptrauth_swift_value_witness_function_pointer(x)
# endif
# ifndef __ptrauth_swift_class_method_pointer
# define __ptrauth_swift_class_method_pointer(x)
# endif
#pragma clang diagnostic pop
#endif
#endif
@@ -246,6 +252,17 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#else
# define SWIFT_NOEXCEPT
#endif
#if !defined(SWIFT_C_INLINE_THUNK)
# if __has_attribute(always_inline)
# if __has_attribute(nodebug)
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))
# else
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))
# endif
# else
# define SWIFT_C_INLINE_THUNK inline
# endif
#endif
#if defined(_WIN32)
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
@@ -359,12 +376,14 @@ SWIFT_CLASS("_TtC9NutPlayer12TechAVPlayer")
#endif
#if defined(__cplusplus)
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#if defined(__cplusplus)
#endif
#pragma clang diagnostic pop
#endif
@@ -1,6 +1,6 @@
#if 0
#elif defined(__arm64__) && __arm64__
// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
// Generated by Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
#ifndef NUTPLAYER_SWIFT_H
#define NUTPLAYER_SWIFT_H
#pragma clang diagnostic push
@@ -42,12 +42,18 @@
#include <string.h>
#endif
#if defined(__cplusplus)
#if __has_include(<ptrauth.h>)
#if defined(__arm64e__) && __has_include(<ptrauth.h>)
# include <ptrauth.h>
#else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
# ifndef __ptrauth_swift_value_witness_function_pointer
# define __ptrauth_swift_value_witness_function_pointer(x)
# endif
# ifndef __ptrauth_swift_class_method_pointer
# define __ptrauth_swift_class_method_pointer(x)
# endif
#pragma clang diagnostic pop
#endif
#endif
@@ -246,6 +252,17 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#else
# define SWIFT_NOEXCEPT
#endif
#if !defined(SWIFT_C_INLINE_THUNK)
# if __has_attribute(always_inline)
# if __has_attribute(nodebug)
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))
# else
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))
# endif
# else
# define SWIFT_C_INLINE_THUNK inline
# endif
#endif
#if defined(_WIN32)
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
@@ -359,17 +376,19 @@ SWIFT_CLASS("_TtC9NutPlayer12TechAVPlayer")
#endif
#if defined(__cplusplus)
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#if defined(__cplusplus)
#endif
#pragma clang diagnostic pop
#endif
#elif defined(__x86_64__) && __x86_64__
// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
// Generated by Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
#ifndef NUTPLAYER_SWIFT_H
#define NUTPLAYER_SWIFT_H
#pragma clang diagnostic push
@@ -411,12 +430,18 @@ SWIFT_CLASS("_TtC9NutPlayer12TechAVPlayer")
#include <string.h>
#endif
#if defined(__cplusplus)
#if __has_include(<ptrauth.h>)
#if defined(__arm64e__) && __has_include(<ptrauth.h>)
# include <ptrauth.h>
#else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
# ifndef __ptrauth_swift_value_witness_function_pointer
# define __ptrauth_swift_value_witness_function_pointer(x)
# endif
# ifndef __ptrauth_swift_class_method_pointer
# define __ptrauth_swift_class_method_pointer(x)
# endif
#pragma clang diagnostic pop
#endif
#endif
@@ -615,6 +640,17 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#else
# define SWIFT_NOEXCEPT
#endif
#if !defined(SWIFT_C_INLINE_THUNK)
# if __has_attribute(always_inline)
# if __has_attribute(nodebug)
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))
# else
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))
# endif
# else
# define SWIFT_C_INLINE_THUNK inline
# endif
#endif
#if defined(_WIN32)
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
@@ -728,12 +764,14 @@ SWIFT_CLASS("_TtC9NutPlayer12TechAVPlayer")
#endif
#if defined(__cplusplus)
#endif
#if __has_attribute(external_source_symbol)
# pragma clang attribute pop
#endif
#if defined(__cplusplus)
#endif
#pragma clang diagnostic pop
#endif
@@ -6,63 +6,63 @@
<dict>
<key>Assets.car</key>
<data>
o6y0hhlmj6iXW8Ziucq2jaS3MSE=
Qt4NFRCpIUeoMqfdzRiqikxPy7w=
</data>
<key>Headers/NutPlayer-Swift.h</key>
<data>
g+2beSGGG/snXq8twMcsgLzrXFw=
w9HbVoaNZuvZwgKEbemE/PSkGHQ=
</data>
<key>Info.plist</key>
<data>
kXlkp5fyUXVKLMMMELvU1Bh1a/o=
QSk+YOMjHAraWHs4bvpdK0D51BQ=
</data>
<key>Modules/NutPlayer.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo</key>
<data>
m6XTV9R9VB6GCXW5DFUtCaihu9Y=
+pNuYGrjogmNAnzjP0VHKpKqc2M=
</data>
<key>Modules/NutPlayer.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo</key>
<data>
QYXCmI27o3MUvPMa/k81iYtXHBw=
yUSYtSaMx+ZucYNN9P2twUVhrMk=
</data>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
<data>
LW69IChcVLEioFykGWzPXs76Szk=
PpkDx950YPsUGml7JDxNARwso1E=
</data>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
<data>
rf9E4+4WKFjgX8KcZVchAsZAJOk=
txNk9o8O2ynvAu2EXahjRWUZ2dw=
</data>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftdoc</key>
<data>
u6qRWaZaCB2yU+XNT2bTd5tOP98=
v9C3rre9mB0bYnLE9TEP4urCke0=
</data>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftinterface</key>
<data>
rf9E4+4WKFjgX8KcZVchAsZAJOk=
txNk9o8O2ynvAu2EXahjRWUZ2dw=
</data>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftmodule</key>
<data>
VgC5miBZX6OTLasWvtZt0jdKTpU=
XFWoTUeUgP9ty8YEnWgp3E7JT9Q=
</data>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
<data>
LW69IChcVLEioFykGWzPXs76Szk=
PpkDx950YPsUGml7JDxNARwso1E=
</data>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
<data>
+K1bOT1/JgUR3ZMM2qkdFi115WU=
f5ad74lxh9ZkN8iwFj8U8FPlHC8=
</data>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
<data>
0nDVTYPdzG7kFvehYpvvRwPtHsc=
u3mi53Pgf9T7CqtnDe4UP4wyNps=
</data>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
<data>
+K1bOT1/JgUR3ZMM2qkdFi115WU=
f5ad74lxh9ZkN8iwFj8U8FPlHC8=
</data>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
<data>
rz/IJIpL03fLmko9HSdV5XvWEn8=
xIq1+5XMwg5ROVvdVKuH4rBRO7I=
</data>
<key>Modules/module.modulemap</key>
<data>
@@ -93,98 +93,98 @@
<dict>
<key>hash2</key>
<data>
Vcf3ncoiKQAmZtCRf3X3Xs2CWAomATfNMroGrhH3r8M=
4Qc2Cva7qmMzjVPkXEKzqECyx1Y83HOOxN5HBN9Ft/Y=
</data>
</dict>
<key>Headers/NutPlayer-Swift.h</key>
<dict>
<key>hash2</key>
<data>
7XHyskQTeHQA0cPcNNOuWbxGVjZaWJBIS+nRULZC4XU=
i2JhMWAu9z7tMuCWRwsdcgTVrAvA3yWVPj/AIX/F6pM=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo</key>
<dict>
<key>hash2</key>
<data>
pR3DgibMao1iC3yiWADwW5hqvPI4lIEcFLaFuuzPF44=
u4sBH5QadVR+A8uTFtSizPxIMSs6uPBdsx0TWEVzVoo=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo</key>
<dict>
<key>hash2</key>
<data>
kUdbwvts6xt4kLPc7DSafMZ5kK/O7CjZAzSrWy7xiC0=
YZLs7qZa5wTAMZKIaKyna6pHCQuThCYO1tqasGVXXvM=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
<dict>
<key>hash2</key>
<data>
HGFop1IQ5cv3LIq+Iu0Wk+xcmBdxpOYsIh3pk0LR3bo=
eZQpY7nOrqPXHv6HB+4DSoWRltqKAL6XIMeTkLT5AII=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
NZ7NeJb037ly9Ckybusn/938/xaHFGc6cjD0EIR+dUk=
s7TN5QqXPqFA+YMrwaPxKR4HCmJ8g1N6L8sEd7hO3xQ=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftdoc</key>
<dict>
<key>hash2</key>
<data>
QHJtqUmd+VNuqw3Q5XJrr4uG7YsrLKkYiIXFMk7TwMU=
UmRZO4w9gioQkgyNR7YulcNigG1KKs7TCNF30zZg5a0=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
NZ7NeJb037ly9Ckybusn/938/xaHFGc6cjD0EIR+dUk=
s7TN5QqXPqFA+YMrwaPxKR4HCmJ8g1N6L8sEd7hO3xQ=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/arm64-apple-ios-simulator.swiftmodule</key>
<dict>
<key>hash2</key>
<data>
ycaTixOftZ4LIx4qyKpxfAoFtOADiea6nHN7SfWX64E=
UTOEapQEPaym1gsq+aLIyGheuyvNvm4oWbOMhmNidCE=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
<dict>
<key>hash2</key>
<data>
HGFop1IQ5cv3LIq+Iu0Wk+xcmBdxpOYsIh3pk0LR3bo=
eZQpY7nOrqPXHv6HB+4DSoWRltqKAL6XIMeTkLT5AII=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
AbGYt1X4fMOkQb9IV50YUG1JVkv036F0W92Kvzhu474=
NGDXi0s7MLsSH52UPkWQYLwALJn9yJ2g7L/pO47KH6o=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
<dict>
<key>hash2</key>
<data>
IGPnhDqOd+OZXX/AQQMa7VHKMhDOGZknqEH1JvXiefw=
7L0U1eNKFdl5LXyRWANZgOMBSgZJAPZdTdlHPCwHBUU=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
<dict>
<key>hash2</key>
<data>
AbGYt1X4fMOkQb9IV50YUG1JVkv036F0W92Kvzhu474=
NGDXi0s7MLsSH52UPkWQYLwALJn9yJ2g7L/pO47KH6o=
</data>
</dict>
<key>Modules/NutPlayer.swiftmodule/x86_64-apple-ios-simulator.swiftmodule</key>
<dict>
<key>hash2</key>
<data>
zIhVyvBuFRiokEEXapLcXGkd3/z1uhP8MkLJfQXYcjw=
H8vUk9vnCA8Yw1cjWG6QmXaIL+jdnxxeUgj+Y2qff4M=
</data>
</dict>
<key>Modules/module.modulemap</key>
+70 -84
View File
@@ -1,103 +1,89 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'nut_player_ios_platform_interface.dart';
import 'package:nut_player_platform_interface/nut_player_platform_interface.dart';
class NutPlayerIos {
Future<String?> getPlatformVersion() {
return NutPlayerIosPlatform.instance.getPlatformVersion();
}
}
typedef void NutPlayerWidgetCreatedCallback(NutPlayerWidgetController controller);
class NutPlayerWidget extends StatelessWidget {
class NutPlayerIosPlatform extends NutPlayerPlatform {
late int _identifier;
late MethodChannel _outputChannel;
static const StandardMessageCodec _decoder = StandardMessageCodec();
final NutPlayerWidgetCreatedCallback onNutPlayerWidgetCreated;
final Map<String, String> creationParams;
NutPlayerWidget({
Key? key,
required this.onNutPlayerWidgetCreated,
required this.creationParams,
}) : super(key: key);
NutPlayerIosPlatform(int playerId) {
this._identifier = playerId;
this._outputChannel = new MethodChannel('NutPlayer/$playerId');
}
static void registerWith() {
NutPlayerPlatform.instance = NutPlayerIosPlatform(0);
}
@override
Future<void> init() {
NutPlayerPlatform.instance = this;
return _outputChannel.invokeMethod("nutplayer.input.initialize");
}
@override
Widget build(BuildContext context) {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
return UiKitView(
viewType: 'nut_player_view_id',
layoutDirection: TextDirection.ltr,
onPlatformViewCreated: _onPlatformViewCreated,
creationParams: creationParams,
creationParams: null,
creationParamsCodec: _decoder);
default:
return Text(
'$defaultTargetPlatform is not yet supported by the web_view plugin');
}
@override
Future<void> dispose(int textureId) {
return _outputChannel.invokeMethod("nutplayer.input.dispose");
}
@override
Future<PlayerId> create(DataSource dataSource) async {
String? asset;
String? packageName;
String? uri;
Map<String, String> httpHeaders = <String, String>{};
switch (dataSource.sourceType) {
case DataSourceType.asset:
asset = dataSource.asset;
packageName = dataSource.package;
break;
case DataSourceType.network:
uri = dataSource.uri;
httpHeaders = dataSource.httpHeaders;
break;
case DataSourceType.file:
uri = dataSource.uri;
break;
case DataSourceType.contentUri:
uri = dataSource.uri;
break;
}
var responseFuture = _outputChannel.invokeMethod<int>("nutplayer.input.create", {
"uri": uri,
"headers": httpHeaders,
"asset": asset,
"packageName": packageName,
});
var playerId = await Future.wait([responseFuture]);
if (playerId.first != null) {
return Future<PlayerId>.value(playerId.first!);
} else {
throw("Ошибка при создании проигрывателя");
}
}
// Блок обратного вызова после создания виджета
void _onPlatformViewCreated(int id) {
onNutPlayerWidgetCreated(NutPlayerWidgetController(id));
}
}
class NutPlayerWidgetController {
ValueNotifier<double> duration = ValueNotifier<double>(0.0);
ValueNotifier<double> currentTime = ValueNotifier<double>(0.0);
ValueNotifier<String> playerState = ValueNotifier<String>("uninitialized");
late MethodChannel _outputChannel;
late MethodChannel _inputChannel;
NutPlayerWidgetController(int id) {
_outputChannel = new MethodChannel('NutPlayer/$id');
_inputChannel = new MethodChannel("nut_player_ios");
_inputChannel.setMethodCallHandler(_handleMethod);
}
Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) {
case "sendState":
print(call.arguments);
case 'sendDuration':
double videoDuration = call.arguments as double;
duration.value = videoDuration;
return new Future.value("Text from native: $videoDuration");
case 'sendCurrentTime':
double time = call.arguments as double;
currentTime.value = time;
return new Future.value("Text from native: $time");
case "sendQuality":
print(call.arguments);
case "sendQualities":
print(call.arguments);
@override
Future<void> play(PlayerId playerId) async {
if (playerId == _identifier) {
await _outputChannel.invokeMethod('nutplayer.input.play');
}
}
Future<double?> getCurrentTime() async {
final currentTime = await _outputChannel.invokeMethod<double>('getCurrentTime');
return currentTime;
}
Future<double?> getDuration() async {
final duration = await _outputChannel.invokeMethod<double>('getDuration');
return duration;
}
Future<String?> getState() async {
final state = await _outputChannel.invokeMethod<String>('getState');
return state;
}
Future<void> setTime(double time) async {
await _outputChannel.invokeMethod('setTime', time);
}
Future<void> play() async {
await _outputChannel.invokeMethod('play');
}
Future<void> pause() async {
await _outputChannel.invokeMethod('pause');
@override
Future<void> pause(PlayerId playerId) async {
if (playerId == _identifier) {
await _outputChannel.invokeMethod('nutplayer.input.pause');
}
}
}
+4 -1
View File
@@ -1,7 +1,7 @@
name: nut_player_ios
description: A new Flutter plugin project.
version: 0.0.1
homepage:
homepage: "www.nut.tech"
environment:
sdk: '>=3.1.0 <4.0.0'
@@ -11,6 +11,8 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
nut_player_platform_interface:
path: ../nut_player_platform_interface
dev_dependencies:
flutter_test:
@@ -35,6 +37,7 @@ flutter:
plugin:
platforms:
ios:
dartPluginClass: NutPlayerIosPlatform
pluginClass: NutPlayerIosPlugin
# To add assets to your plugin package, add an assets section, like this:
+5 -5
View File
@@ -20,10 +20,10 @@ void main() {
});
test('getPlatformVersion', () async {
NutPlayerIos nutPlayerIosPlugin = NutPlayerIos();
MockNutPlayerIosPlatform fakePlatform = MockNutPlayerIosPlatform();
NutPlayerIosPlatform.instance = fakePlatform;
expect(await nutPlayerIosPlugin.getPlatformVersion(), '42');
// NutPlayerIos nutPlayerIosPlugin = NutPlayerIos();
// MockNutPlayerIosPlatform fakePlatform = MockNutPlayerIosPlatform();
// NutPlayerIosPlatform.instance = fakePlatform;
//
// expect(await nutPlayerIosPlugin.getPlatformVersion(), '42');
});
}