Skip to content

Commit 246a35e

Browse files
authored
Implement media and playlist equality operators (#125)
* Implement media and playlist equality operators * Override toString for media and playlist
1 parent 86a1589 commit 246a35e

File tree

8 files changed

+484
-53
lines changed

8 files changed

+484
-53
lines changed

ffi/lib/src/internal/ffi.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'dart:io';
33
import 'dart:isolate';
44
import 'dart:typed_data';
55
import 'package:ffi/ffi.dart';
6-
import 'package:dart_vlc_ffi/src/enums/mediaType.dart';
76
import 'package:dart_vlc_ffi/src/internal/dynamiclibrary.dart';
87
import 'package:dart_vlc_ffi/src/internal/typedefs/player.dart';
98
import 'package:dart_vlc_ffi/src/internal/typedefs/media.dart';
@@ -240,10 +239,7 @@ final ReceivePort receiver = new ReceivePort()
240239
}
241240
case 'MediaType.directShow':
242241
{
243-
Media media = Media();
244-
media.mediaType = MediaType.directShow;
245-
media.resource = event[index + 1];
246-
medias.add(media);
242+
medias.add(Media.directShow(rawUrl: event[index + 1]));
247243
break;
248244
}
249245
}

ffi/lib/src/internal/utils.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
bool listEquals<T>(List<T>? a, List<T>? b) {
2+
if (a == null) return b == null;
3+
if (b == null || a.length != b.length) return false;
4+
if (identical(a, b)) return true;
5+
for (int index = 0; index < a.length; index += 1) {
6+
if (a[index] != b[index]) return false;
7+
}
8+
return true;
9+
}

ffi/lib/src/mediaSource/media.dart

Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import 'package:dart_vlc_ffi/src/mediaSource/mediaSource.dart';
77
import 'package:dart_vlc_ffi/src/enums/mediaSourceType.dart';
88
import 'package:dart_vlc_ffi/src/enums/mediaType.dart';
99

