Skip to content

Commit

Permalink
[video_player] Added formatHint to to override video format on Andr…
Browse files Browse the repository at this point in the history
…oid (#2003)

Solve: flutter/flutter#39076
  • Loading branch information
jtmcdole authored and Chris Yang committed Aug 23, 2019
1 parent 801c26e commit c893375
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.2

* **Android Only** Adds optional VideoFormat used to signal what format the plugin should try.

## 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 @@ -53,6 +53,10 @@
public class VideoPlayerPlugin implements MethodCallHandler {

private static class VideoPlayer {
private static final String FORMAT_SS = "ss";
private static final String FORMAT_DASH = "dash";
private static final String FORMAT_HLS = "hls";
private static final String FORMAT_OTHER = "other";

private SimpleExoPlayer exoPlayer;

Expand All @@ -71,7 +75,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 +98,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,8 +113,29 @@ private static boolean isFileOrAsset(Uri uri) {
}

private MediaSource buildMediaSource(
Uri uri, DataSource.Factory mediaDataSourceFactory, Context context) {
int type = Util.inferContentType(uri.getLastPathSegment());
Uri uri, DataSource.Factory mediaDataSourceFactory, String formatHint, Context context) {
int type;
if (formatHint == null) {
type = Util.inferContentType(uri.getLastPathSegment());
} else {
switch (formatHint) {
case FORMAT_SS:
type = C.TYPE_SS;
break;
case FORMAT_DASH:
type = C.TYPE_DASH;
break;
case FORMAT_HLS:
type = C.TYPE_HLS;
break;
case FORMAT_OTHER:
type = C.TYPE_OTHER;
break;
default:
type = -1;
break;
}
}
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(
Expand Down Expand Up @@ -303,7 +329,8 @@ private void disposeAllPlayers() {
}

private void onDestroy() {
// The whole FlutterView is being destroyed. Here we release resources acquired for all instances
// The whole FlutterView is being destroyed. Here we release resources acquired for all
// instances
// of VideoPlayer. Once https://github.com/flutter/flutter/issues/19358 is resolved this may
// be replaced with just asserting that videoPlayers.isEmpty().
// https://github.com/flutter/flutter/issues/20989 tracks this.
Expand Down Expand Up @@ -343,12 +370,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
22 changes: 20 additions & 2 deletions 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,17 @@ 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)
/// **Android only**: The [formatHint] option allows the caller to override
/// the video format detection code.
VideoPlayerController.network(this.dataSource, {this.formatHint})
: dataSourceType = DataSourceType.network,
package = null,
super(VideoPlayerValue(duration: null));
Expand All @@ -168,10 +173,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 +210,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': _videoFormatStringMap[formatHint]
};
}
final Map<String, dynamic> response =
await _channel.invokeMapMethod<String, dynamic>(
Expand Down Expand Up @@ -397,6 +407,14 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
value = value.copyWith(volume: volume.clamp(0.0, 1.0));
await _applyVolume();
}

static const Map<VideoFormat, String> _videoFormatStringMap =
<VideoFormat, String>{
VideoFormat.ss: 'ss',
VideoFormat.hls: 'hls',
VideoFormat.dash: 'dash',
VideoFormat.other: 'other',
};
}

class _VideoAppLifeCycleObserver extends Object with WidgetsBindingObserver {
Expand Down
2 changes: 1 addition & 1 deletion 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 <[email protected]>
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 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;
}

void main() {
Expand Down

0 comments on commit c893375

Please sign in to comment.