搜索插件、代码仓与 APP 分类

插件详情v1.7.2

flutter_quick_video_encoder

使用硬件H.264编码器将原始RGB图像编码为MP4视频。还支持PCM音频和M4A文件。

AndroidiOSmacOS
近 30 天下载
1.2万
喜欢数
28
Pub 分数
150

安装插件

flutter pub add flutter_quick_video_encoder

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

一个 Flutter 包,可在 Android、iOS 和 macOS 上使用硬件 H.264 编码器高效地将原始 RGB 帧编码为 MP4 视频。它支持 PCM 音频输入以创建 M4A 音频轨道,非常适合实时视频录制和处理。该包利用原生平台功能,在 CPU 使用率极低的情况下实现高性能。专为需要快速、低延迟视频编码的多媒体应用程序开发者设计。

适合场景

  • 实时视频录制
  • 直播流捕获
  • 视频编辑工作流程
  • 设备端视频压缩
  • 音视频同步

主要特点

  • 硬件加速的 H.264 编码
  • PCM 音频支持
  • 跨平台兼容性
  • 低CPU开销
  • 用于帧输入的简单API

适合对象

  • 移动视频应用
  • 基于相机的应用程序
  • 媒体处理工具
  • 嵌入式视频系统
  • 高性能录制

使用建议

  • 需要原生平台权限
  • 仅限RGB输入格式
  • 编码无软件回退
  • 平台特定的配置需要
  • 音频同步需要精确的定时

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

pub package

Logo

Quickly encode raw RGB images & PCM audio to MP4 video using the system h264 encoder

No Dependencies

FlutterQuickVideoEncoder has zero dependencies besides Flutter, Android, iOS, and MacOS themselves. No FFMPEG.

We use AVFoundation on iOS and MediaCodec on Android. These are native system libraries.

For encoding raw RGB pixels

Unlike the video_compress package, this package takes raw rgb pixel buffers as input, not video files.

⭐ Stars ⭐

Please star this repo & on pub.dev. We all benefit from having a larger community.

Usage

await FlutterQuickVideoEncoder.setup(
    width: 1920,
    height: 1080,
    fps: 60,
    videoBitrate: 2500000,
    audioChannels: 1,
    audioBitrate: 64000,
    sampleRate: 44100,
    filepath: "/documents/video.mp4", // output file
);
for(int i = 0; i < frameCount; i++) {
    Uint8List rgba = _renderVideoFrame(i);  // your video function
    Uint8List pcm = _renderAudioFrame(i); // your audio function
    await FlutterQuickVideoEncoder.appendVideoFrame(rgba); 
    await FlutterQuickVideoEncoder.appendAudioFrame(pcm);
}
await FlutterQuickVideoEncoder.finish();

Example App

Enable the platforms you need.

cd ./example                      
flutter config --enable-macos-desktop                                                      
flutter config --enable-android 
flutter config --enable-ios 
flutter create .
flutter run

Create video frames using ui.Image

The easiest way to render a video frame is to use Flutter!

For example, you can render an RGBA frame using ui.Image

Future<Uint8List> _generateVideoFrame(int frameIndex) async {
    const int boxSize = 50; // Size of the moving box

    // Calculate the box position
    int boxX = (frameIndex * 5) % width;
    int boxY = (frameIndex * 5) % height;

    // Paint the moving box
    final recorder = ui.PictureRecorder();
    final canvas = Canvas(recorder);
    final paint = Paint();

    // Draw a white background
    paint.color = Colors.white;
    canvas.drawRect(Rect.fromLTWH(0, 0, width.toDouble(), height.toDouble()), paint);

    // Draw the blue box
    paint.color = Colors.blue;
    canvas.drawRect(Rect.fromLTWH(boxX.toDouble(), boxY.toDouble(), boxSize.toDouble(), boxSize.toDouble()), paint);

    // Convert canvas to image
    final picture = recorder.endRecording();
    final img = await picture.toImage(width, height);

    // Convert the image to a byte array
    final byteData = await img.toByteData(format: ui.ImageByteFormat.rawRgba);
    return byteData!.buffer.asUint8List();
}

Create video frames from Widgets

You can also create video frames from widgets, using RenderRepaintBoundary

import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'dart:typed_data';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  GlobalKey repaintBoundaryKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: repaintBoundaryKey,
      child: YourWidget(), // Replace with your actual widget
    );
  }

  // you would then call appendVideoFrame with this data
  Future<Uint8List?> captureWidgetAsRGBA() async {
    try {
      RenderRepaintBoundary boundary = repaintBoundaryKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
      ui.Image image = await boundary.toImage(pixelRatio: 1.0);
      ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.rawRgba);
      return byteData?.buffer.asUint8List();
    } catch (e) {
      print(e);
      return null;
    }
  }
}

所属分类

源码仓库

使用此插件的项目

暂无相关数据。