更新记录

1.2.1(2026-07-12)

更新文档

1.2.0(2026-07-12)

  • 首次发布 Android/iOS 音视频裁剪、压缩与 FFmpeg/FFprobe 命令能力。

平台兼容性

uni-app(4.85)

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

uni-app x(4.85)

Chrome Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序
- - 5.0 1.2.1 12 1.2.1 - -

hl-ffmpeg-video

hl-ffmpeg-video 是一个运行在 Android 和 iOS 手机上的本地音视频处理插件。它可以裁剪、压缩、取帧、提取音频、拼接视频、生成 GIF,也可以直接执行 FFmpeg 和 FFprobe 命令。

所有处理都在设备本地完成。插件不会上传视频,也不会收集用户数据。

先了解这三件事

  1. 插件只处理本地视频文件,不能直接传网络 URL。
  2. 必须使用包含本插件的自定义基座或云端打包后的 App。标准基座不包含 FFmpeg 依赖。
  3. 所有处理结果都在回调里返回。成功时读取路径字段,例如 result.mp4result.imageresult.audio

支持的平台

平台 最低版本 说明
Android Android 5.0(API 21) 支持 armeabi-v7a、arm64-v8a、x86、x86_64
iOS iOS 12.0 支持 arm64 设备
Web、小程序、HarmonyOS 不支持 没有原生 FFmpeg 运行环境

第一次使用

1. 导入插件

插件放在项目的 uni_modules 目录时,不需要额外安装。

import { getVideoEditor } from '@/uni_modules/hl-ffmpeg-video'

const editor = getVideoEditor()

2. 选择视频并保存本地路径

uni.chooseVideo 返回的 tempFilePath 可以直接传给插件。

import { ref } from 'vue'

const videoPath = ref('')

function chooseVideo() {
  uni.chooseVideo({
    sourceType: ['album', 'camera'],
    compressed: false,
    success: (file) => {
      videoPath.value = file.tempFilePath
    }
  })
}

如果你使用 _doc_www 一类目录,请先转换为绝对路径:

const videoPath = plus.io.convertLocalFileSystemURL('_doc/source.mp4')

3. 用最小示例验证插件

先读取视频信息。看到 code: 0 即说明视频路径和原生依赖可用。

editor.getVideoInfo({ url: videoPath.value }, (result) => {
  if (result.code === 0) {
    console.log('视频尺寸:', result.width, result.height)
    console.log('视频时长:', result.duration, '秒')
    return
  }
  console.error('读取失败:', result.msg)
})

最常用:比例裁剪

下面的示例会打开原生裁剪页面。用户可以拖动裁剪框和时间滑块,点击“完成”后生成一条 9:16、720p 的视频。

editor.openCrop({
  url: videoPath.value,
  ratio: '9/16',
  resolution: '720p',
  mode: 'scale',
  quality: 'hd',
  mintime: 2000,
  maxtime: 30,
  codecs: 1,
  fps: 30,
  gop: 60
}, (result) => {
  if (result.code === 1 && result.progress != null) {
    console.log('处理进度:', result.progress)
    return
  }
  if (result.code === 0) {
    console.log('视频路径:', result.mp4)
    console.log('封面路径:', result.image)
    return
  }
  console.error(result.msg, result.detail || '')
})

mode 的含义:

适用场景
scale 先按裁剪框裁剪,再输出指定比例。适合去掉画面边缘。
fill 保留完整画面,等比缩放后用留边补满目标尺寸。适合不希望裁掉内容。

全部能力一览

方法 用途 成功结果的主要字段
openCrop 打开固定比例裁剪页面 mp4imagedurationsize
openFreeCut 打开自由裁剪页面 mp4;或仅返回裁剪区域
videoToZip 不打开页面,直接截取或压缩视频 mp4imagedurationsize
getVideoInfo 读取时长、尺寸、帧率、码率等 durationwidthheight
getVideoFirstFrame 提取第一帧图片 image
getVideoFrame 提取指定时间点图片 image
generateThumbnails 批量生成缩略图 imagescount
extractAudio 从视频提取 M4A 或 MP3 audioformat
removeAudio 生成无声视频 mp4
mergeAudioVideo 用音频替换视频音轨 mp4
concatVideos 按顺序拼接多个视频 mp4
videoToGif 将视频片段转为 GIF gif
cancel 取消当前媒体处理任务
deleteCache 清理插件默认输出目录
FFmpeg 执行 FFmpeg 命令并接收日志 回调 codemsg
FFprobe 执行 FFprobe 命令并接收日志 通过日志回调返回
ffmpegCancel 取消 FFmpeg 启动的命令

常用调用示例

直接压缩到 720p

editor.videoToZip({
  url: videoPath.value,
  resolutionMax: '720p',
  quality: 'hd',
  codecs: 1,
  startTime: 0,
  endTime: 10_000
}, (result) => {
  if (result.code === 0) console.log(result.mp4)
})

获取首帧和第 5 秒画面

editor.getVideoFirstFrame({ url: videoPath.value, width: 720 }, (result) => {
  if (result.code === 0) console.log('首帧:', result.image)
})

editor.getVideoFrame({ url: videoPath.value, timeMs: 5000, width: 720 }, (result) => {
  if (result.code === 0) console.log('第 5 秒画面:', result.image)
})

生成 6 张缩略图

