Flutter ISO基础媒体处理插件iso_base_media的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter ISO基础媒体处理插件iso_base_media的使用

iso_base_media

pub package Build Status

一个用于解析ISO基础媒体文件格式(如MP4、HEIC、AVIF、JXL文件)的dart包。

使用

提取HEIC文件中的hvcC盒子

Future<void> main() async {
  // 打开HEIC文件
  final fileBox = await ISOBox.openFileBoxFromPath('./test/test_files/a.heic');
  
  // 获取`ipco`盒子
  final ipcoBox = await fileBox.getChildByTypePath(['meta', 'iprp', 'ipco']);
  if (ipcoBox == null) {
    print('ipco box not found');
    return;
  }
  
  // 获取`hvcC`盒子
  final hvcCBoxList = await ipcoBox.getDirectChildrenByTypes({'hvcC'});
  if (hvcCBoxList.isEmpty) {
    print('hvcC box not found');
    return;
  }
  
  // 打印`hvcC`盒子的信息
  for (final hvcCBox in hvcCBoxList) {
    print('hvcC: start: ${hvcCBox.headerOffset}, size: ${hvcCBox.boxSize}');
  }
  /**
    * 输出:
    hvcC: start: 253, size: 108
    hvcC: start: 381, size: 107
   */
}

确定哪些盒子是容器或完整盒子

该包自带了一套默认规则来确定盒子是否为容器或完整盒子。你可以通过isContainerCallbackisFullBoxCallback提供自己的规则。

await fileBox.getChildByTypePath(['meta', 'iprp', 'ipco'], isContainerCallback: (type) {
  // 只有`meta`盒子被认为是容器。
  if (type == 'meta') {
    return true;
  }
  return false;
}, isFullBoxCallback: (type) {
  // 只有`mvhd`盒子被认为是完整盒子。
  if (type == 'mvhd') {
    return true;
  }
  return false;
});

扩展方法

基础盒子类有一些内置的扩展方法:

extension ISOBoxExtension on ISOBoxBase {
  /// 返回直接子盒子列表。
  /// [isContainerCallback] 是一个回调函数,用于确定一个盒子是否为容器。
  /// [isFullBoxCallback] 是一个回调函数,用于确定一个盒子是否为完整盒子。
  /// [filter] 是一个回调函数,用于过滤盒子。
  Future<List<ISOBox>> getDirectChildren({
    bool Function(String type)? isContainerCallback,
    bool Function(String type)? isFullBoxCallback,
    bool Function(ISOBox box)? filter,
  });

  /// 返回直接子盒子列表,通过给定的异步过滤器。
  /// [isContainerCallback] 是一个回调函数,用于确定一个盒子是否为容器。
  /// [isFullBoxCallback] 是一个回调函数,用于确定一个盒子是否为完整盒子。
  Future<List<ISOBox>> getDirectChildrenByAsyncFilter(
    Future<bool> Function(ISOBox box) filter, {
    bool Function(String type)? isContainerCallback,
    bool Function(String type)? isFullBoxCallback,
  });

  /// 返回指定类型的直接子盒子。
  /// 空的[types]集合将返回第一个子盒子。
  /// [isContainerCallback] 是一个回调函数,用于确定一个盒子是否为容器。
  /// [isFullBoxCallback] 是一个回调函数,用于确定一个盒子是否为完整盒子。
  Future<ISOBox?> getDirectChildByTypes(
    Set<String> types, {
    bool Function(String type)? isContainerCallback,
    bool Function(String type)? isFullBoxCallback,
  });

  /// 返回指定类型的直接子盒子列表。
  /// 空的[types]集合将返回所有子盒子。
  /// [isContainerCallback] 是一个回调函数,用于确定一个盒子是否为容器。
  /// [isFullBoxCallback] 是一个回调函数,用于确定一个盒子是否为完整盒子。
  Future<List<ISOBox>> getDirectChildrenByTypes(
    Set<String> types, {
    bool Function(String type)? isContainerCallback,
    bool Function(String type)? isFullBoxCallback,
  });

