Line data Source code
1 : import 'package:equatable/equatable.dart';
2 : import 'package:file_type_plus/file_type_plus.dart';
3 : import 'package:media_source/src/sources/file_media_source.dart';
4 : import 'package:media_source/src/sources/memory_media_source.dart';
5 : import 'package:media_source/src/sources/network_media_source.dart';
6 : import 'package:file_sized/file_sized.dart';
7 : import 'package:path/path.dart' as p;
8 :
9 : /// Abstract base class for all media sources.
10 : ///
11 : /// This class defines the common interface for different media source types
12 : /// (file, memory, network). It provides:
13 : /// - Common properties (name, size, MIME type, media type metadata)
14 : /// - Extension extraction from file names
15 : /// - Pattern matching via [fold] for type-safe handling
16 : /// - Type checking with [isAnyType]
17 : ///
18 : /// Extensibility: You can create your own source types by extending
19 : /// `MediaSource<M>` and, when appropriate, implementing the conversion
20 : /// mixins [`ToMemoryConvertableMedia`], [`ToFileConvertableMedia`]. This
21 : /// allows you to model custom storage backends while still participating
22 : /// in the shared fold pattern.
23 : ///
24 : /// Generic parameter [M] represents the specific media type metadata
25 : /// (e.g., [VideoType], [AudioType], etc.)
26 : abstract class MediaSource<M extends FileType> extends Equatable {
27 : /// The MIME type of the media, if available.
28 : final String? mimeType;
29 :
30 : /// The name or identifier of the media.
31 : final String name;
32 :
33 : /// The size of the media, if known.
34 : final FileSize? size;
35 :
36 : /// Metadata about the media type (e.g., VideoType, AudioType).
37 : final M metadata;
38 :
39 : /// Extracts the file extension from the name.
40 : ///
41 : /// Returns the substring after the last dot, or the entire name if no dot exists.
42 0 : String get extension => p.extension(name);
43 :
44 : /// Creates a [MediaSource] with the specified properties.
45 1 : const MediaSource({
46 : required this.metadata,
47 : required this.mimeType,
48 : required String? name,
49 : required this.size,
50 : }) : name = name ?? '';
51 :
52 1 : @override
53 5 : List<Object?> get props => [name, mimeType, size, metadata];
54 :
55 : /// Checks if this media source's runtime type is in the given list.
56 : ///
57 : /// Useful for runtime type checking against multiple types.
58 0 : bool isAnyType(List<Type> list) => list.contains(runtimeType);
59 :
60 : /// Performs pattern matching on media sources using a fold-like pattern.
61 : ///
62 : /// This method allows type-safe handling of different media source types:
63 : /// - [file]: Called if this is a [FileMediaSource]
64 : /// - [memory]: Called if this is a [MemoryMediaSource]
65 : /// - [network]: Called if this is a [NetworkMediaSource]
66 : /// - [orElse]: Called if no matching callback is provided
67 : ///
68 : /// Returns: The result of the matching callback or [orElse]
69 0 : T fold<T>(
70 : {T Function(FileMediaSource<M> fileMedia)? file,
71 : T Function(MemoryMediaSource<M> memoryMedia)? memory,
72 : T Function(NetworkMediaSource<M> networkMedia)? network,
73 : required T Function() orElse}) {
74 0 : if (this is FileMediaSource<M> && file != null) {
75 0 : return file(this as FileMediaSource<M>);
76 0 : } else if (this is MemoryMediaSource<M> && memory != null) {
77 0 : return memory(this as MemoryMediaSource<M>);
78 0 : } else if (this is NetworkMediaSource<M> && network != null) {
79 0 : return network(this as NetworkMediaSource<M>);
80 : }
81 0 : return orElse();
82 : }
83 : }
84 :
85 : /// Mixin for media sources that can be converted to [MemoryMediaSource].
86 : ///
87 : /// Implement this mixin on media sources that support converting their content
88 : /// to an in-memory byte representation.
89 : abstract class ToMemoryConvertableMedia<M extends FileType> {
90 : /// Converts this media source to a [MemoryMediaSource].
91 : ///
92 : /// This is useful for caching, processing, or uploading media data.
93 : /// Returns a new [MemoryMediaSource] containing the same media data.
94 : Future<MemoryMediaSource<M>> convertToMemory();
95 : }
96 :
97 : /// Mixin for media sources that can be saved as files.
98 : ///
99 : /// Implement this mixin on media sources that support saving their content
100 : /// to the file system.
101 : abstract class ToFileConvertableMedia<M extends FileType> {
102 : /// Saves this media to a file at the specified path.
103 : ///
104 : /// Returns a new [FileMediaSource] pointing to the saved file.
105 : Future<FileMediaSource<M>> saveTo(String path);
106 : }
|