更新记录

1.0.0(2026-11-11)

1.0.0(2026-11-11)

  • 首次发布:uni-app x 双端本地视频合成插件
  • 支持花字、字幕渲染(关键词高亮、描边、背景)
  • 支持画中画图片叠加
  • 支持片头封面(静态图或首帧定格 1 秒)
  • 支持背景音乐混音与淡入淡出
  • 支持 480p / 720p / 1080p 按短边缩放导出 MP4
  • 支持合成进度回调、取消合成
  • Android 基于 MediaCodec / MediaMuxer,iOS 基于 AVFoundation,无需 ffmpeg、无需自定义基座

平台兼容性

synthetic-video 本地视频合成

uni-app x 原生 UTS 插件,用于在 App 端本地完成视频合成:花字、字幕、画中画、片头封面、背景音乐混音、分辨率缩放,最终导出 H.264 MP4。

  • Android:MediaCodec + MediaMuxer 硬编硬解
  • iOS:AVFoundation + AVAssetExportSession
  • 零第三方依赖,不需要 ffmpeg,不需要服务端参与
  • 只读写 App 沙盒临时文件,不申请相册权限

平台兼容性

平台 支持 说明
uni-app x / App-Android √ 5.24 及以上
uni-app x / App-iOS √ 5.24 及以上
Web / H5 × 返回 9100402
小程序 × 不支持
传统 uni-app(Vue2 / Vue3) × 仅支持 uni-app x

安装

  1. 将 synthetic-video 目录放入项目的 uni_modules 下。
  2. 确认项目的 uni-app x 版本不低于 5.24(见 package.json 的 engines)。
  3. 不需要在 manifest.json 中额外声明权限。

快速开始

import { probeVideo, composeVideo, cancelCompose } from '@/uni_modules/synthetic-video'

// 1. 读取视频信息
const info = await probeVideo({ filePath: videoPath })
if (info.errorCode != 0) {
  console.log('读取失败', info.errorMessage)
}

// 2. 合成
let taskId = ''
const result = await composeVideo({
  videoPath,
  texts: [
    {
      text: '标题文字',
      style: titleStyle,
      startSec: 0,
      durationSec: 5,
      isTitle: true
    }
  ],
  overlays: [],
  keywords: ['关键词'],
  canvasWidth: 720,
  canvasHeight: 1280,
  bgmPath: null,
  bgmVolume: 20,
  introCoverPath: null,
  resolution: '720p',
  outputPath: null,
  onStart: (id : string) => {
    taskId = id
  },
  onProgress: (p) => {
    console.log(p.stage, p.percent)
  }
})

if (result.errorCode == 0) {
  console.log('成片路径', result.filePath)
} else {
  console.log('合成失败', result.errorCode, result.errorMessage)
}

// 3. 取消(可选)
// await cancelCompose({ taskId })

选择素材时建议使用 uni.chooseVideo({ compressed: false })。默认的 compressed: true 会先生成 360p / 540p 的临时文件,再合成也无法恢复清晰度。

API

所有 API 均返回 Promise,结果对象包含 errorCode 和 errorMessage,errorCode == 0 表示成功。业务失败通过 errorCode 返回,不会主动 reject。

probeVideo

读取视频宽高与时长,宽高已按旋转元数据校正。

参数 类型 必填 说明
filePath string 是 本地视频路径,支持 file:// 前缀或沙盒绝对路径

返回 ProbeVideoResult:

字段 类型 说明
errorCode number 0 表示成功
errorMessage string 错误信息
width number 视频宽(像素)
height number 视频高(像素)
durationSec number 时长(秒,保留 3 位小数)

renderTextImage

渲染单张透明花字 PNG,用于页面实时预览。样式与成片共用同一套绘制逻辑。

参数 类型 必填 说明
text string 是 文字内容
style ComposeTextStyle 是 花字样式
canvasWidth number 是 目标画布宽,用于字号换算与断行
canvasHeight number 是 目标画布高,用于位置换算
keywords string[] 是 高亮关键词,仅影响着色
outputPath string | null 否 输出 PNG 路径,null 时输出到临时目录

返回 RenderTextImageResult:

字段 类型 说明
errorCode number 0 表示成功
errorMessage string 错误信息
filePath string 生成的透明 PNG 绝对路径
width number PNG 宽
height number PNG 高
x number PNG 左上角在画布中的横坐标
y number PNG 左上角在画布中的纵坐标
canvasWidth number 所属画布宽
canvasHeight number 所属画布高

composeVideo

执行完整本地合成:渲染花字 → 叠加画中画 → 缩放 → 混音 → 插入片头 → 导出。

参数 类型 必填 说明
videoPath string 是 正片本地路径
texts ComposeTextItem[] 是 花字数组,可为空数组
overlays UTSJSONObject[] 是 画中画叠加层,可为空数组
keywords string[] 是 高亮关键词,可为空数组
canvasWidth number 是 输出画布宽,必须大于 0
canvasHeight number 是 输出画布高,必须大于 0
bgmPath string | null 否 背景音乐本地路径,null 表示不混音
bgmVolume number 否 BGM 音量档:15 / 20 / 25 / 30,默认 20
introCoverPath string | null 否 片头封面路径,null 时使用正片首帧定格 1 秒
resolution string 是 480p / 720p / 1080p,仅做档位校验与日志
outputPath string | null 否 输出路径,null 时输出到 App 临时目录
onStart (taskId: string) => void | null 否 任务启动回调,返回 taskId
onProgress (res: ComposeProgress) => void | null 否 进度回调

ComposeTextItem:

字段 类型 说明
text string 文字内容
style ComposeTextStyle 样式
startSec number 出现时间(秒,相对正片起点)
durationSec number 持续时长(秒)
isTitle boolean 是否为标题

