更新记录

1.0.0(2026-01-28)

  • feat: 初版发布(Android/iOS),提供 execFFmpeg/execFFprobe/cancel/isRunning/dispose/getVersion/getWorkDir
  • feat: 增加常用封装函数 compressVideo/extractAudio/snapshot/trimVideo/remux/replaceAudio/probeMediaInfoJson
  • feat: 增加 setLogEnabled 内部日志开关;onLog/ 使用 @UTSJS.keepAlive 适配持续回调

平台兼容性

uni-app(4.87)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.87)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - -

hans-ffmpeg

基于 FFmpegKit (full-gpl) 封装的 uni-app / uni-app x UTS 插件,提供 ffmpegffprobe 的执行能力。

平台

  • Android: √
  • iOS: √(deploymentTarget=13)
  • Harmony: -(stub,可编译)

兼容性说明

  • 本插件的 onLog/ 为持续回调,UTS 导出方法使用 @UTSJS.keepAlive 适配(需要 HBuilderX 4.27+)。

安装

将本插件放到项目的 uni_modules/hans-ffmpeg/(或通过插件市场安装)。

使用

设计为 jobId 句柄式(不返回 Task/类实例),避免跨桥序列化问题。
默认 collectOutput=truecollectLogs=true,长任务可能产生日志/输出大字符串,注意内存占用。

import { setLogEnabled, getVersion, getWorkDir, execFFmpeg, execFFprobe, cancel, isRunning, dispose, compressVideo, extractAudio, snapshot, trimVideo, remux, replaceAudio, probeMediaInfoJson } from '@/uni_modules/hans-ffmpeg'

getVersion(): HansFFmpegKitVersion

返回 FFmpegKit 与 FFmpeg 版本信息。

getWorkDir(): string

返回一个可写目录(Android cacheDir / iOS Library/Caches),便于在 demo 中构造输入输出路径。

setLogEnabled({ enabled, ... }): void

插件内部日志开关(默认关闭)。开启后会在关键节点输出 console.info,便于排查问题。

execFFmpeg(options): jobId

  • options.args: string[]:参数数组(不需要自己拼 command string)
  • 回调:
    • onLog({jobId, level, message})
    • onProgress({jobId, timeMs, size, bitrate, speed, videoFrameNumber})
    • success(res) / fail(err) / complete(any)
  • 可选流控:
    • logIntervalMs / progressIntervalMs(>0 时按间隔节流回调)

execFFprobe(options): jobId

建议使用 -print_format json 并在 success(res.output) 中解析 JSON。

cancel(jobId) / isRunning(jobId) / dispose(jobId): boolean

  • cancel: 请求取消执行
  • isRunning: 是否运行中
  • dispose: 清理内部句柄

常用封装(recipes)

这层 API 仍然是 jobId 句柄式,并复用 execFFmpeg/execFFprobe 的回调能力(onLog//success/fail/complete 等)。

  • compressVideo({ input, output, ... }):常用压缩/转码(默认 H.264 + AAC),支持 crf/preset/scale/fps/+faststart
  • extractAudio({ input, output, ... }):抽取音频(默认 aac;输出为 mp3/wav 会自动选 codec)
  • snapshot({ input, output, timeMs, ... }):截帧生成封面图
  • trimVideo({ input, output, startMs, durationMs|endMs, copyCodec, ... }):裁剪片段(默认 copyCodec=true
  • remux({ input, output, ... }):转封装(-c copy
  • replaceAudio({ videoInput, audioInput, output, ... }):替换音轨(默认视频流 copy)
  • probeMediaInfoJson({ input, ... }):输出媒体信息 JSON(等价于常用的 ffprobe -print_format json -show_format -show_streams

示例(playground 推荐用例)

生成 1 秒测试视频(无需外部输入文件)

const out = getWorkDir() + '/hans-ffmpeg-test.mp4'
execFFmpeg({
  args: ['-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=25', '-t', '1', '-pix_fmt', 'yuv420p', out],
  onLog: (e) => console.log(e.message),
  : (p) => console.log('timeMs', p.timeMs),
  success: (res) => console.log('ok', res.returnCode, res.output),
  fail: (err) => console.error(err.errCode, err.errMsg, err.data),
})

ffprobe 输出 JSON

execFFprobe({
  args: ['-v', 'error', '-print_format', 'json', '-show_format', '-show_streams', out],
  success: (res) => console.log(res.output),
})

使用封装函数(示例)

const input = out
const compressed = getWorkDir() + '/hans-ffmpeg-compressed.mp4'

compressVideo({
  input,
  output: compressed,
  maxWidth: 720,
  crf: 28,
  preset: 'veryfast',
  : (p) => console.log('timeMs', p.timeMs),
})

probeMediaInfoJson({
  input: compressed,
  success: (res) => console.log(res.output),
})

注意事项

  • args 需要按 token 传入(例如 ['-i', input, '-c:v', 'libx264', output]),不要自己拼整条字符串命令。
  • 长任务建议根据需要关闭 collectOutput/collectLogs,避免内存占用过大。
  • trimVideo 参数名为 copyCodec(避免 iOS 侧与 copy 产生 selector 冲突)。
  • 本插件依赖 FFmpegKit full-gpl,发布/分发前请确认许可证合规要求。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

本插件通过 FFmpegKit 调用本地音视频处理能力;默认不申请额外权限(使用外部存储/相册/相机等取决于你的业务与输入输出路径)。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件不采集用户数据。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。