Skip to content

Commit 65a17d2

Browse files
committed
Add :start-time & :stop-time handling & factory const. in Media
1 parent 7191cb7 commit 65a17d2

File tree

2 files changed

+141
-42
lines changed

2 files changed

+141
-42
lines changed

ffi/lib/src/mediaSource/media.dart

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,87 @@ import 'package:dart_vlc_ffi/src/enums/mediaType.dart';
1616
/// * A [Media] from a [File].
1717
///
1818
/// ```dart
19-
/// Media media = await Media.file(new File('C:/music.ogg'));
19+
/// Media media = Media.file(File('C:/music.ogg'));
2020
/// ```
2121
///
2222
/// * A [Media] from a [Uri].
2323
///
2424
/// ```dart
25-
/// Media media = await Media.network('http://alexmercerind.github.io/music.mp3');
25+
/// Media media = Media.network('http://alexmercerind.github.io/music.mp3');
2626
/// ```
2727
///
28+
/// For starting a [Media] at particular time, one can pass `startTime`.
29+
///
30+
/// ```dart
31+
/// Media media = Media.file(
32+
/// File('C:/music.ogg'),
33+
/// startTime: Duration(milliseconds: 20),
34+
/// );
35+
/// ```
2836
///
2937
class Media implements MediaSource {
3038
MediaSourceType get mediaSourceType => MediaSourceType.media;
3139
final MediaType mediaType;
3240
final String resource;
41+
final Duration startTime;
42+
final Duration stopTime;
3343
final Map<String, String> metas;
3444

35-
const Media._(
36-
{required this.mediaType, required this.resource, required this.metas});
45+
const Media._({
46+
required this.mediaType,
47+
required this.resource,
48+
required this.metas,
49+
this.startTime: Duration.zero,
50+
this.stopTime: Duration.zero,
51+
});
3752

3853
/// Makes [Media] object from a [File].
39-
static Media file(File file,
40-
{bool parse: false,
41-
Map<String, dynamic>? extras,
42-
Duration timeout: const Duration(seconds: 10)}) {
43-
final media =
44-
Media._(mediaType: MediaType.file, resource: file.path, metas: {});
45-
54+
factory Media.file(
55+
File file, {
56+
bool parse: false,
57+
Map<String, dynamic>? extras,
58+
Duration timeout: const Duration(seconds: 10),
59+
startTime: Duration.zero,
60+
stopTime: Duration.zero,
61+
}) {
62+
final media = Media._(
63+
mediaType: MediaType.file,
64+
resource: file.path,
65+
metas: {},
66+
startTime: startTime,
67+
stopTime: stopTime,
68+
);
4669
if (parse) {
4770
media.parse(timeout);
4871
}
4972
return media;
5073
}
5174

5275
/// Makes [Media] object from url.
53-
static Media network(dynamic url,
54-
{bool parse: false,
55-
Map<String, dynamic>? extras,
56-
Duration timeout: const Duration(seconds: 10)}) {
76+
factory Media.network(
77+
dynamic url, {
78+
bool parse: false,
79+
Map<String, dynamic>? extras,
80+
Duration timeout: const Duration(seconds: 10),
81+
startTime: Duration.zero,
82+
stopTime: Duration.zero,
83+
}) {
5784
final resource = (url is Uri) ? url.toString() : url;
58-
final Media media =
59-
Media._(mediaType: MediaType.network, resource: resource, metas: {});
60-
85+
final Media media = Media._(
86+
mediaType: MediaType.network,
87+
resource: resource,
88+
metas: {},
89+
startTime: startTime,
90+
stopTime: stopTime,
91+
);
6192
if (parse) {
6293
media.parse(timeout);
6394
}
6495
return media;
6596
}
6697

6798
/// Makes [Media] object from direct show.
68-
static Media directShow(
99+
factory Media.directShow(
69100
{String? rawUrl,
70101
Map<String, dynamic>? args,
71102
String? vdev,
@@ -90,7 +121,10 @@ class Media implements MediaSource {
90121
/// This method only works for Flutter.
91122
/// Might result in an exception on Dart CLI.
92123
///
93-
static Media asset(String asset) {
124+
factory Media.asset(
125+
String asset, {
126+
startTime: Duration.zero,
127+
}) {
94128
String? assetPath;
95129
if (Platform.isWindows || Platform.isLinux) {
96130
assetPath = path.join(
@@ -119,12 +153,16 @@ class Media implements MediaSource {
119153
);
120154
}
121155
if (assetPath == null) {
122-
// TODO: Add Android asset path support.
156+
// TODO: Add Android support.
123157
throw UnimplementedError('The platform is not supported');
124158
}
125159
final url = Uri.file(assetPath, windows: Platform.isWindows);
126160
return Media._(
127-
mediaType: MediaType.asset, resource: url.toString(), metas: {});
161+
mediaType: MediaType.asset,
162+
resource: url.toString(),
163+
metas: {},
164+
startTime: startTime,
165+
);
128166
}
129167

130168
/// Parses the [Media] to retrieve [Media.metas].
@@ -181,3 +219,9 @@ class Media implements MediaSource {
181219
@override
182220
String toString() => '[$mediaType]$resource';
183221
}
222+
223+
extension DurationExtension on Duration {
224+
String argument(String value) => this == Duration.zero
225+
? ''
226+
: ':$value=${(inMilliseconds / 1000).toStringAsFixed(6)}';
227+
}

ffi/lib/src/player.dart

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,33 @@ class Player {
154154
PlayerFFI.open(
155155
this.id,
156156
autoStart ? 1 : 0,
157-
<String>[source.mediaType.toString(), source.resource]
158-
.toNativeUtf8Array(),
157+
<String>[
158+
source.mediaType.toString(),
159+
source.resource,
160+
source.startTime.argument('start-time'),
161+
source.stopTime.argument('stop-time'),
162+
].toNativeUtf8Array(),
159163
1);
160164
}
161165
if (source is Playlist) {
162166
List<String> medias = <String>[];
163167
source.medias.forEach((media) {
164-
medias.add(media.mediaType.toString());
165-
medias.add(media.resource);
168+
medias.addAll(
169+
<String>[
170+
media.mediaType.toString(),
171+
media.resource,
172+
media.startTime.argument('start-time'),
173+
media.stopTime.argument('stop-time'),
174+
],
175+
);
166176
});
167-
PlayerFFI.open(this.id, autoStart ? 1 : 0, medias.toNativeUtf8Array(),
168-
source.medias.length);
177+
print(medias);
178+
PlayerFFI.open(
179+
this.id,
180+
autoStart ? 1 : 0,
181+
medias.toNativeUtf8Array(),
182+
source.medias.length,
183+
);
169184
}
170185
}
171186

@@ -206,54 +221,86 @@ class Player {
206221
/// Jumps to [Media] at specific index in the [Playlist] opened.
207222
/// Pass index as parameter.
208223
void jump(int index) {
209-
PlayerFFI.jump(this.id, index);
224+
PlayerFFI.jump(
225+
this.id,
226+
index,
227+
);
210228
}
211229

212230
/// Seeks the [Media] currently playing in the [Player] instance, to the provided [Duration].
213231
void seek(Duration duration) {
214-
PlayerFFI.seek(this.id, duration.inMilliseconds);
232+
PlayerFFI.seek(
233+
this.id,
234+
duration.inMilliseconds,
235+
);
215236
}
216237

217238
/// Sets volume of the [Player] instance.
218239
void setVolume(double volume) {
219-
PlayerFFI.setVolume(this.id, volume);
240+
PlayerFFI.setVolume(
241+
this.id,
242+
volume,
243+
);
220244
}
221245

222246
/// Sets playback rate of the [Media] currently playing in the [Player] instance.
223247
void setRate(double rate) {
224-
PlayerFFI.setRate(this.id, rate);
248+
PlayerFFI.setRate(
249+
this.id,
250+
rate,
251+
);
225252
}
226253

227254
/// Sets user agent for dart_vlc player.
228255
void setUserAgent(String userAgent) {
229-
PlayerFFI.setUserAgent(this.id, userAgent.toNativeUtf8());
256+
PlayerFFI.setUserAgent(
257+
this.id,
258+
userAgent.toNativeUtf8(),
259+
);
230260
}
231261

232262
/// Changes [Playlist] playback mode.
233263
void setPlaylistMode(PlaylistMode playlistMode) {
234-
PlayerFFI.setPlaylistMode(this.id, playlistMode.toString().toNativeUtf8());
264+
PlayerFFI.setPlaylistMode(
265+
this.id,
266+
playlistMode.toString().toNativeUtf8(),
267+
);
235268
}
236269

237270
/// Appends [Media] to the [Playlist] of the [Player] instance.
238271
void add(Media source) {
239-
PlayerFFI.add(this.id, source.mediaType.toString().toNativeUtf8(),
240-
source.resource.toString().toNativeUtf8());
272+
PlayerFFI.add(
273+
this.id,
274+
source.mediaType.toString().toNativeUtf8(),
275+
source.resource.toString().toNativeUtf8(),
276+
);
241277
}
242278

243279
/// Removes [Media] from the [Playlist] at a specific index.
244280
void remove(int index) {
245-
PlayerFFI.remove(this.id, index);
281+
PlayerFFI.remove(
282+
this.id,
283+
index,
284+
);
246285
}
247286

248287
/// Inserts [Media] to the [Playlist] of the [Player] instance at specific index.
249288
void insert(int index, Media source) {
250-
PlayerFFI.insert(this.id, index, source.mediaType.toString().toNativeUtf8(),
251-
source.resource.toString().toNativeUtf8());
289+
PlayerFFI.insert(
290+
this.id,
291+
index,
292+
source.mediaType.toString().toNativeUtf8(),
293+
source.resource.toString().toNativeUtf8(),
294+
);
252295
}
253296

254297
/// Moves [Media] already present in the [Playlist] of the [Player] from [initialIndex] to [finalIndex].
255298
void move(int initialIndex, int finalIndex) {
256-
PlayerFFI.move(this.id, initialIndex, finalIndex);
299+
PlayerFFI.move(
300+
this.id,
301+
initialIndex,
302+
finalIndex,
303+
);
257304
}
258305

259306
/// Sets playback [Device] for the instance of [Player].
@@ -265,7 +312,10 @@ class Player {
265312
///
266313
void setDevice(Device device) {
267314
PlayerFFI.setDevice(
268-
this.id, device.id.toNativeUtf8(), device.name.toNativeUtf8());
315+
this.id,
316+
device.id.toNativeUtf8(),
317+
device.name.toNativeUtf8(),
318+
);
269319
}
270320

271321
/// Sets [Equalizer] for the [Player].
@@ -275,7 +325,12 @@ class Player {
275325

276326
/// Saves snapshot of a video to a desired [File] location.
277327
void takeSnapshot(File file, int width, int height) {
278-
PlayerFFI.takeSnapshot(this.id, file.path.toNativeUtf8(), width, height);
328+
PlayerFFI.takeSnapshot(
329+
this.id,
330+
file.path.toNativeUtf8(),
331+
width,
332+
height,
333+
);
279334
}
280335

281336
/// Destroys the instance of [Player] & closes all [StreamController]s in it.

0 commit comments

Comments
 (0)