ComposeTextStyle:

字段 类型 说明
enabled boolean 是否渲染该条花字
font string yahei / simhei / kaiti / simsun / youyuan / lisu / alimama
position string top / center(字幕)/ bottom
color string 字色,形如 #FFFFFF
font_gradient boolean 是否启用字体渐变
font_color2 string 渐变结束色
keyword_effect boolean 是否高亮关键词
highlight_color string 关键词高亮色
font_size number 设计字号,以 720 宽为基准等比换算
vertical_offset number 垂直微调,-15 ~ 15(画面高度百分比)
show_seconds number 显示时长(秒),0 表示按时间轴/整片显示
effect string fade / slide / none
background string 背景色
bg_effect string none / translucent / solid
bg_gradient boolean 是否启用背景渐变
bg_color2 string 背景渐变结束色
outline string 描边色,空字符串表示按字色自动取对比色
outline_width number 描边粗细 0 ~ 8,0 表示关闭
shadow number 阴影强度 0 ~ 8,0 表示关闭

overlays 每项字段:

字段 类型 说明
filePath string 图片或视频的本地路径
type string image / video,默认 image
startSec number 出现时间(秒,相对正片起点)
durationSec number 持续时长(秒)
aspect number 宽高比 width / height,用于等比计算高度

层级顺序:正片 → 画中画 → 花字。

ComposeProgress:

字段 类型 说明
stage string prepare / renderTexts / composeVideo / mixAudio / intro / alignAudio / finalize
percent number 0 ~ 100

返回 ComposeVideoResult:

字段 类型 说明
errorCode number 0 表示成功
errorMessage string 错误信息
filePath string 成片绝对路径
durationSec number 成片时长(秒,含片头)
width number 成片宽
height number 成片高
hasIntro boolean 是否插入了片头
hasBgm boolean 是否混入了背景音乐

cancelCompose

取消正在进行的合成,取消后插件会清理临时文件。

参数 类型 必填 说明
taskId string 是 composeVideo 的 onStart 回调返回的 taskId

返回 CancelComposeResult:errorCode、errorMessage、ok(是否成功发出取消指令)。

compressVideo

本地受控压缩,用于上传前把素材压成统一规格。

参数 类型 必填 说明
filePath string 是 本地视频路径
maxLongSide number 是 目标长边上限(像素),<= 0 不限制
bitrate number 是 目标码率(bps),<= 0 由插件自动估算
fps number 是 目标帧率,<= 0 跟随源视频
keepAudio boolean 是 是否保留音轨
outputPath string | null 否 输出路径,null 时输出到临时目录
onStart (taskId: string) => void | null 否 任务启动回调
onProgress (res: ComposeProgress) => void | null 否 进度回调

返回 CompressVideoResult:errorCode、errorMessage、filePath、width、height、durationSec、sizeBytes。

错误码

错误码 常量 说明
9100101 COMPOSE_ERR_VIDEO_NOT_FOUND 输入视频不存在或不可读
9100102 COMPOSE_ERR_INVALID_PARAMS 参数非法
9100201 COMPOSE_ERR_RENDER_TEXT_FAILED 花字渲染失败
9100202 COMPOSE_ERR_FONT_LOAD_FAILED 字体加载失败
9100301 COMPOSE_ERR_COMPOSE_FAILED 合成失败
9100302 COMPOSE_ERR_CANCELED 已取消
9100303 COMPOSE_ERR_OUTPUT_WRITE_FAILED 输出写入失败
9100304 COMPOSE_ERR_TIMEOUT 合成超时
9100305 COMPOSE_ERR_COMPRESS_FAILED 压缩失败
9100401 COMPOSE_ERR_IOS_NOT_IMPLEMENTED 历史保留错误码
9100402 COMPOSE_ERR_PLATFORM_NOT_SUPPORTED 当前平台不支持

注意事项

  1. 输出尺寸以画布为准:resolution 只做合法性校验;实际输出宽高由 canvasWidth / canvasHeight 决定。
  2. 不放大低分辨率素材:画布大于源视频时按 1 倍处理,不会插值放大。
  3. BGM 是混音,不是替换:填入 bgmPath 后原声仍然保留,BGM 按 bgmVolume 增益叠加,并带淡入淡出。当前版本没有“静音原声”参数。
  4. BGM 路径必须真实存在:路径错误或解码失败时会跳过 BGM,保留原声。
  5. 片头规则:introCoverPath 为 null 时使用正片首帧定格 1 秒;传入封面时按封面图生成 1 秒片头。
  6. 不自动保存相册:outputPath 为 null 时成片在 App 临时目录,需要调用方自行调用 uni.saveVideoToPhotosAlbum。
  7. Android 码率:按 宽 × 高 × 帧率 × 0.2 计算,限制在 2 ~ 24 Mbps;1080p30 约 12.4 Mbps。
  8. iOS 导出:使用 AVAssetExportPresetHighestQuality,由系统决定码率,通常高于 Android。
  9. 临时文件:取消或失败时插件会尽力清理本次任务的临时文件,页面侧可定期清理缓存目录。
  10. H5 / 小程序:不支持本地合成,调用返回 9100402。

更新日志

1.0.0(2026-11-11)

  • 首次发布
  • 支持花字、字幕渲染(关键词高亮、描边、背景)
  • 支持画中画图片 / 视频叠加
  • 支持片头封面(静态图或首帧定格 1 秒)
  • 支持背景音乐混音与淡入淡出
  • 支持 480p / 720p / 1080p 导出
  • 支持合成进度回调与取消
  • 支持本地受控压缩 compressVideo

隐私、权限声明

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

无

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

无

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

无

暂无用户评论。