193 lines
4.4 KiB
Markdown
Raw Normal View History

2025-04-21 15:11:23 +08:00
# Video Decode Plugin
2025-04-28 01:08:21 +00:00
2025-04-28 09:07:23 +08:00
> 当前版本0.0.1
> 最低 Flutter SDK 要求:>=3.3.0
> 最低 Dart SDK 要求:>=3.3.4
2025-04-28 09:24:11 +08:00
## 说明
- 目前只支持Android端解码
2025-04-21 15:11:23 +08:00
## 安装
2025-04-28 01:08:21 +00:00
2025-04-21 10:56:28 +08:00
```yaml
dependencies:
2025-04-28 09:07:23 +08:00
video_decode_plugin: ^0.0.1 # 使用最新版本
2025-04-21 10:56:28 +08:00
```
2025-04-28 01:08:21 +00:00
2025-04-28 09:07:23 +08:00
## 环境要求
- Flutter SDK: >=3.3.0
- Dart SDK: >=3.3.4
- Android:
- minSdkVersion: 21 (Android 5.0)
- targetSdkVersion: 最新版本
- iOS:
- 最低版本: 11.0
- 开发环境: Xcode 最新版本
2025-04-21 15:11:23 +08:00
## 快速开始
2025-04-28 01:08:21 +00:00
2025-04-28 09:24:11 +08:00
### 在星锁项目中调试
2025-04-28 09:25:05 +08:00
1. 需切换到`develop_liyi`分支
2025-04-28 09:25:36 +08:00
2025-04-28 09:27:42 +08:00
2. 将本仓库代码拉取到本地后,在项目中增加本地的插件依赖
```dart
video_decode_plugin:
path: ../video_decode_plugin
```
3. `appRouters.dart`找到打开路由配置文件,在文件最下方切换配置路由地址
2025-04-28 09:24:11 +08:00
```dart
// GetPage<dynamic>(name: Routers.h264WebView, page: () => TalkViewNativeDecodePage()), // 插件播放页面
GetPage<dynamic>(name: Routers.h264WebView, page: () => H264WebView()), // webview播放页面
```
2025-04-28 09:27:42 +08:00
4. 使用插件调试则打开上一个注释同时注释掉weview的播放页面
2025-04-28 09:24:11 +08:00
2025-04-21 15:11:23 +08:00
### 初始化解码器
2025-04-21 10:56:28 +08:00
```dart
import 'package:video_decode_plugin/video_decode_plugin.dart';
2025-04-21 15:11:23 +08:00
// 创建解码器配置
final config = VideoDecoderConfig(
width: 640, // 视频宽度
height: 480, // 视频高度
codecType: CodecType.h264, // 编解码类型h264或h265
frameRate: 30, // 目标帧率(可选)
isDebug: true, // 是否启用详细日志
2025-04-21 10:56:28 +08:00
);
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
// 初始化解码器获取纹理ID
final textureId = await VideoDecodePlugin.initDecoder(config);
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
// 设置帧回调
VideoDecodePlugin.setFrameCallback((textureId) {
// 当新帧可用时被调用
setState(() {
// 更新UI
});
});
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
### 渲染视频
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
```dart
// 使用Flutter的Texture组件显示视频
Texture(
textureId: textureId,
filterQuality: FilterQuality.low,
)
2025-04-21 10:56:28 +08:00
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
### 解码视频帧
```dart
// 解码I帧
await VideoDecodePlugin.decodeFrame(
frameData, // Uint8List类型的H.264/H.265帧数据
FrameType.iFrame
);
// 解码P帧
await VideoDecodePlugin.decodeFrame(
frameData, // Uint8List类型的H.264/H.265帧数据
FrameType.pFrame
);
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
### 获取解码统计信息
2025-04-28 01:08:21 +00:00
2025-04-21 10:56:28 +08:00
```dart
2025-04-21 15:11:23 +08:00
final stats = await VideoDecodePlugin.getDecoderStats(textureId);
print('已渲染帧数: ${stats['renderedFrames']}');
print('丢弃帧数: ${stats['droppedFrames']}');
2025-04-21 10:56:28 +08:00
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
### 释放资源
2025-04-28 01:08:21 +00:00
2025-04-21 10:56:28 +08:00
```dart
2025-04-21 15:11:23 +08:00
await VideoDecodePlugin.releaseDecoder();
2025-04-21 10:56:28 +08:00
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
## 高级用法
### 多实例支持
插件支持同时创建和管理多个解码器实例:
2025-04-21 10:56:28 +08:00
```dart
2025-04-21 15:11:23 +08:00
// 创建第一个解码器
final textureId1 = await VideoDecodePlugin.createDecoder(config1);
// 创建第二个解码器
final textureId2 = await VideoDecodePlugin.createDecoder(config2);
// 为特定纹理ID设置回调
VideoDecodePlugin.setFrameCallbackForTexture(textureId1, (id) {
// 处理第一个解码器的帧
2025-04-21 10:56:28 +08:00
});
2025-04-21 15:11:23 +08:00
// 为特定纹理ID解码帧
await VideoDecodePlugin.decodeFrameForTexture(textureId2, frameData, frameType);
// 释放特定解码器
await VideoDecodePlugin.releaseDecoderForTexture(textureId1);
2025-04-21 10:56:28 +08:00
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
### 优化I帧和SPS/PPS处理
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
对于H.264视频流,建议按照以下顺序处理帧:
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
1. 首先发送SPS序列参数集NAL类型7
2. 其次发送PPS图像参数集NAL类型8
3. 然后发送IDR帧即I帧NAL类型5
4. 最后发送P帧NAL类型1
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
```dart
// 发送SPS和PPS数据
await VideoDecodePlugin.decodeFrame(spsData, FrameType.iFrame);
await VideoDecodePlugin.decodeFrame(ppsData, FrameType.iFrame);
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
// 发送IDR帧
await VideoDecodePlugin.decodeFrame(idrData, FrameType.iFrame);
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
// 发送P帧
await VideoDecodePlugin.decodeFrame(pFrameData, FrameType.pFrame);
```
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
## 完整示例
2025-04-28 01:08:21 +00:00
2025-04-21 15:11:23 +08:00
请参考示例应用,了解如何:
- 从文件或网络流加载H.264视频
- 正确解析和处理NAL单元
- 高效地解码和渲染视频帧
- 监控解码性能并进行故障排除
2025-04-28 01:08:21 +00:00
2025-04-28 09:07:23 +08:00
## 版本历史
2025-04-28 01:08:21 +00:00
2025-04-28 09:38:17 +08:00
### 0.0.1 - 2025.04
2025-04-28 09:07:23 +08:00
- ✨ 初始版本发布
- 🎯 基础功能实现:
- H.264/H.265 解码支持
- 实时视频流解码
- 基础错误处理
2025-04-28 01:08:21 +00:00
2025-04-28 09:31:42 +08:00
### 现有问题
- 解码后在flutter渲染实际帧数较低
- 方案一使用原生activity渲染视频数据
- 方案二多个TextureView并行交替渲染
- 方案三:待补充
- 方案四:待补充
2025-04-28 01:08:21 +00:00
2025-04-28 09:07:23 +08:00
### 后续计划
- [ ] 解码帧数较低
- [ ] 增加更多错误处理
- [ ] 完善文档和示例
- [ ] 添加单元测试
- [ ] 支持更多编解码格式
- [ ] 优化内存管理
2025-04-28 01:08:21 +00:00