LCOV - code coverage report
Current view: top level - src/sources - asset_media_source.dart Coverage Total Hit
Test: lcov.info Lines: 99.2 % 120 119
Test Date: 2025-11-06 04:39:56

            Line data    Source code
       1              : import 'package:cross_file/cross_file.dart';
       2              : import 'package:flutter/services.dart';
       3              : import 'package:media_source/src/media_type.dart';
       4              : import 'package:media_source/src/sources/file_media_source.dart';
       5              : import 'package:media_source/src/sources/media_source.dart';
       6              : import 'package:media_source/src/sources/memory_media_source.dart';
       7              : import 'package:path/path.dart' as p;
       8              : import 'package:file_sized/file_sized.dart';
       9              : import 'package:file_type_plus/file_type_plus.dart';
      10              : 
      11              : /// Abstract base class for Flutter asset-based media sources.
      12              : ///
      13              : /// This class manages media content stored in the Flutter asset bundle. It provides:
      14              : /// - Asset loading with automatic size detection
      15              : /// - Type-specific asset media implementations
      16              : /// - Conversion to file or in-memory representation
      17              : /// - Factory methods for creating instances from asset paths
      18              : ///
      19              : /// Note: Assets are read-only resources bundled with the app. To get the size,
      20              : /// the asset must be loaded, which reads the entire asset into memory.
      21              : ///
      22              : /// Subclasses include:
      23              : /// - [VideoAssetMedia] for video assets
      24              : /// - [AudioAssetMedia] for audio assets
      25              : /// - [ImageAssetMedia] for image assets
      26              : /// - [DocumentAssetMedia] for document assets
      27              : /// - [OtherTypeAssetMedia] for unclassified assets
      28              : abstract class AssetMediaSource<M extends FileType> extends MediaSource<M>
      29              :     implements ToFileConvertableMedia<M>, ToMemoryConvertableMedia<M> {
      30              :   /// The asset path in the Flutter asset bundle (e.g., 'assets/video.mp4').
      31              :   final String assetPath;
      32              : 
      33              :   /// Optional custom asset bundle. If null, [rootBundle] is used.
      34              :   final AssetBundle? bundle;
      35              : 
      36              :   /// Internal constructor for creating asset media sources.
      37              :   ///
      38              :   /// Parameters:
      39              :   /// - [assetPath]: Path to the asset in the bundle
      40              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
      41              :   /// - [metadata]: Type-specific metadata (VideoType, AudioType, etc.)
      42              :   /// - [name]: Optional custom name, defaults to basename of asset path
      43              :   /// - [size]: File size (computed by loading asset if not provided)
      44              :   /// - [mimeType]: Optional MIME type, auto-detected from path if not provided
      45            1 :   AssetMediaSource._({
      46              :     required this.assetPath,
      47              :     this.bundle,
      48              :     required super.metadata,
      49              :     required String? name,
      50              :     required super.size,
      51              :     required String? mimeType,
      52            1 :   }) : super(
      53            1 :           mimeType: mimeType ?? FileUtil.getMimeTypeFromPath(assetPath),
      54            1 :           name: name ?? p.basename(assetPath),
      55              :         );
      56              : 
      57              :   /// Saves this asset to the file system at the specified path.
      58              :   ///
      59              :   /// Loads the asset bytes and writes them to disk as a file.
      60              :   /// Returns a new [FileMediaSource] instance pointing to the saved file.
      61              :   ///
      62              :   /// Parameters:
      63              :   /// - [path]: The destination file path
      64              :   Future<FileMediaSource<M>> saveTo(String path);
      65              : 
      66              :   /// Saves this asset to a folder, preserving the original filename.
      67              :   ///
      68              :   /// Convenience method that combines the folder path with the asset's name.
      69              :   ///
      70              :   /// Parameters:
      71              :   /// - [folderPath]: The directory where the file should be saved
      72              :   ///
      73              :   /// Returns a new [FileMediaSource] instance with the saved file.
      74            4 :   Future<FileMediaSource<M>> saveToFolder(String folderPath) => saveTo(p.join(folderPath, name));
      75              : 
      76              :   /// Includes the asset path and bundle in equality comparisons.
      77            1 :   @override
      78            4 :   List<Object?> get props => [assetPath, bundle, ...super.props];
      79              : 
      80              :   /// Loads an asset from the bundle and returns its bytes.
      81              :   ///
      82              :   /// This is a utility method used by all asset media types to load
      83              :   /// the raw bytes from the asset bundle.
      84              :   ///
      85              :   /// Parameters:
      86              :   /// - [assetPath]: Path to the asset in the bundle
      87              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
      88              :   ///
      89              :   /// Returns the asset data as a [Uint8List].
      90            1 :   static Future<Uint8List> loadAsset(String assetPath, [AssetBundle? bundle]) async {
      91            0 :     final assetBundle = bundle ?? rootBundle;
      92              : 
      93              :     // Load the asset bytes
      94            1 :     final byteData = await assetBundle.load(assetPath);
      95            2 :     final binary = byteData.buffer.asUint8List();
      96              :     return binary;
      97              :   }
      98              : }
      99              : 
     100              : /// Represents video assets from the Flutter asset bundle.
     101              : ///
     102              : /// Stores video metadata including optional duration information.
     103              : /// Supports conversion to file (by saving) and in-memory representation.
     104              : ///
     105              : /// Example:
     106              : /// ```dart
     107              : /// final video = await VideoAssetMedia.load(
     108              : ///   'assets/videos/intro.mp4',
     109              : ///   duration: Duration(seconds: 30),
     110              : /// );
     111              : ///
     112              : /// // Save to file system
     113              : /// final fileMedia = await video.saveTo('/storage/intro.mp4');
     114              : ///
     115              : /// // Or convert to memory
     116              : /// final memoryMedia = await video.convertToMemory();
     117              : /// ```
     118              : class VideoAssetMedia extends AssetMediaSource<VideoType> {
     119              :   /// Internal constructor for creating video asset media.
     120              :   ///
     121              :   /// Parameters:
     122              :   /// - [assetPath]: Path to the video asset
     123              :   /// - [bundle]: Optional custom AssetBundle
     124              :   /// - [name]: Display name
     125              :   /// - [duration]: Optional video duration
     126              :   /// - [size]: Asset size in bytes
     127              :   /// - [mimeType]: MIME type of the video
     128            1 :   VideoAssetMedia._({
     129              :     required super.assetPath,
     130              :     super.bundle,
     131              :     required super.name,
     132              :     required Duration? duration,
     133              :     required super.size,
     134              :     required super.mimeType,
     135            2 :   }) : super._(metadata: VideoType(duration));
     136              : 
     137              :   /// Loads a video asset from the Flutter asset bundle.
     138              :   ///
     139              :   /// This method loads the asset to determine its size. For large assets,
     140              :   /// consider providing the size parameter to avoid loading the asset twice.
     141              :   ///
     142              :   /// Parameters:
     143              :   /// - [assetPath]: Path to the video asset (e.g., 'assets/videos/intro.mp4')
     144              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
     145              :   /// - [name]: Optional custom display name, defaults to asset filename
     146              :   /// - [duration]: Optional video duration
     147              :   /// - [mimeType]: Optional MIME type override, auto-detected from path
     148              :   /// - [size]: Optional pre-computed asset size to avoid loading asset
     149              :   ///
     150              :   /// Returns a [VideoAssetMedia] instance.
     151            1 :   static Future<VideoAssetMedia> load(
     152              :     String assetPath, {
     153              :     AssetBundle? bundle,
     154              :     String? name,
     155              :     Duration? duration,
     156              :     String? mimeType,
     157              :     FileSize? size,
     158              :   }) async {
     159            1 :     return VideoAssetMedia._(
     160              :       assetPath: assetPath,
     161              :       bundle: bundle,
     162              :       name: name,
     163              :       duration: duration,
     164            3 :       size: size ?? (await AssetMediaSource.loadAsset(assetPath, bundle)).lengthInBytes.b,
     165              :       mimeType: mimeType,
     166              :     );
     167              :   }
     168              : 
     169              :   /// Saves this video asset to the file system.
     170              :   ///
     171              :   /// Loads the asset bytes and writes them to the specified path.
     172              :   /// Creates the directory structure if it doesn't exist.
     173              :   ///
     174              :   /// Parameters:
     175              :   /// - [path]: The destination file path
     176              :   ///
     177              :   /// Returns a [VideoFileMedia] instance pointing to the saved file.
     178            1 :   @override
     179              :   Future<VideoFileMedia> saveTo(String path) async {
     180            3 :     final bytes = await AssetMediaSource.loadAsset(assetPath, bundle);
     181            1 :     final file = XFile.fromData(
     182              :       bytes,
     183            1 :       name: name,
     184            1 :       mimeType: mimeType,
     185            1 :       length: bytes.lengthInBytes,
     186              :     );
     187            1 :     final fileMedia = await VideoFileMedia.fromFile(
     188              :       file,
     189            2 :       duration: metadata.duration,
     190            1 :       mimeType: mimeType,
     191            1 :       name: name,
     192            1 :       size: size,
     193              :     );
     194            1 :     return fileMedia.saveTo(path);
     195              :   }
     196              : 
     197              :   /// Converts this video asset to an in-memory representation.
     198              :   ///
     199              :   /// Loads the asset bytes into a [VideoMemoryMedia] instance.
     200              :   /// Useful for uploading, processing, or passing to APIs that expect byte arrays.
     201              :   ///
     202              :   /// Returns a [VideoMemoryMedia] with the asset's data in memory.
     203            1 :   @override
     204              :   Future<MemoryMediaSource<VideoType>> convertToMemory() async {
     205            1 :     return VideoMemoryMedia(
     206            3 :       await AssetMediaSource.loadAsset(assetPath, bundle),
     207            1 :       name: name,
     208            2 :       duration: metadata.duration,
     209            1 :       mimeType: mimeType,
     210              :     );
     211              :   }
     212              : }
     213              : 
     214              : /// Represents audio assets from the Flutter asset bundle.
     215              : ///
     216              : /// Stores audio metadata including optional duration information.
     217              : /// Supports conversion to file (by saving) and in-memory representation.
     218              : ///
     219              : /// Example:
     220              : /// ```dart
     221              : /// final audio = await AudioAssetMedia.load(
     222              : ///   'assets/audio/song.mp3',
     223              : ///   duration: Duration(minutes: 3, seconds: 45),
     224              : /// );
     225              : /// ```
     226              : class AudioAssetMedia extends AssetMediaSource<AudioType> {
     227              :   /// Internal constructor for creating audio asset media.
     228              :   ///
     229              :   /// Parameters:
     230              :   /// - [assetPath]: Path to the audio asset
     231              :   /// - [bundle]: Optional custom AssetBundle
     232              :   /// - [name]: Display name
     233              :   /// - [duration]: Optional audio duration
     234              :   /// - [size]: Asset size in bytes
     235              :   /// - [mimeType]: MIME type of the audio
     236            1 :   AudioAssetMedia._({
     237              :     required super.assetPath,
     238              :     super.bundle,
     239              :     required super.name,
     240              :     required Duration? duration,
     241              :     required super.size,
     242              :     required super.mimeType,
     243            2 :   }) : super._(metadata: AudioType(duration));
     244              : 
     245              :   /// Loads an audio asset from the Flutter asset bundle.
     246              :   ///
     247              :   /// This method loads the asset to determine its size. For large assets,
     248              :   /// consider providing the size parameter to avoid loading the asset twice.
     249              :   ///
     250              :   /// Parameters:
     251              :   /// - [assetPath]: Path to the audio asset (e.g., 'assets/audio/song.mp3')
     252              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
     253              :   /// - [name]: Optional custom display name, defaults to asset filename
     254              :   /// - [duration]: Optional audio duration
     255              :   /// - [mimeType]: Optional MIME type override, auto-detected from path
     256              :   /// - [size]: Optional pre-computed asset size to avoid loading asset
     257              :   ///
     258              :   /// Returns an [AudioAssetMedia] instance.
     259            1 :   static Future<AudioAssetMedia> load(
     260              :     String assetPath, {
     261              :     AssetBundle? bundle,
     262              :     String? name,
     263              :     Duration? duration,
     264              :     String? mimeType,
     265              :     FileSize? size,
     266              :   }) async {
     267            1 :     return AudioAssetMedia._(
     268              :       assetPath: assetPath,
     269              :       bundle: bundle,
     270              :       name: name,
     271              :       duration: duration,
     272            3 :       size: size ?? (await AssetMediaSource.loadAsset(assetPath, bundle)).lengthInBytes.b,
     273              :       mimeType: mimeType,
     274              :     );
     275              :   }
     276              : 
     277              :   /// Saves this audio asset to the file system.
     278              :   ///
     279              :   /// Loads the asset bytes and writes them to the specified path.
     280              :   /// Creates the directory structure if it doesn't exist.
     281              :   ///
     282              :   /// Parameters:
     283              :   /// - [path]: The destination file path
     284              :   ///
     285              :   /// Returns an [AudioFileMedia] instance pointing to the saved file.
     286            1 :   @override
     287              :   Future<AudioFileMedia> saveTo(String path) async {
     288            3 :     final bytes = await AssetMediaSource.loadAsset(assetPath, bundle);
     289            1 :     final file = XFile.fromData(
     290              :       bytes,
     291            1 :       name: name,
     292            1 :       mimeType: mimeType,
     293            1 :       length: bytes.lengthInBytes,
     294              :     );
     295            1 :     final fileMedia = await AudioFileMedia.fromFile(
     296              :       file,
     297            2 :       duration: metadata.duration,
     298            1 :       mimeType: mimeType,
     299            1 :       name: name,
     300            1 :       size: size,
     301              :     );
     302            1 :     return fileMedia.saveTo(path);
     303              :   }
     304              : 
     305              :   /// Converts this audio asset to an in-memory representation.
     306              :   ///
     307              :   /// Loads the asset bytes into an [AudioMemoryMedia] instance.
     308              :   /// Useful for uploading, processing, or passing to APIs that expect byte arrays.
     309              :   ///
     310              :   /// Returns an [AudioMemoryMedia] with the asset's data in memory.
     311            1 :   @override
     312              :   Future<MemoryMediaSource<AudioType>> convertToMemory() async {
     313            1 :     return AudioMemoryMedia(
     314            3 :       await AssetMediaSource.loadAsset(assetPath, bundle),
     315            1 :       name: name,
     316            2 :       duration: metadata.duration,
     317            1 :       mimeType: mimeType,
     318              :     );
     319              :   }
     320              : }
     321              : 
     322              : /// Represents image assets from the Flutter asset bundle.
     323              : ///
     324              : /// Stores image metadata and supports conversion to file (by saving)
     325              : /// and in-memory representation.
     326              : ///
     327              : /// Example:
     328              : /// ```dart
     329              : /// final image = await ImageAssetMedia.load('assets/images/logo.png');
     330              : ///
     331              : /// // Save to cache directory
     332              : /// final cachedFile = await image.saveTo('/cache/logo.png');
     333              : /// ```
     334              : class ImageAssetMedia extends AssetMediaSource<ImageType> {
     335              :   /// Internal constructor for creating image asset media.
     336              :   ///
     337              :   /// Parameters:
     338              :   /// - [assetPath]: Path to the image asset
     339              :   /// - [bundle]: Optional custom AssetBundle
     340              :   /// - [name]: Display name
     341              :   /// - [size]: Asset size in bytes
     342              :   /// - [mimeType]: MIME type of the image
     343            1 :   ImageAssetMedia._({
     344              :     required super.assetPath,
     345              :     super.bundle,
     346              :     required super.name,
     347              :     required super.size,
     348              :     required super.mimeType,
     349            2 :   }) : super._(metadata: ImageType());
     350              : 
     351              :   /// Loads an image asset from the Flutter asset bundle.
     352              :   ///
     353              :   /// This method loads the asset to determine its size. For large assets,
     354              :   /// consider providing the size parameter to avoid loading the asset twice.
     355              :   ///
     356              :   /// Parameters:
     357              :   /// - [assetPath]: Path to the image asset (e.g., 'assets/images/logo.png')
     358              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
     359              :   /// - [name]: Optional custom display name, defaults to asset filename
     360              :   /// - [mimeType]: Optional MIME type override, auto-detected from path
     361              :   /// - [size]: Optional pre-computed asset size to avoid loading asset
     362              :   ///
     363              :   /// Returns an [ImageAssetMedia] instance.
     364            1 :   static Future<ImageAssetMedia> load(
     365              :     String assetPath, {
     366              :     AssetBundle? bundle,
     367              :     String? name,
     368              :     String? mimeType,
     369              :     FileSize? size,
     370              :   }) async {
     371            1 :     return ImageAssetMedia._(
     372              :       assetPath: assetPath,
     373              :       bundle: bundle,
     374              :       name: name,
     375            3 :       size: size ?? (await AssetMediaSource.loadAsset(assetPath, bundle)).lengthInBytes.b,
     376              :       mimeType: mimeType,
     377              :     );
     378              :   }
     379              : 
     380              :   /// Saves this image asset to the file system.
     381              :   ///
     382              :   /// Loads the asset bytes and writes them to the specified path.
     383              :   /// Creates the directory structure if it doesn't exist.
     384              :   ///
     385              :   /// Parameters:
     386              :   /// - [path]: The destination file path
     387              :   ///
     388              :   /// Returns an [ImageFileMedia] instance pointing to the saved file.
     389            1 :   @override
     390              :   Future<ImageFileMedia> saveTo(String path) async {
     391            3 :     final bytes = await AssetMediaSource.loadAsset(assetPath, bundle);
     392            1 :     final file = XFile.fromData(
     393              :       bytes,
     394            1 :       name: name,
     395            1 :       mimeType: mimeType,
     396            1 :       length: bytes.lengthInBytes,
     397              :     );
     398            1 :     final fileMedia = await ImageFileMedia.fromFile(
     399              :       file,
     400            1 :       mimeType: mimeType,
     401            1 :       name: name,
     402            1 :       size: size,
     403              :     );
     404            1 :     return fileMedia.saveTo(path);
     405              :   }
     406              : 
     407              :   /// Converts this image asset to an in-memory representation.
     408              :   ///
     409              :   /// Loads the asset bytes into an [ImageMemoryMedia] instance.
     410              :   /// Useful for image processing, uploading, or displaying in widgets.
     411              :   ///
     412              :   /// Returns an [ImageMemoryMedia] with the asset's data in memory.
     413            1 :   @override
     414              :   Future<MemoryMediaSource<ImageType>> convertToMemory() async {
     415            1 :     return ImageMemoryMedia(
     416            3 :       await AssetMediaSource.loadAsset(assetPath, bundle),
     417            1 :       name: name,
     418            1 :       mimeType: mimeType,
     419              :     );
     420              :   }
     421              : }
     422              : 
     423              : /// Represents document assets from the Flutter asset bundle.
     424              : ///
     425              : /// Supports documents like PDF, DOCX, XLSX, etc. bundled with the app.
     426              : /// Provides conversion to file (by saving) and in-memory representation.
     427              : ///
     428              : /// Example:
     429              : /// ```dart
     430              : /// final pdf = await DocumentAssetMedia.load('assets/docs/manual.pdf');
     431              : /// final fileMedia = await pdf.saveTo('/downloads/manual.pdf');
     432              : /// ```
     433              : class DocumentAssetMedia extends AssetMediaSource<DocumentType> {
     434              :   /// Internal constructor for creating document asset media.
     435              :   ///
     436              :   /// Parameters:
     437              :   /// - [assetPath]: Path to the document asset
     438              :   /// - [bundle]: Optional custom AssetBundle
     439              :   /// - [name]: Display name
     440              :   /// - [size]: Asset size in bytes
     441              :   /// - [mimeType]: MIME type of the document
     442            1 :   DocumentAssetMedia._({
     443              :     required super.assetPath,
     444              :     super.bundle,
     445              :     required super.name,
     446              :     required super.size,
     447              :     required super.mimeType,
     448            2 :   }) : super._(metadata: DocumentType());
     449              : 
     450              :   /// Loads a document asset from the Flutter asset bundle.
     451              :   ///
     452              :   /// This method loads the asset to determine its size. For large assets,
     453              :   /// consider providing the size parameter to avoid loading the asset twice.
     454              :   ///
     455              :   /// Parameters:
     456              :   /// - [assetPath]: Path to the document asset (e.g., 'assets/docs/manual.pdf')
     457              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
     458              :   /// - [name]: Optional custom display name, defaults to asset filename
     459              :   /// - [mimeType]: Optional MIME type override, auto-detected from path
     460              :   /// - [size]: Optional pre-computed asset size to avoid loading asset
     461              :   ///
     462              :   /// Returns a [DocumentAssetMedia] instance.
     463            1 :   static Future<DocumentAssetMedia> load(
     464              :     String assetPath, {
     465              :     AssetBundle? bundle,
     466              :     String? name,
     467              :     String? mimeType,
     468              :     FileSize? size,
     469              :   }) async {
     470            1 :     return DocumentAssetMedia._(
     471              :       assetPath: assetPath,
     472              :       bundle: bundle,
     473              :       name: name,
     474            3 :       size: size ?? (await AssetMediaSource.loadAsset(assetPath, bundle)).lengthInBytes.b,
     475              :       mimeType: mimeType,
     476              :     );
     477              :   }
     478              : 
     479              :   /// Saves this document asset to the file system.
     480              :   ///
     481              :   /// Loads the asset bytes and writes them to the specified path.
     482              :   /// Creates the directory structure if it doesn't exist.
     483              :   ///
     484              :   /// Parameters:
     485              :   /// - [path]: The destination file path
     486              :   ///
     487              :   /// Returns a [DocumentFileMedia] instance pointing to the saved file.
     488            1 :   @override
     489              :   Future<DocumentFileMedia> saveTo(String path) async {
     490            3 :     final bytes = await AssetMediaSource.loadAsset(assetPath, bundle);
     491            1 :     final file = XFile.fromData(
     492              :       bytes,
     493            1 :       name: name,
     494            1 :       mimeType: mimeType,
     495            1 :       length: bytes.lengthInBytes,
     496              :     );
     497            1 :     final fileMedia = await DocumentFileMedia.fromFile(
     498              :       file,
     499            1 :       mimeType: mimeType,
     500            1 :       name: name,
     501            1 :       size: size,
     502              :     );
     503            1 :     return fileMedia.saveTo(path);
     504              :   }
     505              : 
     506              :   /// Converts this document asset to an in-memory representation.
     507              :   ///
     508              :   /// Loads the asset bytes into a [DocumentMemoryMedia] instance.
     509              :   /// Useful for sharing, uploading, or processing documents.
     510              :   ///
     511              :   /// Returns a [DocumentMemoryMedia] with the asset's data in memory.
     512            1 :   @override
     513              :   Future<MemoryMediaSource<DocumentType>> convertToMemory() async {
     514            1 :     return DocumentMemoryMedia(
     515            3 :       await AssetMediaSource.loadAsset(assetPath, bundle),
     516            1 :       name: name,
     517            1 :       mimeType: mimeType,
     518              :     );
     519              :   }
     520              : }
     521              : 
     522              : /// Represents assets of unclassified or unknown types.
     523              : ///
     524              : /// Used for asset files that don't fit into the standard categories
     525              : /// (video, audio, image, document). Provides the same operations as
     526              : /// other asset media types.
     527              : ///
     528              : /// Example:
     529              : /// ```dart
     530              : /// final data = await OtherTypeAssetMedia.load('assets/data/config.json');
     531              : /// ```
     532              : class OtherTypeAssetMedia extends AssetMediaSource<OtherType> {
     533              :   /// Internal constructor for creating other type asset media.
     534              :   ///
     535              :   /// Parameters:
     536              :   /// - [assetPath]: Path to the asset
     537              :   /// - [bundle]: Optional custom AssetBundle
     538              :   /// - [name]: Display name
     539              :   /// - [size]: Asset size in bytes
     540              :   /// - [mimeType]: MIME type of the asset
     541            1 :   @override
     542              :   OtherTypeAssetMedia._({
     543              :     required super.assetPath,
     544              :     super.bundle,
     545              :     required super.name,
     546              :     required super.size,
     547              :     required super.mimeType,
     548            2 :   }) : super._(metadata: OtherType());
     549              : 
     550              :   /// Loads an asset of unknown type from the Flutter asset bundle.
     551              :   ///
     552              :   /// This method loads the asset to determine its size. For large assets,
     553              :   /// consider providing the size parameter to avoid loading the asset twice.
     554              :   ///
     555              :   /// Parameters:
     556              :   /// - [assetPath]: Path to the asset (e.g., 'assets/data/config.json')
     557              :   /// - [bundle]: Optional custom AssetBundle, defaults to rootBundle
     558              :   /// - [name]: Optional custom display name, defaults to asset filename
     559              :   /// - [mimeType]: Optional MIME type override, auto-detected from path
     560              :   /// - [size]: Optional pre-computed asset size to avoid loading asset
     561              :   ///
     562              :   /// Returns an [OtherTypeAssetMedia] instance.
     563            1 :   static Future<OtherTypeAssetMedia> load(
     564              :     String assetPath, {
     565              :     AssetBundle? bundle,
     566              :     String? name,
     567              :     String? mimeType,
     568              :     FileSize? size,
     569              :   }) async {
     570            1 :     return OtherTypeAssetMedia._(
     571              :       assetPath: assetPath,
     572              :       bundle: bundle,
     573              :       name: name,
     574            3 :       size: size ?? (await AssetMediaSource.loadAsset(assetPath, bundle)).lengthInBytes.b,
     575              :       mimeType: mimeType,
     576              :     );
     577              :   }
     578              : 
     579              :   /// Saves this asset to the file system.
     580              :   ///
     581              :   /// Loads the asset bytes and writes them to the specified path.
     582              :   /// Creates the directory structure if it doesn't exist.
     583              :   ///
     584              :   /// Parameters:
     585              :   /// - [path]: The destination file path
     586              :   ///
     587              :   /// Returns an [OtherTypeFileMedia] instance pointing to the saved file.
     588            1 :   @override
     589              :   Future<OtherTypeFileMedia> saveTo(String path) async {
     590            3 :     final bytes = await AssetMediaSource.loadAsset(assetPath, bundle);
     591            1 :     final file = XFile.fromData(
     592              :       bytes,
     593            1 :       name: name,
     594            1 :       mimeType: mimeType,
     595            1 :       length: bytes.lengthInBytes,
     596              :     );
     597            1 :     final fileMedia = await OtherTypeFileMedia.fromFile(
     598              :       file,
     599            1 :       mimeType: mimeType,
     600            1 :       name: name,
     601            1 :       size: size,
     602              :     );
     603            1 :     return fileMedia.saveTo(path);
     604              :   }
     605              : 
     606              :   /// Converts this asset to an in-memory representation.
     607              :   ///
     608              :   /// Loads the asset bytes into an [OtherTypeMemoryMedia] instance.
     609              :   /// Useful for processing or handling custom file types.
     610              :   ///
     611              :   /// Returns an [OtherTypeMemoryMedia] with the asset's data in memory.
     612            1 :   @override
     613              :   Future<MemoryMediaSource<OtherType>> convertToMemory() async {
     614            1 :     return OtherTypeMemoryMedia(
     615            3 :       await AssetMediaSource.loadAsset(assetPath, bundle),
     616            1 :       name: name,
     617            1 :       mimeType: mimeType,
     618              :     );
     619              :   }
     620              : }
        

Generated by: LCOV version 2.3.2-1