  /// 返回给定类型路径的子盒子。
  /// [isContainerCallback] 是一个回调函数,用于确定一个盒子是否为容器。
  /// [isFullBoxCallback] 是一个回调函数,用于确定一个盒子是否为完整盒子。
  Future<ISOBox?> getChildByTypePath(
    List<String> path, {
    bool Function(String type)? isContainerCallback,
    bool Function(String type)? isFullBoxCallback,
  });
}

/// 将盒子列表写入字节。
Future<Uint8List> isoBoxesToBytes(List<ISOBox> boxes);

完整示例Demo

以下是一个完整的示例代码,展示了如何使用iso_base_media插件来提取HEIC文件中的hvcC盒子信息。

// ignore_for_file: avoid_print

import 'package:iso_base_media/iso_base_media.dart';

Future<void> main() async {
  // 打开HEIC文件
  final fileBox = await ISOBox.openFileBoxFromPath('./test/test_files/a.heic');
  
  // 获取`ipco`盒子
  final ipcoBox = await fileBox.getChildByTypePath(['meta', 'iprp', 'ipco']);
  if (ipcoBox == null) {
    print('ipco box not found');
    return;
  }
  
  // 获取`hvcC`盒子
  final hvcCBoxList = await ipcoBox.getDirectChildrenByTypes({'hvcC'});
  if (hvcCBoxList.isEmpty) {
    print('hvcC box not found');
    return;
  }
  
  // 打印`hvcC`盒子的信息
  for (final hvcCBox in hvcCBoxList) {
    print('hvcC: start: ${hvcCBox.headerOffset}, size: ${hvcCBox.boxSize}');
  }
  /**
    * 输出:
    hvcC: start: 253, size: 108
    hvcC: start: 381, size: 107
   */
}

更多关于Flutter ISO基础媒体处理插件iso_base_media的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter ISO基础媒体处理插件iso_base_media的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用iso_base_media插件来处理ISO基础媒体文件的示例代码。这个插件通常用于解析和处理ISO基础媒体文件(如MP4文件)中的元数据和信息。

首先,你需要在pubspec.yaml文件中添加iso_base_media依赖:

dependencies:
  flutter:
    sdk: flutter
  iso_base_media: ^x.y.z  # 请替换为最新的版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以使用以下代码来加载和解析一个ISO基础媒体文件:

import 'package:flutter/material.dart';
import 'package:iso_base_media/iso_base_media.dart';
import 'dart:typed_data';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  File? _file;
  MoovBox? _moovBox;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ISO Base Media Parser'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: _pickFile,
                child: Text('Pick MP4 File'),
              ),
              if (_file != null)
                ElevatedButton(
                  onPressed: _parseFile,
                  child: Text('Parse File'),
                ),
              if (_moovBox != null)
                Text('Number of Tracks: ${_moovBox!.trakBoxes.length}'),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _pickFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.video,
      allowMultiple: false,
    );

    if (result != null && result.files.isNotEmpty) {
      setState(() {
        _file = File(result.files.single.path!);
      });
    }
  }

  Future<void> _parseFile() async {
    if (_file == null) return;

    Uint8List fileBytes = await _file!.readAsBytes();
    IsoFile isoFile = IsoFile.parse(fileBytes);

    setState(() {
      _moovBox = isoFile.moovBox;
    });
  }
}

注意

  1. 这个示例代码使用了file_picker插件来选择文件。你需要在pubspec.yaml中添加file_picker依赖,并运行flutter pub get来安装它。
  2. iso_base_media插件的具体API可能会有所不同,取决于其版本和具体实现。上面的代码假设IsoFile类有一个静态的parse方法,该方法接受一个字节数组并返回一个IsoFile对象,该对象包含解析后的ISO基础媒体文件结构。
  3. MoovBox类代表媒体文件中的“moov”盒子(box),通常包含有关媒体轨道的元数据。

确保你已经正确导入了所有必要的包,并根据iso_base_media插件的实际API进行调整。这个示例提供了一个基本的框架,展示了如何使用该插件来加载和解析ISO基础媒体文件。

回到顶部