Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[video_player_avplay] Add get streaming property interface and Update SetStreamingProperty interface #672

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion packages/video_player_avplay/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT
## 0.4.0

* Minor refactor.
* Add getStreamingProperty interface.

## 0.3.3

Expand Down
2 changes: 1 addition & 1 deletion packages/video_player_avplay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec.

```yaml
dependencies:
video_player_avplay: ^0.3.3
video_player_avplay: ^0.4.0
```

Then you can import `video_player_avplay` in your Dart code:
Expand Down
101 changes: 96 additions & 5 deletions packages/video_player_avplay/lib/src/messages.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,58 @@ class DurationMessage {
}
}

class StreamingPropertyMessage {
StreamingPropertyMessage({
required this.playerId,
required this.streamingProperty,
});

int playerId;

String streamingProperty;

Object encode() {
return <Object?>[
playerId,
streamingProperty,
];
}

static StreamingPropertyMessage decode(Object result) {
result as List<Object?>;
return StreamingPropertyMessage(
playerId: result[0]! as int,
streamingProperty: result[1]! as String,
);
}
}

class StreamingPropertyTypeMessage {
StreamingPropertyTypeMessage({
required this.playerId,
required this.streamingPropertyType,
});

int playerId;

String streamingPropertyType;

Object encode() {
return <Object?>[
playerId,
streamingPropertyType,
];
}

static StreamingPropertyTypeMessage decode(Object result) {
result as List<Object?>;
return StreamingPropertyTypeMessage(
playerId: result[0]! as int,
streamingPropertyType: result[1]! as String,
);
}
}

class _VideoPlayerAvplayApiCodec extends StandardMessageCodec {
const _VideoPlayerAvplayApiCodec();
@override
Expand Down Expand Up @@ -395,15 +447,21 @@ class _VideoPlayerAvplayApiCodec extends StandardMessageCodec {
} else if (value is SelectedTracksMessage) {
buffer.putUint8(136);
writeValue(buffer, value.encode());
} else if (value is TrackMessage) {
} else if (value is StreamingPropertyMessage) {
buffer.putUint8(137);
writeValue(buffer, value.encode());
} else if (value is TrackTypeMessage) {
} else if (value is StreamingPropertyTypeMessage) {
buffer.putUint8(138);
writeValue(buffer, value.encode());
} else if (value is VolumeMessage) {
} else if (value is TrackMessage) {
buffer.putUint8(139);
writeValue(buffer, value.encode());
} else if (value is TrackTypeMessage) {
buffer.putUint8(140);
writeValue(buffer, value.encode());
} else if (value is VolumeMessage) {
buffer.putUint8(141);
writeValue(buffer, value.encode());
} else {
super.writeValue(buffer, value);
}
Expand Down Expand Up @@ -431,10 +489,14 @@ class _VideoPlayerAvplayApiCodec extends StandardMessageCodec {
case 136:
return SelectedTracksMessage.decode(readValue(buffer)!);
case 137:
return TrackMessage.decode(readValue(buffer)!);
return StreamingPropertyMessage.decode(readValue(buffer)!);
case 138:
return TrackTypeMessage.decode(readValue(buffer)!);
return StreamingPropertyTypeMessage.decode(readValue(buffer)!);
case 139:
return TrackMessage.decode(readValue(buffer)!);
case 140:
return TrackTypeMessage.decode(readValue(buffer)!);
case 141:
return VolumeMessage.decode(readValue(buffer)!);
default:
return super.readValueOfType(type, buffer);
Expand Down Expand Up @@ -876,4 +938,33 @@ class VideoPlayerAvplayApi {
return;
}
}

Future<StreamingPropertyMessage> getStreamingProperty(
StreamingPropertyTypeMessage arg_msg) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.video_player_avplay.VideoPlayerAvplayApi.getStreamingProperty',
codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_msg]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as StreamingPropertyMessage?)!;
}
}
}
38 changes: 35 additions & 3 deletions packages/video_player_avplay/lib/src/video_player_tizen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

