Skip to content

Commit

Permalink
Update media playback component
Browse files Browse the repository at this point in the history
  • Loading branch information
rk0cc committed Apr 20, 2024
1 parent f9b6c43 commit 5ab1613
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 262 deletions.
7 changes: 7 additions & 0 deletions media_control/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 4.0.0

* Migration from `dart:html` to `package:web`
* Integrated selected parameters from `PlayerConfiguration` and `VideoControllerConfiguration` into `MediaPlaybackPreference`
* Disable follow redirection when evaluating media type
* New user agent string for determine media content type: `oghref_content_type_guard`

## 3.0.7

* Declare unsupported under widget testing environment.
Expand Down
7 changes: 3 additions & 4 deletions media_control/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:http/http.dart'
hide delete, get, head, patch, post, put, read, readBytes, runWithClient;
import 'package:meta/meta.dart';

import 'ua.dart' if (dart.library.html) 'ua_web.dart';
import 'ua.dart' if (dart.library.js_interop) 'ua_web.dart';

@internal
final class OgHrefMediaClient extends BaseClient {
Expand All @@ -11,9 +11,8 @@ final class OgHrefMediaClient extends BaseClient {
@override
Future<StreamedResponse> send(BaseRequest request) {
request
..headers["user-agent"] =
requestUserAgent ?? "Mozilla/5.0 oghref/2 (Media classification)"
..followRedirects = true;
..headers["user-agent"] = requestUserAgent
..followRedirects = false;

return request.send();
}
Expand Down
85 changes: 55 additions & 30 deletions media_control/lib/src/playback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,45 @@ import 'package:http/http.dart' show Response, Client;

import 'client.dart';
import 'testing_mode.dart' if (dart.library.io) 'testing_mode_io.dart';
import 'ua.dart' if (dart.library.html) 'ua_web.dart';
import 'ua.dart' if (dart.library.js_interop) 'ua_web.dart';

/// Define sizes of video frame in [MediaPlayback].
typedef VideoSize = ({int? width, int? height});

/// Cofigure preference for [MediaPlayback].
@immutable
final class MediaPlaybackPreference {
/// Determine media playback is muted initially.
final bool muted;

/// Allow [MediaPlayback] play media once all context has been loaded already.
final bool autoplay;

/// Determine fixed sizes of video playback.
final VideoSize videoSize;

/// Scale of video frame.
final double videoScale;

/// Create preference
const MediaPlaybackPreference(
{this.muted = true,
this.autoplay = true,
this.videoSize = (width: null, height: null),
this.videoScale = 1.0});
}

/// A [Widget] for handle audio and video playback if offered.
final class MediaPlayback extends StatefulWidget {
static const List<String> _protocolWhitelist = <String>["http", "https"];

/// Video, audio or both resources in URL.
///
/// If the given resources is audio type, it retains
/// an empty [Widget] but still functional when hovering
/// this area for changing media position.
final List<Uri> resources;

/// Define behaviour of player.
final PlayerConfiguration configuration;

/// Define behaviour of video controller.
final VideoControllerConfiguration? videoCtrlConfiguration;
/// Preference of [MediaPlayback] behaviours.
final MediaPlaybackPreference preference;

/// Display context when content is loading.
final WidgetBuilder? onLoading;
Expand All @@ -42,9 +63,7 @@ final class MediaPlayback extends StatefulWidget {
MediaPlayback(Iterable<Uri> resources,
{required this.onLoadFailed,
this.onLoading,
this.configuration = const PlayerConfiguration(
muted: true, protocolWhitelist: _protocolWhitelist),
this.videoCtrlConfiguration,
this.preference = const MediaPlaybackPreference(),
super.key})
: resources = List.unmodifiable(resources) {
if (isTesting) {
Expand Down Expand Up @@ -111,47 +130,53 @@ final class _MediaPlaybackState extends State<MediaPlayback> {
}

return snapshot.data!
? _MediaPlaybackRender(widget.resources)
? _MediaPlaybackRender()
: widget.onLoadFailed(context);
});
}
}

final class _MediaPlaybackRender extends StatefulWidget {
final List<Uri> resources;

// ignore: unused_element
_MediaPlaybackRender(this.resources, {super.key});
_MediaPlaybackRender({super.key});

@override
_MediaPlaybackRenderState createState() => _MediaPlaybackRenderState();
}

final class _MediaPlaybackRenderState extends State<_MediaPlaybackRender> {
static const List<String> _protocolWhitelist = ["http", "https"];

late final Player player;
late final VideoController vidCtrl;

@override
void initState() {
super.initState();
player = Player(
configuration: PlayerConfiguration(
muted: true,
ready: () async {
await player.pause();
}));
vidCtrl = VideoController(player);

Map<String, String> header = {};
String? ua = requestUserAgent;
final MediaPlayback playbackWidget =
context.findAncestorStateOfType<_MediaPlaybackState>()!.widget;

if (ua != null) {
header["user-agent"] = ua;
}
final MediaPlaybackPreference preference = playbackWidget.preference;

player.open(Playlist(widget.resources
.map((e) => Media(e.toString(), httpHeaders: header))
.toList()));
player = Player(
configuration: PlayerConfiguration(
protocolWhitelist: _protocolWhitelist,
muted: preference.muted,
title: "OgHref media playback component"));

vidCtrl = VideoController(player,
configuration: VideoControllerConfiguration(
width: preference.videoSize.width,
height: preference.videoSize.height,
scale: preference.videoScale));

player.open(
Playlist(playbackWidget.resources
.map((e) => Media(e.toString(),
httpHeaders: {"user-agent": requestUserAgent}))
.toList()),
play: preference.autoplay);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion media_control/lib/src/ua.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:meta/meta.dart';

@internal
String? get requestUserAgent => null;
String get requestUserAgent => "oghref_content_type_guard 1";
6 changes: 2 additions & 4 deletions media_control/lib/src/ua_web.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';

import 'package:meta/meta.dart';
import 'package:web/web.dart';

@internal
String? get requestUserAgent => window.navigator.userAgent;
String get requestUserAgent => window.navigator.userAgent;
3 changes: 2 additions & 1 deletion media_control/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: oghref_media_control
description: Additional package for providing mixin to build widget for playing multimedia resources
version: 3.0.7
version: 4.0.0
repository: https://github.com/rk0cc/oghref/tree/main/media_control
issue_tracker: https://github.com/rk0cc/oghref/issues
environment:
Expand All @@ -15,6 +15,7 @@ dependencies:
meta: ^1.9.1
http: ^1.1.0
collection: ^1.18.0
web: ^0.5.1
dev_dependencies:
flutter_lints: ^3.0.1
flutter:
Loading

0 comments on commit 5ab1613

Please sign in to comment.