editor.generateThumbnails({
  url: videoPath.value,
  startTime: 0,
  intervalMs: 2000,
  count: 6,
  width: 320
}, (result) => {
  if (result.code === 0) console.log(result.images)
})

提取音频、生成无声视频、替换音轨

editor.extractAudio({ url: videoPath.value, format: 'm4a', bitrate: '192k' }, (audioResult) => {
  if (audioResult.code !== 0) return

  editor.mergeAudioVideo({
    url: videoPath.value,
    audioUrl: audioResult.audio
  }, (mergeResult) => {
    if (mergeResult.code === 0) console.log('新视频:', mergeResult.mp4)
  })
})

editor.removeAudio({ url: videoPath.value }, (result) => {
  if (result.code === 0) console.log('无声视频:', result.mp4)
})

拼接视频和生成 GIF

editor.concatVideos({
  urls: [firstVideoPath, secondVideoPath]
}, (result) => {
  if (result.code === 0) console.log('拼接结果:', result.mp4)
})

editor.videoToGif({
  url: videoPath.value,
  startTime: 1000,
  durationMs: 3000,
  width: 480,
  fps: 12
}, (result) => {
  if (result.code === 0) console.log('GIF:', result.gif)
})

执行 FFmpeg 和 FFprobe

命令可以带 ffmpeg / ffprobe 前缀,也可以只传参数。路径中有空格时请用单引号包住。

const input = videoPath.value
const cover = plus.io.convertLocalFileSystemURL('_doc/cover.jpg')

editor.FFmpeg(
  { command: `ffmpeg -y -ss 1 -i '${input}' -frames:v 1 '${cover}'` },
  (log) => console.log(log),
  (result) => console.log(result)
)

editor.FFprobe(
  { command: `ffprobe -i '${input}' -show_streams -show_format` },
  (log) => console.log(log)
)

参数说明

所有生成文件的方法

参数 类型 说明
url string 本地视频绝对路径,必填。可以带 file://
saveDirectory string 输出目录绝对路径。省略时使用插件缓存目录。

裁剪、压缩和导出参数

参数 推荐值或范围 说明
resolution 360p480p720p1080p 固定输出宽度。
resolutionMax 同上 只在原视频超过该宽度时缩小。
ratio 1/19/1616/9 输出比例;不传则保持原比例。
mode scalefill 裁剪或留边策略。
quality ldsdhdssd 预设码率等级。一般选择 hd
bitrate 例如 2500k 明确指定视频码率,优先级高于 quality
codecs 012 0 为平台硬编码,1 为 H.264,2 为 H.265。iOS 会使用系统 VideoToolbox 编码器。
fps 例如 30 输出帧率;0 保持原帧率。
gop 例如 60 关键帧间隔;0 使用编码器默认值。
startTimeendTime 毫秒 无界面截取的开始和结束时间;endTime: 0 表示到结尾。
saveToAlbum truefalse 成功后保存到系统相册。首次使用会请求系统权限。

crf 是软件编码质量参数。移动端首次接入建议先使用 quality,不必设置 crf。如同时设置 bitratecrfbitrate 优先。

裁剪界面额外参数

参数 说明
mintime 最短可选时长,单位毫秒,默认 2000
maxtime 最长可选时长,单位秒,0 表示不限。
showModeButton 是否显示“裁剪/填充”切换按钮。
backgroundColor 裁剪页面背景色,例如 #141414
setCropFrameColor 裁剪框颜色。
isCrop openFreeCut 使用。设为 false 时只返回选中的裁剪区域,不生成视频。
isHideCropFrame openFreeCut 使用。是否隐藏裁剪框。
cropFrameParam 网格配置,例如 { isShowGrid: true, gridNumber: 3, dragBlock4or8: true }

回调结果和进度

每个回调至少包含 codemsg

code 含义 处理方式
0 成功 读取当前方法的结果字段。
1 且有 progress 正在处理 progress 范围为 0-99。成功时即为 100%。
1 且没有 progress 已取消 可以恢复页面按钮状态。
负数 失败 查看 msg,高级方法还可查看 detail

失败时建议同时输出 result.msgresult.detail

if (result.code < 0) {
  console.error(result.msg)
  console.error(result.detail || '')
}

常见问题

提示找不到 FFmpeg 或原生类

当前运行的不是新制作的自定义基座。重新制作并安装基座后再运行项目;普通标准基座无法加载本插件的原生依赖。

提示文件不存在或无法读取视频

确认传入的是 App 可访问的本地绝对路径。不要直接传 _doc/a.mp4,应先通过 plus.io.convertLocalFileSystemURL() 转换。

处理完成后找不到输出文件

先使用回调中的 mp4imageaudiogif 路径。未设置 saveDirectory 时,文件位于插件缓存目录;调用 deleteCache() 会清理这些默认输出。

处理失败如何定位

打印 result.detail。其中包含 FFmpeg 日志和失败时实际执行的命令。常见原因包括输入路径错误、输出目录不可写、视频编码不受支持或参数超出视频尺寸。

iOS 比例裁剪或压缩失败

iOS 使用 h264_videotoolboxhevc_videotoolbox 进行编码。请使用本插件最新版本制作自定义基座,不要在 iOS 上手动指定 libx264libx265

隐私、权限声明

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

仅在 saveToAlbum 为 true 时请求系统媒体库写入权限

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

插件不采集或上传用户数据

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

暂无用户评论。