-
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathcontroller.dart
More file actions
296 lines (260 loc) · 11.8 KB
/
Copy pathcontroller.dart
File metadata and controls
296 lines (260 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
// ignore_for_file: invalid_use_of_visible_for_testing_member
// see https://github.com/ardera/flutter_packages/blob/main/packages/flutterpi_gstreamer_video_player/lib/src/controller.dart
import 'dart:io';
import 'dart:typed_data';
import 'package:video_player/video_player.dart';
import 'package:video_player_platform_interface/video_player_platform_interface.dart';
import 'media_info.dart'
if (dart.library.js_interop) 'media_info_dummy.dart'
if (dart.library.html) 'media_info_dummy.dart';
import 'video_player_mdk.dart'
if (dart.library.js_interop) 'video_player_dummy.dart'
if (dart.library.html) 'video_player_dummy.dart';
MdkVideoPlayerPlatform get _platform {
if (VideoPlayerPlatform.instance is! MdkVideoPlayerPlatform) {
throw StateError(
'`VideoPlayerPlatform.instance` have to be of `MdkVideoPlayerPlatform` to use advanced video player features.'
'Make sure you\'ve called `fvp.registerWith()`',
);
}
return VideoPlayerPlatform.instance as MdkVideoPlayerPlatform;
}
/// Advanced features for [VideoPlayerController].
///
/// All methods in this extension must be called after initialized, otherwise no effect.
extension FVPControllerExtensions on VideoPlayerController {
/*
static int Function(VideoPlayerController)? _idGetter;
int _getId(VideoPlayerController controller) {
_idGetter ??= _getIdFunc();
return _idGetter!(this);
}
int Function(VideoPlayerController) _getIdFunc() {
//final dynamic self = this;
try { // try to get textureId
//final _ = self.textureId;
final _ = (this as dynamic).textureId;
return (dynamic c) => c.textureId;
} on NoSuchMethodError { // since video_player 2.10.0 to support platform view
return (dynamic c) => c.playerId;
}
}
// extension can't override existing method, e.g. `dynamic noSuchMethod(Invocation invocation)`
*/
// TODO: prefer playerId in a future version
static final int Function(VideoPlayerController c) _getId = () {
try {
// try to get textureId. static implies late, but can't access this
final _ = (VideoPlayerController.file(File('')) as dynamic).textureId;
return (dynamic c) => c.textureId as int;
} on NoSuchMethodError {
// since video_player 2.10.0 to support platform view
return (dynamic c) => c.playerId as int;
}
}();
/// Indicates whether current media is a live stream or not
bool isLive() {
return _platform.isLive(_getId(this));
}
/// Get current media info.
MediaInfo? getMediaInfo() {
return _platform.getMediaInfo(_getId(this));
}
/// set additional properties
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setpropertyconst-stdstring-key-const-stdstring-value
void setProperty(String name, String value) {
_platform.setProperty(_getId(this), name, value);
}
/// Change video decoder list on the fly.
/// NOTE: the default decoder list used by [VideoPlayerController] constructor MUST set via [registerWith].
/// Detail: https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setdecodersmediatype-type-const-stdvectorstdstring-names
void setVideoDecoders(List<String> value) {
_platform.setVideoDecoders(_getId(this), value);
}
/// Start to record if [to] is not null. Stop recording if [to] is null.
/// [to] can be a local file, or are network stream, for example rtmp.
/// If not stopped by user, recording will be stopped when playback is finished.
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-recordconst-char-url--nullptr-const-char-format--nullptr
void record({String? to, String? format}) {
_platform.record(_getId(this), to: to, format: format);
}
/// Take a snapshot for current rendered frame.
///
/// [width] snapshot width. if not set, result is `mediaInfo.video[current_track].codec.width`
/// [height] snapshot height. if not set, result is `mediaInfo.video[current_track].codec.height`
/// Return rgba data of image size [width]x[height], stride is `width*4`
Future<Uint8List?> snapshot({int? width, int? height}) async {
return _platform.snapshot(_getId(this), width: width, height: height);
}
/// Set position range in milliseconds. Can be used by A-B loop.
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setrangeint64_t-a-int64_t-b--int64_max
void setRange({required int from, int to = -1}) {
_platform.setRange(_getId(this), from: from, to: to);
}
/// Set duration range(milliseconds) of buffered data.
///
/// [min] default 1000. wait for buffered duration >= [min]
/// If [min] < 0, then [min], [max] and [drop] will be reset to the default value
/// [max] default 4000. max buffered duration.
/// If [max] < 0, then [max] and drop will be reset to the default value
/// If [max] == 0, same as INT64_MAX
/// [drop] = true: drop old non-key frame packets to reduce buffered duration until < [max].
/// [drop] = false: wait for buffered duration < max before pushing packets
///
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setbufferrangeint64_t-minms-int64_t-maxms-bool-drop--false
/// NOTE: default values are set in [VideoPlayerController] constructor if 'lowLatency' is enabled in [registerWith]
void setBufferRange({int min = -1, int max = -1, bool drop = false}) {
_platform.setBufferRange(_getId(this), min: min, max: max, drop: drop);
}
/// fast seek to a key frame
Future<void> fastSeekTo(Duration position) async {
return _platform.fastSeekTo(_getId(this), position);
}
/// Step forward or backward.
/// Step forward if [frames] > 0, backward otherwise.
Future<void> step({int frames = 1}) async {
return _platform.step(_getId(this), frames);
}
/// set brightness. -1 <= [value] <= 1
void setBrightness(double value) {
_platform.setBrightness(_getId(this), value);
}
/// set contrast. -1 <= [value] <= 1
void setContrast(double value) {
_platform.setContrast(_getId(this), value);
}
/// set hue. -1 <= [value] <= 1
void setHue(double value) {
_platform.setHue(_getId(this), value);
}
/// set saturation. -1 <= [value] <= 1
void setSaturation(double value) {
_platform.setSaturation(_getId(this), value);
}
/// Set a program to play. used by mpegts programs or hls.
/// [programId] is the index in [MediaInfo.programs]
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setactivetracksmediatype-type-const-stdsetint-tracks
void setProgram(int programId) {
_platform.setProgram(_getId(this), programId);
}
/// Set active audio tracks. Other tracks will be disabled.
/// The tracks can be from data source from [VideoPlayerController] constructor, or an external audio data source via [setExternalAudio]
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setactivetracksmediatype-type-const-stdsetint-tracks
void setAudioTracks(List<int> value) {
_platform.setAudioTracks(_getId(this), value);
}
/// Get active audio tracks.
List<int>? getActiveAudioTracks() {
return _platform.getActiveAudioTracks(_getId(this));
}
/// Set active video tracks. Other tracks will be disabled.
/// The tracks can be from data source from [VideoPlayerController] constructor, or an external video data source via [setExternalVideo]
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setactivetracksmediatype-type-const-stdsetint-tracks
void setVideoTracks(List<int> value) {
_platform.setVideoTracks(_getId(this), value);
}
/// Get active video tracks.
List<int>? getActiveVideoTracks() {
return _platform.getActiveVideoTracks(_getId(this));
}
/// Set active subtitle tracks. Other tracks will be disabled.
/// The tracks can be from data source from [VideoPlayerController] constructor, or an external subtitle data source via [setExternalSubtitle]
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setactivetracksmediatype-type-const-stdsetint-tracks
void setSubtitleTracks(List<int> value) {
_platform.setSubtitleTracks(_getId(this), value);
}
/// Get active subtitle tracks.
List<int>? getActiveSubtitleTracks() {
return _platform.getActiveSubtitleTracks(_getId(this));
}
/// set an external audio data source
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setmediaconst-char-url-mediatype-type
void setExternalAudio(String uri) {
_platform.setExternalAudio(_getId(this), uri);
}
/// set an external video data source
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setmediaconst-char-url-mediatype-type
void setExternalVideo(String uri) {
_platform.setExternalVideo(_getId(this), uri);
}
/// set an external subtitle data source
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#void-setmediaconst-char-url-mediatype-type
void setExternalSubtitle(String uri) {
_platform.setExternalSubtitle(_getId(this), uri);
}
}
/// A [VideoPlayerController] subclass that pre-creates the underlying player so that
/// [appendBuffer] can be called before or during [initialize].
///
/// Use this class instead of [VideoPlayerController] when you need to feed media data
/// incrementally (e.g. with a `mdk:` source URL) using [appendBuffer].
///
/// Typical usage:
/// ```dart
/// final ctrl = FVPController.network('mdk:');
/// final initFuture = ctrl.initialize(); // starts but does not await yet
/// ctrl.appendBuffer(chunk1);
/// ctrl.appendBuffer(chunk2, flags: -1); // flags: -1 signals end-of-stream
/// await initFuture;
/// ```
class FVPController extends VideoPlayerController {
final int _nativeHandle;
FVPController.network(
String dataSource, {
VideoFormat? formatHint,
Map<String, String> httpHeaders = const {},
VideoPlayerOptions? videoPlayerOptions,
Future<ClosedCaptionFile>? closedCaptionFile,
}) : _nativeHandle = _platform.createPendingPlayer(),
super.network(dataSource,
formatHint: formatHint,
httpHeaders: httpHeaders,
videoPlayerOptions: videoPlayerOptions,
closedCaptionFile: closedCaptionFile);
FVPController.asset(
String dataSource, {
String? package,
Future<ClosedCaptionFile>? closedCaptionFile,
VideoPlayerOptions? videoPlayerOptions,
}) : _nativeHandle = _platform.createPendingPlayer(),
super.asset(dataSource,
package: package,
closedCaptionFile: closedCaptionFile,
videoPlayerOptions: videoPlayerOptions);
FVPController.file(
File file, {
Future<ClosedCaptionFile>? closedCaptionFile,
VideoPlayerOptions? videoPlayerOptions,
Map<String, String> httpHeaders = const {},
}) : _nativeHandle = _platform.createPendingPlayer(),
super.file(file,
closedCaptionFile: closedCaptionFile,
videoPlayerOptions: videoPlayerOptions,
httpHeaders: httpHeaders);
@override
Future<void> initialize() async {
_platform.setNextPlayerHandle(_nativeHandle);
try {
return await super.initialize();
} finally {
// Safety: clear the hint if create() was never reached (e.g. on error).
_platform.clearNextPlayerHandle();
}
}
@override
Future<void> dispose() async {
// Disposes the pre-created player if initialize() was never called.
_platform.discardPendingPlayer(_nativeHandle);
return super.dispose();
}
/// Append media data to the player. Works before, during, and after [initialize].
///
/// Used together with a `mdk:` source URL to feed data incrementally. [initialize]
/// will not complete until enough data has been appended via this method.
/// [flags] can be 0 for normal data, or -1 to signal end-of-stream.
/// Returns true on success.
/// https://github.com/wang-bin/mdk-sdk/wiki/Player-APIs#bool-appendbufferconst-uint8_t-data-size_t-size-int-flags
bool appendBuffer(Uint8List data, {int flags = 0}) {
return _platform.appendBufferByHandle(_nativeHandle, data, flags: flags);
}
}