Expand Down Expand Up @@ -42,7 +40,13 @@ class VideoPlayerTizen extends VideoPlayerPlatform {
message.httpHeaders = dataSource.httpHeaders;
message.drmConfigs = dataSource.drmConfigs?.toMap();
message.playerOptions = dataSource.playerOptions;
message.streamingProperty = dataSource.streamingProperty;
message.streamingProperty = dataSource.streamingProperty == null
? null
: <String, String>{
for (final MapEntry<StreamingPropertyType, String> entry
in dataSource.streamingProperty!.entries)
_streamingPropertyType[entry.key]!: entry.value
};
break;
case DataSourceType.file:
message.uri = dataSource.uri;
Expand Down Expand Up @@ -197,6 +201,16 @@ class VideoPlayerTizen extends VideoPlayerPlatform {
return Duration(milliseconds: response.position);
}

@override
Future<String> getStreamingProperty(
int playerId, StreamingPropertyType type) async {
final StreamingPropertyMessage streamingPropertyMessage =
await _api.getStreamingProperty(StreamingPropertyTypeMessage(
playerId: playerId,
streamingPropertyType: _streamingPropertyType[type]!));
return streamingPropertyMessage.streamingProperty;
}

@override
Stream<VideoEvent> videoEventsFor(int playerId) {
return _eventChannelFor(playerId)
Expand Down Expand Up @@ -286,4 +300,22 @@ class VideoPlayerTizen extends VideoPlayerPlatform {
2: AudioTrackChannelType.stereo,
3: AudioTrackChannelType.surround,
};

static const Map<StreamingPropertyType, String> _streamingPropertyType =
<StreamingPropertyType, String>{
StreamingPropertyType.adaptiveInfo: 'ADAPTIVE_INFO',
StreamingPropertyType.availableBitrate: 'AVAILABLE_BITRATE',
StreamingPropertyType.cookie: 'COOKIE',
StreamingPropertyType.currentBandwidth: 'CURRENT_BANDWIDTH',
StreamingPropertyType.getLiveDuration: 'GET_LIVE_DURATION',
StreamingPropertyType.inAppMultiView: 'IN_APP_MULTIVIEW',
StreamingPropertyType.isLive: 'IS_LIVE',
StreamingPropertyType.listenSparseTrack: 'LISTEN_SPARSE_TRACK',
StreamingPropertyType.portraitMode: 'PORTRAIT_MODE',
StreamingPropertyType.prebufferMode: 'PREBUFFER_MODE',
StreamingPropertyType.setMixedFrame: 'SET_MIXEDFRAME',
StreamingPropertyType.setMode4K: 'SET_MODE_4K',
StreamingPropertyType.userAgent: 'USER_AGENT',
StreamingPropertyType.useVideoMixer: 'USE_VIDEOMIXER',
};
}
10 changes: 9 additions & 1 deletion packages/video_player_avplay/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
/// Sets specific feature values for HTTP, MMS, or specific streaming engine (Smooth Streaming, HLS, DASH, DivX Plus Streaming, or Widevine).
/// The available streaming properties depend on the streaming protocol or engine.
/// Only for [VideoPlayerController.network].
final Map<String, String>? streamingProperty;
final Map<StreamingPropertyType, String>? streamingProperty;

/// **Android only**. Will override the platform's generic file format
/// detection with whatever is set here.
Expand Down Expand Up @@ -714,6 +714,14 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
await _applyVolume();
}

/// Retrieves a specific property value obtained by the streaming engine (Smooth Streaming, HLS, DASH, or Widevine).
Future<String> getStreamingProperty(StreamingPropertyType type) async {
if (_isDisposedOrNotInitialized) {
return '';
}
return _videoPlayerPlatform.getStreamingProperty(_playerId, type);
}

/// Sets the playback speed of [this].
///
/// [speed] indicates a speed value with different platforms accepting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ abstract class VideoPlayerPlatform extends PlatformInterface {
throw UnimplementedError('getDuration() has not been implemented.');
}

/// Retrieves a specific property value obtained by the streaming engine (Smooth Streaming, HLS, DASH, or Widevine).
Future<String> getStreamingProperty(
int playerId, StreamingPropertyType type) {
throw UnimplementedError(
'getStreamingProperty() has not been implemented.');
}

