Skip to content

Commit 3aa0b0d

Browse files
authored
[video_player_avplay] Add new features for DASH (#909)
1 parent eb2ff7f commit 3aa0b0d

30 files changed

+662
-203
lines changed

packages/video_player_avplay/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 0.7.0
2+
* Add new features for DASH video player
3+
1. Support update token before and after player prepare done.
4+
2. Support setting resolution, frame rate and whether to update same language code.
5+
3. Support obtaining streaming information such as audio, video, and subtitle.
6+
4. Support getting the http response header of the requested url.
7+
5. Support capturing ad information in the stream.
8+
* Update plusplayer
9+
1. [DASH] Fix the issue of incorrect duration after the stream changes from live to static.
10+
2. [Common] Add protect for smpted image subtitle decoder.
11+
112
## 0.6.0
213
* Support multi TizenOS version.
314

packages/video_player_avplay/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec.
1212

1313
```yaml
1414
dependencies:
15-
video_player_avplay: ^0.6.0
15+
video_player_avplay: ^0.7.0
1616
```
1717
1818
Then you can import `video_player_avplay` in your Dart code:

packages/video_player_avplay/example/lib/main.dart

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,48 @@ class _DashRomoteVideo extends StatefulWidget {
127127

128128
class _DashRomoteVideoState extends State<_DashRomoteVideo> {
129129
late VideoPlayerController _controller;
130+
// Optional
131+
final Map<StreamingPropertyType, String> _streamingProperties =
132+
<StreamingPropertyType, String>{
133+
StreamingPropertyType.unwantedResolution: '3840X2160',
134+
StreamingPropertyType.unwantedFramerate: '60',
135+
StreamingPropertyType.updateSameLanguageCode: '1',
136+
137+
/// update token [before] dash-player prepare done.
138+
StreamingPropertyType.dashToken: 'YWJyVHlwZT1CUi1BVkMtREFTSC',
139+
StreamingPropertyType.openHttpHeader: 'TRUE',
140+
};
130141

131142
@override
132143
void initState() {
133144
super.initState();
134145
_controller = VideoPlayerController.network(
135146
'https://dash.akamaized.net/dash264/TestCasesUHD/2b/11/MultiRate.mpd',
136147
formatHint: VideoFormat.dash,
148+
streamingProperty: _streamingProperties,
137149
);
138150

139151
_controller.addListener(() {
140152
if (_controller.value.hasError) {
141153
print(_controller.value.errorDescription);
142154
}
155+
if (_controller.value.hasAdInfo) {
156+
print(_controller.value.adInfo);
157+
}
143158
setState(() {});
144159
});
145160
_controller.setLooping(true);
146-
_controller.initialize().then((_) => setState(() {}));
161+
_controller.initialize().then((_) {
162+
setState(() {});
163+
// update token [after] dash-player prepare done.
164+
_controller.updateDashToken('YWJyVHlwZT1CUi1BVkMtREFTSC');
165+
// New features: get the following properties.
166+
_controller.getStreamingProperty(StreamingPropertyType.audioStreamInfo);
167+
_controller
168+
.getStreamingProperty(StreamingPropertyType.subtitleStreamInfo);
169+
_controller.getStreamingProperty(StreamingPropertyType.videoStreamInfo);
170+
_controller.getData(<DashPlayerProperty>{DashPlayerProperty.httpHeader});
171+
});
147172
_controller.play();
148173
}
149174

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2025 Samsung Electronics Co., Ltd. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/foundation.dart' show immutable, objectRuntimeType;
6+
7+
/// Ad information class for DASH. This class contains all the necessary information about an ad.
8+
@immutable
9+
class AdInfoFromDash {
10+
/// Create a new instance of [AdInfoFromDash].
11+
const AdInfoFromDash({
12+
required this.adId,
13+
required this.cancelIndicator,
14+
required this.startTime,
15+
required this.endTime,
16+
required this.durationTime,
17+
required this.outOfNetworkIndicator,
18+
});
19+
20+
/// The unique identifier for the ad event from DASH.
21+
final int adId;
22+
23+
/// When set to "true", indicates that a previously sent segmentation event, has been cancelled.
24+
final bool cancelIndicator;
25+
26+
/// The start time of the ad in milliseconds.
27+
final int startTime;
28+
29+
/// The end time of the ad in milliseconds.
30+
final int endTime;
31+
32+
/// The duration of the ad in milliseconds.
33+
final int durationTime;
34+
35+
/// When set to "1", indicates that the splice event is AD insert start time point, AD start time, end time and Duration are valid.
36+
/// When set to "0", indicates that the splice event is AD end time point, only end time is valid.
37+
final int outOfNetworkIndicator;
38+
39+
/// Parse the ad information from a map. Returns null if the map is null or empty. Otherwise, returns a new instance of [AdInfoFromDash].
40+
static AdInfoFromDash? fromAdInfoMap(Map<Object?, Object?>? adInfo) {
41+
if (adInfo!.isNotEmpty) {
42+
final int adId = adInfo['id']! as int;
43+
final int startTime = adInfo['start_ms']! as int;
44+
final int endTime = adInfo['end_ms']! as int;
45+
final int durationTime = adInfo['duration_ms']! as int;
46+
final int outOfNetworkIndicator =
47+
adInfo['out_of_network_indicator']! as int;
48+
final bool cancelIndicator = adInfo['cancel_indicator']! as bool;
49+
50+
return AdInfoFromDash(
51+
adId: adId,
52+
cancelIndicator: cancelIndicator,
53+
startTime: startTime,
54+
endTime: endTime,
55+
durationTime: durationTime,
56+
outOfNetworkIndicator: outOfNetworkIndicator,
57+
);
58+
}
59+
60+
return null;
61+
}
62+
63+
@override
64+
String toString() {
65+
return '${objectRuntimeType(this, 'AdInfoFromDash')}('
66+
'adId: $adId, '
67+
'cancelIndicator: $cancelIndicator, '
68+
'startTime: $startTime, '
69+
'endTime: $endTime, '
70+
'durationTime: $durationTime, '
71+
'outOfNetworkIndicator: $outOfNetworkIndicator)';
72+
}
73+
74+
@override
75+
bool operator ==(Object other) =>
76+
identical(this, other) ||
77+
other is AdInfoFromDash &&
78+
runtimeType == other.runtimeType &&
79+
adId == other.adId &&
80+
cancelIndicator == other.cancelIndicator &&
81+
startTime == other.startTime &&
82+
endTime == other.endTime &&
83+
durationTime == other.durationTime &&
84+
outOfNetworkIndicator == other.outOfNetworkIndicator;
85+
86+
@override
87+
int get hashCode => Object.hash(
88+
adId,
89+
cancelIndicator,
90+
startTime,
91+
endTime,
92+
durationTime,
93+
outOfNetworkIndicator,
94+
);
95+
}

0 commit comments

Comments
 (0)