@@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart';
33import 'package:media_kit/media_kit.dart' ;
44import 'package:media_kit_video/media_kit_video.dart' ;
55import 'package:http/http.dart' show Response, Client;
6+ import 'package:oghref_model/verifiers.dart' ;
67
78import 'client.dart' ;
89import 'testing_mode.dart' if (dart.library.io) 'testing_mode_io.dart' ;
@@ -27,11 +28,12 @@ final class MediaPlaybackPreference {
2728 final double videoScale;
2829
2930 /// Create preference
30- const MediaPlaybackPreference (
31- {this .muted = true ,
32- this .autoplay = true ,
33- this .videoSize = (width: null , height: null ),
34- this .videoScale = 1.0 });
31+ const MediaPlaybackPreference ({
32+ this .muted = true ,
33+ this .autoplay = true ,
34+ this .videoSize = (width: null , height: null ),
35+ this .videoScale = 1.0 ,
36+ });
3537}
3638
3739/// A [Widget] for handle audio and video playback if offered.
@@ -60,15 +62,17 @@ final class MediaPlayback extends StatefulWidget {
6062 /// behavourial of [Dart's built in client] (https://api.dart.dev/stable/dart-io/HttpClient-class.html).
6163 /// Therefore, [UnsupportedError] will be thrown if attempted to
6264 /// build it.
63- MediaPlayback (Iterable <Uri > resources,
64- {required this .onLoadFailed,
65- this .onLoading,
66- this .preference = const MediaPlaybackPreference (),
67- super .key})
68- : resources = List .unmodifiable (resources) {
65+ MediaPlayback (
66+ Iterable <Uri > resources, {
67+ required this .onLoadFailed,
68+ this .onLoading,
69+ this .preference = const MediaPlaybackPreference (),
70+ super .key,
71+ }) : resources = List .unmodifiable (resources) {
6972 if (isTesting) {
7073 throw UnsupportedError (
71- "No real network interaction allowed during test, and it should never be built." );
74+ "No real network interaction allowed during test, and it should never be built." ,
75+ );
7276 }
7377 }
7478
@@ -96,48 +100,45 @@ final class _MediaPlaybackState extends State<MediaPlayback> {
96100 Future <bool > _playableCond () async {
97101 final Client c = OgHrefMediaClient ();
98102
99- Stream <Response > resps =
100- Stream .fromFutures (widget.resources.map ((e) => c.head (e)));
101-
102- return resps.every ((r) {
103- String ? mime = r.headers["content-type" ]? .split (';' ).first;
104-
105- if (mime != null ) {
106- return RegExp (
107- r"^(audio|video)\/((?:x-)?(?:[\w-]+\.)*[\w-]+(?:\+[\w-]+)?)$" ,
108- dotAll: true ,
109- caseSensitive: false )
110- .hasMatch (mime);
111- }
112-
113- return false ;
114- }).then ((value) {
115- c.close ();
116- return value;
117- });
103+ Stream <Response > resps = Stream .fromFutures (
104+ widget.resources.map ((e) => c.head (e)),
105+ );
106+
107+ return resps
108+ .every (
109+ (r) => switch (r.contentTypeCategory) {
110+ ContentTypeCategory .audio || ContentTypeCategory .video => true ,
111+ _ => false ,
112+ },
113+ )
114+ .then ((value) {
115+ c.close ();
116+ return value;
117+ });
118118 }
119119
120120 @override
121121 Widget build (BuildContext context) {
122122 return FutureBuilder <bool >(
123- future: allPlayable,
124- builder: (context, snapshot) {
125- if (snapshot.hasError) {
126- return widget.onLoadFailed (context);
127- } else if (! snapshot.hasData ||
128- snapshot.connectionState == ConnectionState .waiting) {
129- return (widget.onLoading ?? (_) => const SizedBox ())(context);
130- }
131-
132- return snapshot.data!
133- ? _MediaPlaybackRender ()
134- : widget.onLoadFailed (context);
135- });
123+ future: allPlayable,
124+ builder: (context, snapshot) {
125+ if (snapshot.hasError) {
126+ return widget.onLoadFailed (context);
127+ } else if (! snapshot.hasData ||
128+ snapshot.connectionState == ConnectionState .waiting) {
129+ return (widget.onLoading ?? (_) => const SizedBox ())(context);
130+ }
131+
132+ return snapshot.data!
133+ ? _MediaPlaybackRender ()
134+ : widget.onLoadFailed (context);
135+ },
136+ );
136137 }
137138}
138139
139140final class _MediaPlaybackRender extends StatefulWidget {
140- // ignore: unused_element
141+ // ignore: unused_element_parameter
141142 _MediaPlaybackRender ({super .key});
142143
143144 @override
@@ -154,29 +155,42 @@ final class _MediaPlaybackRenderState extends State<_MediaPlaybackRender> {
154155 void initState () {
155156 super .initState ();
156157
157- final MediaPlayback playbackWidget =
158- context.findAncestorStateOfType <_MediaPlaybackState >()! .widget;
158+ final MediaPlayback playbackWidget = context
159+ .findAncestorStateOfType <_MediaPlaybackState >()!
160+ .widget;
159161
160162 final MediaPlaybackPreference preference = playbackWidget.preference;
161163
162164 player = Player (
163- configuration: PlayerConfiguration (
164- protocolWhitelist: _protocolWhitelist,
165- muted: preference.muted,
166- title: "OgHref media playback component" ));
167-
168- vidCtrl = VideoController (player,
169- configuration: VideoControllerConfiguration (
170- width: preference.videoSize.width,
171- height: preference.videoSize.height,
172- scale: preference.videoScale));
165+ configuration: PlayerConfiguration (
166+ protocolWhitelist: _protocolWhitelist,
167+ muted: preference.muted,
168+ title: "OgHref media playback component" ,
169+ ),
170+ );
171+
172+ vidCtrl = VideoController (
173+ player,
174+ configuration: VideoControllerConfiguration (
175+ width: preference.videoSize.width,
176+ height: preference.videoSize.height,
177+ scale: preference.videoScale,
178+ ),
179+ );
173180
174181 player.open (
175- Playlist (playbackWidget.resources
176- .map ((e) => Media (e.toString (),
177- httpHeaders: {"user-agent" : requestUserAgent}))
178- .toList ()),
179- play: preference.autoplay);
182+ Playlist (
183+ playbackWidget.resources
184+ .map (
185+ (e) => Media (
186+ e.toString (),
187+ httpHeaders: {"user-agent" : requestUserAgent},
188+ ),
189+ )
190+ .toList (),
191+ ),
192+ play: preference.autoplay,
193+ );
180194 }
181195
182196 @override
0 commit comments