/// Returns a widget displaying the video with a given playerId.
Widget buildView(int playerId) {
throw UnimplementedError('buildView() has not been implemented.');
Expand Down Expand Up @@ -217,7 +224,7 @@ class DataSource {
Map<String, dynamic>? playerOptions;

/// Sets specific feature values for HTTP, MMS, or specific streaming engine
Map<String, String>? streamingProperty;
Map<StreamingPropertyType, String>? streamingProperty;
}

/// The way in which the video was originally loaded.
Expand Down Expand Up @@ -253,6 +260,63 @@ enum VideoFormat {
other,
}

/// The streaming property type.
enum StreamingPropertyType {
/// HTTP request cookie used to establish the session with the HTTP server.
cookie,

/// HTTP user agent, used in the HTTP request header.
userAgent,

/// Property to initiate prebuffering mode. The second parameter indicates start-time for prebuffered content, in milliseconds.
prebufferMode,

/// Sets a custom streaming URL with various streaming parameters, such as "BITRATES", "STARTBITRATE", or "SKIPBITRATE".
/// String containing custom attributes for adaptive streaming playback.
/// "STARTBITRATE=" Valid values are "LOWEST", "HIGHEST", and "AVERAGE". You can also define a specific bandwidth for the start of playback.
/// "BITRATES=" Use '~' to define a bandwidth range (5000 ~ 20000). You can also define a specific bandwidth for playback.
/// "SKIPBITRATE=" Defines the bandwidth to use after a skip operation.
/// "STARTFRAGMENT=" For live content playback, defines the start fragment number.
/// "FIXED_MAX_RESOLUTION=max_widthXmax_height". Only if the given media URI such as mpd in MPEG-DASH or m3u8 in HLS through open()
/// method doesn't describe entire required video resolutions,application should use this attribute to complete the resolution information for the player.
adaptiveInfo,

/// Forces the player to use the 4K UHD decoder. Its parameter can be the string "TRUE" or "FALSE".
/// In the case of adaptive streaming which requires stream-change for different video resolution during the playback,
/// Only if the given media URI such as mpd in MPEG-DASH or m3u8 in HLS through open() method doesn't describe entire required video resolutions,
/// pass TRUE with this property in IDLE state.
setMode4K,

/// For the Smooth Streaming case, configures the player to listen for a "Sparse name" configured through "propertyParam" . The sparse track name is a string.
listenSparseTrack,

/// Whether the stream is LIVE or VOD. Applicable to all streaming types.
isLive,

/// String listing the available bit-rates for the currently-playing stream.
availableBitrate,

/// String describing the duration of live content.
getLiveDuration,

/// String describing the current streaming bandwidth.
currentBandwidth,

/// Property used for enabling/initializing video mixer feature on B2B product only. It should be set before
/// setting SET_MIXEDFRAME property on the player.
useVideoMixer,

/// Property to set the position of mixed frame. setDisplayRect with required position on corresponding
/// player instance to be called before setting this property.
setMixedFrame,

/// Property to force the playback the video in potrait mode on B2B proudct only.
portraitMode,

/// Property to select the Scaler type, By Default MAIN Scaler selected.
inAppMultiView,
}

/// Event emitted from the platform implementation.
@immutable
class VideoEvent {
Expand Down
14 changes: 14 additions & 0 deletions packages/video_player_avplay/pigeons/messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ class DurationMessage {
List<int?>? durationRange;
}

class StreamingPropertyMessage {
StreamingPropertyMessage(this.playerId, this.streamingProperty);
int playerId;
String streamingProperty;
}

class StreamingPropertyTypeMessage {
StreamingPropertyTypeMessage(this.playerId, this.streamingPropertyType);
int playerId;
String streamingPropertyType;
}

@HostApi()
abstract class VideoPlayerAvplayApi {
void initialize();
Expand All @@ -109,4 +121,6 @@ abstract class VideoPlayerAvplayApi {
void pause(PlayerMessage msg);
void setMixWithOthers(MixWithOthersMessage msg);
void setDisplayGeometry(GeometryMessage msg);
StreamingPropertyMessage getStreamingProperty(
StreamingPropertyTypeMessage msg);
}
2 changes: 1 addition & 1 deletion packages/video_player_avplay/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: video_player_avplay
description: Flutter plugin for displaying inline video on Tizen TV devices.
homepage: https://github.com/flutter-tizen/plugins
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player_avplay
version: 0.3.3
version: 0.4.0

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
6 changes: 3 additions & 3 deletions packages/video_player_avplay/tizen/src/media_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ int64_t MediaPlayer::Create(const std::string &uri,
return -1;
}

std::string cookie = flutter_common::GetValue(create_message.http_headers(),
"Cookie", std::string());
std::string cookie = flutter_common::GetValue(
create_message.streaming_property(), "COOKIE", std::string());
if (!cookie.empty()) {
int ret =
player_set_streaming_cookie(player_, cookie.c_str(), cookie.size());
Expand All @@ -97,7 +97,7 @@ int64_t MediaPlayer::Create(const std::string &uri,
}
}
std::string user_agent = flutter_common::GetValue(
create_message.http_headers(), "User-Agent", std::string());
create_message.streaming_property(), "USER_AGENT", std::string());
if (!user_agent.empty()) {
int ret = player_set_streaming_user_agent(player_, user_agent.c_str(),
user_agent.size());
Expand Down
Loading
Loading