10-
/// Internally used class to avoid direct creation of the object of a [Media] class.
11-
class _Media extends Media {}
12-
1310
/// A media object to open inside a [Player].
1411
///
1512
/// Pass `true` to [parse] for retrieving the metadata of the [Media].
@@ -29,20 +26,22 @@ class _Media extends Media {}
2926
/// ```
3027
///
3128
///
32-
class Media extends MediaSource {
33-
MediaSourceType mediaSourceType = MediaSourceType.media;
34-
Map<String, String> metas = {};
35-
late MediaType mediaType;
36-
late String resource;
29+
class Media implements MediaSource {
30+
MediaSourceType get mediaSourceType => MediaSourceType.media;
31+
final MediaType mediaType;
32+
final String resource;
33+
final Map<String, String> metas;
34+
35+
const Media._(
36+
{required this.mediaType, required this.resource, this.metas = const {}});
3737

3838
/// Makes [Media] object from a [File].
3939
static Media file(File file,
4040
{bool parse: false,
4141
Map<String, dynamic>? extras,
4242
Duration timeout: const Duration(seconds: 10)}) {
43-
Media media = new _Media();
44-
media.mediaType = MediaType.file;
45-
media.resource = file.path;
43+
final media = Media._(mediaType: MediaType.file, resource: file.path);
44+
4645
if (parse) {
4746
media.parse(timeout);
4847
}
@@ -54,12 +53,10 @@ class Media extends MediaSource {
5453
{bool parse: false,
5554
Map<String, dynamic>? extras,
5655
Duration timeout: const Duration(seconds: 10)}) {
57-
Media media = new _Media();
58-
media.mediaType = MediaType.network;
59-
if (url is Uri)
60-
media.resource = url.toString();
61-
else
62-
media.resource = url;
56+
final resource = (url is Uri) ? url.toString() : url;
57+
final Media media =
58+
Media._(mediaType: MediaType.network, resource: resource);
59+
6360
if (parse) {
6461
media.parse(timeout);
6562
}
@@ -68,12 +65,20 @@ class Media extends MediaSource {
6865

6966
/// Makes [Media] object from direct show.
7067
static Media directShow(
71-
{String vdev = '', String adev = '', required int liveCaching}) {
72-
Media media = new _Media();
73-
media.mediaType = MediaType.directShow;
74-
media.resource =
75-
'dshow:// :dshow-vdev=$vdev :dshow-adev=$adev :live-caching=$liveCaching';
76-
return media;
68+
{String? rawUrl,
69+
Map<String, dynamic>? args,
70+
String? vdev,
71+
String? adev,
72+
int? liveCaching}) {
73+
final resourceUrl = rawUrl ??
74+
_buildDirectShowUrl(args ??
75+
{
76+
'dshow-vdev': vdev,
77+
'dshow-adev': adev,
78+
'live-caching': liveCaching
79+
});
80+
81+
return Media._(mediaType: MediaType.directShow, resource: resourceUrl);
7782
}
7883

7984
/// Makes [Media] object from assets.
@@ -84,26 +89,15 @@ class Media extends MediaSource {
8489
/// Might result in an exception on Dart CLI.
8590
///
8691
static Media asset(String asset) {
87-
Media media = new _Media();
88-
media.mediaType = MediaType.asset;
89-
late String directory;
90-
if (Platform.isWindows) {
91-
directory = Platform.resolvedExecutable
92-
.split('\\')
93-
.sublist(0, Platform.resolvedExecutable.split('\\').length - 1)
94-
.join('\\');
95-
media.resource =
96-
path.join('file:///' + directory, 'data', 'flutter_assets', asset);
97-
}
98-
if (Platform.isLinux) {
99-
directory = Platform.resolvedExecutable
100-
.split('/')
101-
.sublist(0, Platform.resolvedExecutable.split('/').length - 1)
102-
.join('/');
103-
media.resource =
104-
path.join('file://' + directory, 'data', 'flutter_assets', asset);
92+
if (Platform.isWindows || Platform.isLinux) {
93+
final assetPath = path.join(path.dirname(Platform.resolvedExecutable),
94+
'data', 'flutter_assets', asset);
95+
final url = Uri.file(assetPath, windows: Platform.isWindows);
96+
return Media._(mediaType: MediaType.asset, resource: url.toString());
10597
}
106-
return media;
98+
99+
// TODO: Add macOS asset path support.
100+
throw UnimplementedError('The platform is not supported');
107101
}
108102

109103
/// Parses the [Media] to retrieve [Media.metas].
@@ -139,4 +133,24 @@ class Media extends MediaSource {
139133
this.metas['trackTotal'] = metas.elementAt(22).value.toDartString();
140134
this.metas['url'] = metas.elementAt(23).value.toDartString();
141135
}
136+
137+
static String _buildDirectShowUrl(Map<String, dynamic> args) {
138+
return args.entries.fold(
139+
'dshow://',
140+
(prev, pair) =>
141+
prev +
142+
(pair.value != null
143+
? ' :${pair.key.toLowerCase()}=${pair.value}'
144+
: ''));
145+
}
146+
147+
int get hashCode => mediaType.hashCode ^ resource.hashCode;
148+
149+
bool operator ==(Object other) =>
150+
other is Media &&
151+
other.mediaType == mediaType &&
152+
other.resource == resource;
153+
154+
@override
155+
String toString() => '[$mediaType]$resource';
142156
}

ffi/lib/src/mediaSource/mediaSource.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import 'package:dart_vlc_ffi/src/enums/mediaSourceType.dart';
22

33
/// Parent abstract class of [Media] and [Playlist].
44
abstract class MediaSource {
5-
late MediaSourceType mediaSourceType;
5+
MediaSourceType get mediaSourceType;
66
}

ffi/lib/src/mediaSource/playlist.dart

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:dart_vlc_ffi/src/enums/playlistMode.dart';
2+
import 'package:dart_vlc_ffi/src/internal/utils.dart';
23
import 'package:dart_vlc_ffi/src/mediaSource/media.dart';
34
import 'package:dart_vlc_ffi/src/mediaSource/mediaSource.dart';
45
import 'package:dart_vlc_ffi/src/enums/mediaSourceType.dart';
@@ -23,10 +24,23 @@ import 'package:dart_vlc_ffi/src/enums/mediaSourceType.dart';
2324
/// );
2425
/// ```
2526
///
26-
class Playlist extends MediaSource {
27+
class Playlist implements MediaSource {
28+
MediaSourceType get mediaSourceType => MediaSourceType.playlist;
29+
2730
/// [List] of [Media] present in the playlist.
28-
List<Media> medias;
29-
MediaSourceType mediaSourceType = MediaSourceType.playlist;
30-
PlaylistMode playlistMode;
31-
Playlist({required this.medias, this.playlistMode = PlaylistMode.single});
31+
final List<Media> medias;
32+
final PlaylistMode playlistMode;
33+
34+
const Playlist(
35+
{required this.medias, this.playlistMode = PlaylistMode.single});
36+
37+
int get hashCode => medias.hashCode ^ playlistMode.hashCode;
38+
39+
bool operator ==(Object other) =>
40+
other is Playlist &&
41+
other.playlistMode == playlistMode &&
42+
listEquals(other.medias, medias);
43+
44+
@override
45+
String toString() => 'Playlist[${medias.length}]';
3246
}

0 commit comments

Comments
 (0)