2025-04-28 09:11:53 +08:00
2025-04-28 09:11:53 +08:00
2025-04-28 09:11:53 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:53 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:51 +08:00
2025-04-28 09:11:53 +08:00

Video Decode Plugin

基于MediaCodec/VideoToolbox的跨平台H.264/H.265视频解码Flutter插件专为低延迟实时视频流解码设计。

pub package

特性

  • 🔄 基于原生解码器的高性能视频解码Android使用MediaCodeciOS使用VideoToolbox
  • 🖼️ 支持H.264和H.265HEVC视频格式
  • ⏱️ 低延迟解码,适用于实时视频流应用
  • 📱 跨平台支持Android和iOS
  • 🔧 高度可配置的解码参数
  • 📊 详细的解码统计和诊断信息
  • 💡 支持I帧和P帧的单独传入和处理
  • 🎞️ 使用Flutter Texture进行高效渲染

安装

dependencies:
  video_decode_plugin: ^1.0.0

快速开始

初始化解码器

import 'package:video_decode_plugin/video_decode_plugin.dart';

// 创建解码器配置
final config = VideoDecoderConfig(
  width: 640,         // 视频宽度
  height: 480,        // 视频高度
  codecType: CodecType.h264,  // 编解码类型h264或h265
  frameRate: 30,      // 目标帧率(可选)
  isDebug: true,      // 是否启用详细日志
);

// 初始化解码器获取纹理ID
final textureId = await VideoDecodePlugin.initDecoder(config);

// 设置帧回调
VideoDecodePlugin.setFrameCallback((textureId) {
  // 当新帧可用时被调用
  setState(() {
    // 更新UI
  });
});

渲染视频

// 使用Flutter的Texture组件显示视频
Texture(
  textureId: textureId,
  filterQuality: FilterQuality.low,
)

解码视频帧

// 解码I帧
await VideoDecodePlugin.decodeFrame(
  frameData,  // Uint8List类型的H.264/H.265帧数据
  FrameType.iFrame
);

// 解码P帧
await VideoDecodePlugin.decodeFrame(
  frameData,  // Uint8List类型的H.264/H.265帧数据
  FrameType.pFrame
);

获取解码统计信息

final stats = await VideoDecodePlugin.getDecoderStats(textureId);
print('已渲染帧数: ${stats['renderedFrames']}');
print('丢弃帧数: ${stats['droppedFrames']}');

释放资源

await VideoDecodePlugin.releaseDecoder();

高级用法

多实例支持

插件支持同时创建和管理多个解码器实例:

// 创建第一个解码器
final textureId1 = await VideoDecodePlugin.createDecoder(config1);

// 创建第二个解码器
final textureId2 = await VideoDecodePlugin.createDecoder(config2);

// 为特定纹理ID设置回调
VideoDecodePlugin.setFrameCallbackForTexture(textureId1, (id) {
  // 处理第一个解码器的帧
});

// 为特定纹理ID解码帧
await VideoDecodePlugin.decodeFrameForTexture(textureId2, frameData, frameType);

// 释放特定解码器
await VideoDecodePlugin.releaseDecoderForTexture(textureId1);

优化I帧和SPS/PPS处理

对于H.264视频流,建议按照以下顺序处理帧:

  1. 首先发送SPS序列参数集NAL类型7
  2. 其次发送PPS图像参数集NAL类型8
  3. 然后发送IDR帧即I帧NAL类型5
  4. 最后发送P帧NAL类型1
// 发送SPS和PPS数据
await VideoDecodePlugin.decodeFrame(spsData, FrameType.iFrame);
await VideoDecodePlugin.decodeFrame(ppsData, FrameType.iFrame);

// 发送IDR帧
await VideoDecodePlugin.decodeFrame(idrData, FrameType.iFrame);

// 发送P帧
await VideoDecodePlugin.decodeFrame(pFrameData, FrameType.pFrame);

完整示例

请参考示例应用,了解如何:

  • 从文件或网络流加载H.264视频
  • 正确解析和处理NAL单元
  • 高效地解码和渲染视频帧
  • 监控解码性能并进行故障排除

支持

  • Android 5.0 (API级别21)及以上
  • iOS 11.0及以上

注意事项

  • 视频分辨率受设备硬件限制,较旧设备可能无法支持高分辨率视频
  • 硬件解码器可能在某些设备上不可用,插件会自动回退到软件解码
  • 对于最佳性能,建议在实际硬件设备上测试,而不仅仅是模拟器

许可证

MIT

Description
可视对讲的原生端解码插件
Readme 48 MiB
Languages
Dart 46.8%
Swift 28.3%
Kotlin 22.9%
Ruby 2%