Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.2

* Adds optional VideoFormat used to signal what format the plugin should try.
Comment thread
jtmcdole marked this conversation as resolved.
Outdated

## 0.10.1+7

* Fix tests by ignoring deprecated member use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ private static class VideoPlayer {
EventChannel eventChannel,
TextureRegistry.SurfaceTextureEntry textureEntry,
String dataSource,
Result result) {
Result result,
String formatHint) {
this.eventChannel = eventChannel;
this.textureEntry = textureEntry;

Expand All @@ -93,7 +94,7 @@ private static class VideoPlayer {
true);
}

MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, context);
MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint, context);
exoPlayer.prepare(mediaSource);

setupVideoPlayer(eventChannel, textureEntry, result);
Expand All @@ -108,29 +109,27 @@ private static boolean isFileOrAsset(Uri uri) {
}

private MediaSource buildMediaSource(
Uri uri, DataSource.Factory mediaDataSourceFactory, Context context) {
Uri uri, DataSource.Factory mediaDataSourceFactory, String formatHint, Context context) {
int type = Util.inferContentType(uri.getLastPathSegment());
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);
case C.TYPE_DASH:
return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(mediaDataSourceFactory)
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(uri);
default:
{
throw new IllegalStateException("Unsupported type: " + type);
}
if (type == C.TYPE_SS || "ss".equals(formatHint)) {
Comment thread
jtmcdole marked this conversation as resolved.
Outdated
return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);
} else if (type == C.TYPE_DASH || "dash".equals(formatHint)) {
return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
new DefaultDataSourceFactory(context, null, mediaDataSourceFactory))
.createMediaSource(uri);

} else if (type == C.TYPE_HLS || "hsl".equals(formatHint)) {
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
} else if (type == C.TYPE_OTHER || "other".equals(formatHint)) {
return new ExtractorMediaSource.Factory(mediaDataSourceFactory)
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(uri);
} else {
throw new IllegalStateException("Unsupported type: " + type);
}
}

Expand Down Expand Up @@ -343,12 +342,18 @@ public void onMethodCall(MethodCall call, Result result) {
eventChannel,
handle,
"asset:///" + assetLookupKey,
result);
result,
null);
videoPlayers.put(handle.id(), player);
} else {
player =
new VideoPlayer(
registrar.context(), eventChannel, handle, call.argument("uri"), result);
registrar.context(),
eventChannel,
handle,
call.argument("uri"),
result,
call.argument("formatHint"));
videoPlayers.put(handle.id(), player);
}
break;
Expand Down
27 changes: 25 additions & 2 deletions packages/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class DurationRange {
String toString() => '$runtimeType(start: $start, end: $end)';
}

enum VideoFormat { dash, hls, ss, other }

/// The duration, current position, buffering state, error state and settings
/// of a [VideoPlayerController].
class VideoPlayerValue {
Expand Down Expand Up @@ -148,14 +150,15 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
/// package and null otherwise.
VideoPlayerController.asset(this.dataSource, {this.package})
: dataSourceType = DataSourceType.asset,
formatHint = null,
super(VideoPlayerValue(duration: null));

/// Constructs a [VideoPlayerController] playing a video from obtained from
/// the network.
///
/// The URI for the video is given by the [dataSource] argument and must not be
/// null.
VideoPlayerController.network(this.dataSource)
VideoPlayerController.network(this.dataSource, {this.formatHint})
Comment thread
jtmcdole marked this conversation as resolved.
: dataSourceType = DataSourceType.network,
package = null,
super(VideoPlayerValue(duration: null));
Expand All @@ -168,10 +171,12 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
: dataSource = 'file://${file.path}',
dataSourceType = DataSourceType.file,
package = null,
formatHint = null,
super(VideoPlayerValue(duration: null));

int _textureId;
final String dataSource;
final VideoFormat formatHint;

/// Describes the type of data source this [VideoPlayerController]
/// is constructed with.
Expand Down Expand Up @@ -203,7 +208,10 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
dataSourceDescription = <String, dynamic>{'uri': dataSource};
break;
case DataSourceType.file:
dataSourceDescription = <String, dynamic>{'uri': dataSource};
dataSourceDescription = <String, dynamic>{
'uri': dataSource,
'formatHint': _nameOf(formatHint)
};
}
final Map<String, dynamic> response =
await _channel.invokeMapMethod<String, dynamic>(
Expand Down Expand Up @@ -397,6 +405,21 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
value = value.copyWith(volume: volume.clamp(0.0, 1.0));
await _applyVolume();
}

static String _nameOf(VideoFormat format) {
Comment thread
jtmcdole marked this conversation as resolved.
Outdated
switch (format) {
case VideoFormat.ss:
return 'ss';
Comment thread
jtmcdole marked this conversation as resolved.
Outdated
case VideoFormat.hls:
return 'hls';
case VideoFormat.dash:
return 'dash';
case VideoFormat.other:
return 'other';
default:
return null;
}
}
}

class _VideoAppLifeCycleObserver extends Object with WidgetsBindingObserver {
Expand Down
2 changes: 1 addition & 1 deletion packages/video_player/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: video_player
description: Flutter plugin for displaying inline video with other Flutter
widgets on Android and iOS.
author: Flutter Team <flutter-dev@googlegroups.com>
version: 0.10.1+7
version: 0.10.2
homepage: https://github.com/flutter/plugins/tree/master/packages/video_player

flutter:
Expand Down
3 changes: 3 additions & 0 deletions packages/video_player/test/video_player_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class FakeController extends ValueNotifier<VideoPlayerValue>
Future<void> play() async {}
@override
Future<void> setLooping(bool looping) async {}

@override
VideoFormat get formatHint => null;
Comment thread
jtmcdole marked this conversation as resolved.
}

void main() {
Expand Down