flet-video 0.0.1__py3-none-any.whl → 0.1.0.dev18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flet-video might be problematic. Click here for more details.

@@ -0,0 +1,291 @@
1
+ import 'dart:convert';
2
+
3
+ import 'package:collection/collection.dart';
4
+ import 'package:flet/flet.dart';
5
+ import 'package:flutter/material.dart';
6
+ import 'package:media_kit/media_kit.dart';
7
+ import 'package:media_kit_video/media_kit_video.dart';
8
+
9
+ import 'utils/video.dart';
10
+
11
+ class VideoControl extends StatefulWidget {
12
+ final Control? parent;
13
+ final Control control;
14
+ final FletControlBackend backend;
15
+
16
+ const VideoControl(
17
+ {super.key,
18
+ required this.parent,
19
+ required this.control,
20
+ required this.backend});
21
+
22
+ @override
23
+ State<VideoControl> createState() => _VideoControlState();
24
+ }
25
+
26
+ class _VideoControlState extends State<VideoControl> with FletStoreMixin {
27
+ late final playerConfig = PlayerConfiguration(
28
+ title: widget.control.attrString("title", "Flet Video")!,
29
+ muted: widget.control.attrBool("muted", false)!,
30
+ pitch: widget.control.attrDouble("pitch") != null ? true : false,
31
+ ready: () {
32
+ if (widget.control.attrBool("onLoaded", false)!) {
33
+ widget.backend.triggerControlEvent(widget.control.id, "loaded");
34
+ }
35
+ },
36
+ );
37
+
38
+ late final Player player = Player(
39
+ configuration: playerConfig,
40
+ );
41
+ late final videoControllerConfiguration = parseControllerConfiguration(
42
+ widget.control, "configuration", const VideoControllerConfiguration())!;
43
+ late final controller =
44
+ VideoController(player, configuration: videoControllerConfiguration);
45
+
46
+ @override
47
+ void initState() {
48
+ super.initState();
49
+ player.open(Playlist(parseVideoMedia(widget.control, "playlist")),
50
+ play: widget.control.attrBool("autoPlay", false)!);
51
+ }
52
+
53
+ @override
54
+ void dispose() {
55
+ player.dispose();
56
+ super.dispose();
57
+ }
58
+
59
+ void _onError(String? message) {
60
+ debugPrint("Video onError: $message");
61
+ widget.backend
62
+ .triggerControlEvent(widget.control.id, "error", message ?? "");
63
+ }
64
+
65
+ void _onCompleted(String? message) {
66
+ debugPrint("Video onCompleted: $message");
67
+ widget.backend
68
+ .triggerControlEvent(widget.control.id, "completed", message ?? "");
69
+ }
70
+
71
+ void _onTrackChanged(String? message) {
72
+ debugPrint("Video onTrackChanged: $message");
73
+ widget.backend
74
+ .triggerControlEvent(widget.control.id, "track_changed", message ?? "");
75
+ }
76
+
77
+ @override
78
+ Widget build(BuildContext context) {
79
+ debugPrint("Video build: ${widget.control.id}");
80
+
81
+ FilterQuality filterQuality = parseFilterQuality(
82
+ widget.control.attrString("filterQuality"), FilterQuality.low)!;
83
+
84
+ return withPageArgs((context, pageArgs) {
85
+ SubtitleTrack? subtitleTrack;
86
+ Map<String, dynamic>? subtitleConfiguration = parseSubtitleConfiguration(
87
+ Theme.of(context), widget.control, "subtitleConfiguration");
88
+ if (subtitleConfiguration?["src"] != null) {
89
+ try {
90
+ var assetSrc = getAssetSrc(subtitleConfiguration?["src"],
91
+ pageArgs.pageUri!, pageArgs.assetsDir);
92
+ subtitleTrack = parseSubtitleTrack(
93
+ assetSrc,
94
+ subtitleConfiguration?["title"],
95
+ subtitleConfiguration?["language"]);
96
+ } catch (ex) {
97
+ _onError(ex.toString());
98
+ subtitleTrack = SubtitleTrack.no();
99
+ }
100
+ }
101
+
102
+ SubtitleViewConfiguration? subtitleViewConfiguration =
103
+ subtitleConfiguration?["subtitleViewConfiguration"];
104
+
105
+ bool onError = widget.control.attrBool("onError", false)!;
106
+ bool onCompleted = widget.control.attrBool("onCompleted", false)!;
107
+ bool onTrackChanged = widget.control.attrBool("onTrackChanged", false)!;
108
+
109
+ double? volume = widget.control.attrDouble("volume");
110
+ double? pitch = widget.control.attrDouble("pitch");
111
+ double? playbackRate = widget.control.attrDouble("playbackRate");
112
+ bool? shufflePlaylist = widget.control.attrBool("shufflePlaylist");
113
+ bool? showControls = widget.control.attrBool("showControls", true)!;
114
+ PlaylistMode? playlistMode = PlaylistMode.values.firstWhereOrNull((e) =>
115
+ e.name.toLowerCase() ==
116
+ widget.control.attrString("playlistMode")?.toLowerCase());
117
+
118
+ final double? prevVolume = widget.control.state["volume"];
119
+ final double? prevPitch = widget.control.state["pitch"];
120
+ final double? prevPlaybackRate = widget.control.state["playbackRate"];
121
+ final bool? prevShufflePlaylist = widget.control.state["shufflePlaylist"];
122
+ final PlaylistMode? prevPlaylistMode =
123
+ widget.control.state["playlistMode"];
124
+ final SubtitleTrack? prevSubtitleTrack =
125
+ widget.control.state["subtitleTrack"];
126
+
127
+ Video? video = Video(
128
+ controller: controller,
129
+ wakelock: widget.control.attrBool("wakelock", true)!,
130
+ controls: showControls ? AdaptiveVideoControls : null,
131
+ pauseUponEnteringBackgroundMode:
132
+ widget.control.attrBool("pauseUponEnteringBackgroundMode", true)!,
133
+ resumeUponEnteringForegroundMode:
134
+ widget.control.attrBool("resumeUponEnteringForegroundMode", false)!,
135
+ alignment:
136
+ parseAlignment(widget.control, "alignment", Alignment.center)!,
137
+ fit: parseBoxFit(widget.control.attrString("fit"), BoxFit.contain)!,
138
+ filterQuality: filterQuality,
139
+ subtitleViewConfiguration:
140
+ subtitleViewConfiguration ?? const SubtitleViewConfiguration(),
141
+ fill: parseColor(Theme.of(context),
142
+ widget.control.attrString("fillColor", "")!) ??
143
+ const Color(0xFF000000),
144
+ onEnterFullscreen: widget.control.attrBool("onEnterFullscreen", false)!
145
+ ? () async {
146
+ widget.backend.triggerControlEvent(
147
+ widget.control.id, "enter_fullscreen", "");
148
+ }
149
+ : defaultEnterNativeFullscreen,
150
+ onExitFullscreen: widget.control.attrBool("onExitFullscreen", false)!
151
+ ? () async {
152
+ widget.backend.triggerControlEvent(
153
+ widget.control.id, "exit_fullscreen", "");
154
+ }
155
+ : defaultExitNativeFullscreen,
156
+ );
157
+
158
+ () async {
159
+ if (volume != null &&
160
+ volume != prevVolume &&
161
+ volume >= 0 &&
162
+ volume <= 100) {
163
+ widget.control.state["volume"] = volume;
164
+ debugPrint("Video.setVolume($volume)");
165
+ await player.setVolume(volume);
166
+ }
167
+
168
+ if (pitch != null && pitch != prevPitch) {
169
+ widget.control.state["pitch"] = pitch;
170
+ debugPrint("Video.setPitch($pitch)");
171
+ await player.setPitch(pitch);
172
+ }
173
+
174
+ if (playbackRate != null && playbackRate != prevPlaybackRate) {
175
+ widget.control.state["playbackRate"] = playbackRate;
176
+ debugPrint("Video.setPlaybackRate($playbackRate)");
177
+ await player.setRate(playbackRate);
178
+ }
179
+
180
+ if (shufflePlaylist != null && shufflePlaylist != prevShufflePlaylist) {
181
+ widget.control.state["shufflePlaylist"] = shufflePlaylist;
182
+ debugPrint("Video.setShufflePlaylist($shufflePlaylist)");
183
+ await player.setShuffle(shufflePlaylist);
184
+ }
185
+
186
+ if (playlistMode != null && playlistMode != prevPlaylistMode) {
187
+ widget.control.state["playlistMode"] = playlistMode;
188
+ debugPrint("Video.setPlaylistMode($playlistMode)");
189
+ await player.setPlaylistMode(playlistMode);
190
+ }
191
+
192
+ if (subtitleTrack != null && subtitleTrack != prevSubtitleTrack) {
193
+ widget.control.state["subtitleTrack"] = subtitleTrack;
194
+ debugPrint("Video.setSubtitleTrack($subtitleTrack)");
195
+ await player.setSubtitleTrack(subtitleTrack);
196
+ }
197
+
198
+ widget.backend.subscribeMethods(widget.control.id,
199
+ (methodName, args) async {
200
+ switch (methodName) {
201
+ case "play":
202
+ debugPrint("Video.play($hashCode)");
203
+ await player.play();
204
+ break;
205
+ case "pause":
206
+ debugPrint("Video.pause($hashCode)");
207
+ await player.pause();
208
+ break;
209
+ case "play_or_pause":
210
+ debugPrint("Video.playOrPause($hashCode)");
211
+ await player.playOrPause();
212
+ break;
213
+ case "stop":
214
+ debugPrint("Video.stop($hashCode)");
215
+ await player.stop();
216
+ player.open(Playlist(parseVideoMedia(widget.control, "playlist")),
217
+ play: false);
218
+ break;
219
+ case "seek":
220
+ debugPrint("Video.jump($hashCode)");
221
+ await player.seek(Duration(
222
+ milliseconds: int.tryParse(args["position"] ?? "") ?? 0));
223
+ break;
224
+ case "next":
225
+ debugPrint("Video.next($hashCode)");
226
+ await player.next();
227
+ break;
228
+ case "previous":
229
+ debugPrint("Video.previous($hashCode)");
230
+ await player.previous();
231
+ break;
232
+ case "jump_to":
233
+ debugPrint("Video.jump($hashCode)");
234
+ await player.jump(parseInt(args["media_index"], 0)!);
235
+ break;
236
+ case "playlist_add":
237
+ debugPrint("Video.add($hashCode)");
238
+ Map<String, dynamic> extras =
239
+ json.decode(args["extras"]!.replaceAll("'", "\""));
240
+ Map<String, String> httpHeaders =
241
+ (json.decode(args["http_headers"]!.replaceAll("'", "\""))
242
+ as Map)
243
+ .map((key, value) =>
244
+ MapEntry(key.toString(), value.toString()));
245
+ await player.add(Media(args["resource"]!,
246
+ extras: extras.isNotEmpty ? extras : null,
247
+ httpHeaders: httpHeaders.isNotEmpty ? httpHeaders : null));
248
+ break;
249
+ case "playlist_remove":
250
+ debugPrint("Video.remove($hashCode)");
251
+ await player.remove(parseInt(args["media_index"], 0)!);
252
+ break;
253
+ case "is_playing":
254
+ debugPrint("Video.isPlaying($hashCode)");
255
+ return player.state.playing.toString();
256
+ case "is_completed":
257
+ debugPrint("Video.isCompleted($hashCode)");
258
+ return player.state.completed.toString();
259
+ case "get_duration":
260
+ debugPrint("Video.getDuration($hashCode)");
261
+ return player.state.duration.inMilliseconds.toString();
262
+ case "get_current_position":
263
+ debugPrint("Video.getCurrentPosition($hashCode)");
264
+ return player.state.position.inMilliseconds.toString();
265
+ }
266
+ return null;
267
+ });
268
+ }();
269
+
270
+ player.stream.error.listen((event) {
271
+ if (onError) {
272
+ _onError(event.toString());
273
+ }
274
+ });
275
+
276
+ player.stream.completed.listen((event) {
277
+ if (onCompleted) {
278
+ _onCompleted(event.toString());
279
+ }
280
+ });
281
+
282
+ player.stream.playlist.listen((event) {
283
+ if (onTrackChanged) {
284
+ _onTrackChanged(event.index.toString());
285
+ }
286
+ });
287
+
288
+ return constrainedControl(context, video, widget.parent, widget.control);
289
+ });
290
+ }
291
+ }
@@ -0,0 +1,20 @@
1
+ name: flet_video
2
+ description: Flet Video control
3
+ homepage: https://flet.dev
4
+ repository: https://github.com/flet-dev/flet/packages/flet_video
5
+ version: 0.1.0
6
+ environment:
7
+ sdk: '>=3.2.3 <4.0.0'
8
+ flutter: '>=1.17.0'
9
+ dependencies:
10
+ flutter:
11
+ sdk: flutter
12
+ collection: ^1.16.0
13
+ media_kit: ^1.1.10
14
+ media_kit_video: ^1.2.4
15
+ media_kit_libs_video: ^1.0.4
16
+ flet: ^0.25.1
17
+ dev_dependencies:
18
+ flutter_test:
19
+ sdk: flutter
20
+ flutter_lints: ^2.0.0
.DS_Store DELETED
Binary file
flet_video/.DS_Store DELETED
Binary file
Binary file
@@ -1,14 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: flet-video
3
- Version: 0.0.1
4
- Summary: Flet Video control
5
- Author: Appveyor Systems Inc.
6
- Author-email: hello@flet.dev
7
- Requires-Python: >=3.8,<4.0
8
- Project-URL: homepage, https://flet.dev
9
- Download-URL:
10
- Description-Content-Type: text/markdown
11
-
12
- # Flet Video
13
-
14
- Video control for Flet.
@@ -1,7 +0,0 @@
1
- .DS_Store,sha256=UGxWgJfmLLyazGK5A-uGE3FwdljfvRyUi6SV7VdJU-E,6148
2
- flet_video/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
3
- flet_video/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
- flet_video-0.0.1.dist-info/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
5
- flet_video-0.0.1.dist-info/METADATA,sha256=cDizSAGhaFaLKbWeIXOSOcg6R15EzVJRpWPOBIl54v4,301
6
- flet_video-0.0.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
7
- flet_video-0.0.1.dist-info/RECORD,,