更新记录

1.0.0(2026-11-13) 下载此版本

视频压缩(yy-videocompress)

纯 Android 系统 API 实现的视频压缩原生插件,不携带任何第三方 so,aar 仅 18KB。

功能

对已有视频文件做一次转码压缩,输出体积更小的 mp4。适用于作业类、巡检类 App 上传现场录像前把 40~80MB 的原片压到 3~6MB。

  • 硬解硬编直连:MediaExtractor 解封装 → MediaCodec 解码 → 编码器输入 Surface 直连 → MediaMuxer 重封装,全程不经过 CPU 内存拷贝,不产生 YUV 中间数据
  • 分辨率降级链:按源尺寸、1280、960、640 逐档尝试,某档编码器不认才降下一档,四档全失败才报错
  • 旋转信息保留:读取源 rotation 并写入 setOrientationHint,竖屏录像压完不会变横屏
  • 音频直通:采样率与声道不变时不重编码,速度快且无二次损伤
  • 单线程串行队列:内部排队,不并发抢 MediaCodec 实例(低端手持机通常只有 2~4 个编码器实例,并发即失败)
  • 输出落应用私有目录:不需要任何存储权限,Android 10 / 11 / 12+ 行为一致
  • 源文件未写完保护:进转码前轮询等文件大小稳定,避免录制刚结束时读到不完整的 moov

兼容性

项 支持范围
平台 Android
最低版本 Android 5.0(API 21)
CPU 架构 不限(纯 Java,无 so)
权限 不需要申请任何权限
需用 云打包、离线打包均可(云打包需上架市场)

前置条件

插件不申请存储权限,因此只能读取宿主 App 自己有权限访问的路径。录制产生的文件位于应用私有目录(getExternalFilesDir 下)时可直接使用;若要处理相册或外置卡的任意视频,需宿主 App 自行申请 READ_MEDIA_VIDEO(Android 13+)或 READ_EXTERNAL_STORAGE 后再传路径进来。

使用方法

const vc = uni.requireNativePlugin('yy-videocompress-YYVideoCompressModule');

vc.compress({
    inPath: '/storage/emulated/0/Android/data/<包名>/files/xxx.mp4',
    bitrate: 1800000,
    frameRate: 24
}, (res) => {
    if (res.done) {
        console.log('压缩完成', res.outPath, res.outBytes);
    }
}, (err) => {
    console.log('压缩失败', err.code, err.message);
});

参数

参数 类型 默认 说明
inPath String 必填 源文件绝对路径,带不带 file:// 均可
outPath String 空 不传则输出到源文件同目录,命名 原名_c.mp4,重名自动加序号
bitrate Number 1800000 目标码率,会按缩放比例折算并夹到编码器支持区间
frameRate Number 24 目标帧率,上限 60
maxWidth Number 0 0 表示跟随源尺寸;指定后以此宽度为第一档再逐档降
timeoutMs Number 120000 单档超时,超时后自动换下一档继续,不整体失败

回调

进度回调走第二个参数,字段 done: false、progress: 0~100,可多次触发:

{ done: false, progress: 45 }

终态只回调一次。

成功:

{ done: true, outPath: '/xxx/xxx_c.mp4', outBytes: 4123456, srcBytes: 41234567 }

失败:

{ done: false, code: 1002, message: '四档降级均失败: 1280px: ...' }

其他方法

// 读取视频信息,用于判断是否值得压缩
vc.info({ inPath: '...' }, (res) => {
    // { done: true, width, height, rotation, durationMs, bitrate, bytes }
});

// 查询队列积压数
vc.pending((res) => { console.log(res.pending); });

// 取消当前任务及队列中后续任务
vc.cancel();

错误码

code 含义 建议处理
1001 源文件不存在、不可读或无视频轨 不要重试,直接用原文件
1002 四档降级全部失败 可重试一次,仍失败则用原文件
1003 解码异常,源文件多半被截断 不要重试
1004 编码异常,codec 被回收 可重试一次
1005 输出文件创建失败 检查剩余存储空间
1006 单档超时 内部已自动降档,一般不会外抛

注意事项

  • 压缩耗时与视频时长、分辨率正相关,1080p、30 秒的视频在低端手持机上约需 20~40 秒,建议在界面上给出进度提示
  • 插件内部串行处理,同时提交多条任务时会依次排队,可用 pending() 取积压数
  • 压缩失败时务必保留原文件,不要直接删除,避免数据丢失
  • 不支持 Kotlin,插件本身为 Java 实现

更新记录

1.0.0

  • 首个版本,支持分辨率降级、旋转保留、音频直通、队列串行与取消

平台兼容性

uni-app(5.04)

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

视频压缩(yy-videocompress)

纯 Android 系统 API 实现的视频压缩原生插件,不携带任何第三方 so,aar 仅 18KB。

功能

对已有视频文件做一次转码压缩,输出体积更小的 mp4。适用于作业类、巡检类 App 上传现场录像前把 40~80MB 的原片压到 3~6MB。

  • 硬解硬编直连:MediaExtractor 解封装 → MediaCodec 解码 → 编码器输入 Surface 直连 → MediaMuxer 重封装,全程不经过 CPU 内存拷贝,不产生 YUV 中间数据
  • 分辨率降级链:按源尺寸、1280、960、640 逐档尝试,某档编码器不认才降下一档,四档全失败才报错
  • 旋转信息保留:读取源 rotation 并写入 setOrientationHint,竖屏录像压完不会变横屏
  • 音频直通:采样率与声道不变时不重编码,速度快且无二次损伤
  • 单线程串行队列:内部排队,不并发抢 MediaCodec 实例(低端手持机通常只有 2~4 个编码器实例,并发即失败)
  • 输出落应用私有目录:不需要任何存储权限,Android 10 / 11 / 12+ 行为一致
  • 源文件未写完保护:进转码前轮询等文件大小稳定,避免录制刚结束时读到不完整的 moov

兼容性

项 支持范围
平台 Android
最低版本 Android 5.0(API 21)
CPU 架构 不限(纯 Java,无 so)
权限 不需要申请任何权限
需用 云打包、离线打包均可(云打包需上架市场)

前置条件

插件不申请存储权限,因此只能读取宿主 App 自己有权限访问的路径。录制产生的文件位于应用私有目录(getExternalFilesDir 下)时可直接使用;若要处理相册或外置卡的任意视频,需宿主 App 自行申请 READ_MEDIA_VIDEO(Android 13+)或 READ_EXTERNAL_STORAGE 后再传路径进来。

使用方法

const vc = uni.requireNativePlugin('yy-videocompress-YYVideoCompressModule');

vc.compress({
    inPath: '/storage/emulated/0/Android/data/<包名>/files/xxx.mp4',
    bitrate: 1800000,
    frameRate: 24
}, (res) => {
    if (res.done) {
        console.log('压缩完成', res.outPath, res.outBytes);
    }
}, (err) => {
    console.log('压缩失败', err.code, err.message);
});

参数

参数 类型 默认 说明
inPath String 必填 源文件绝对路径,带不带 file:// 均可
outPath String 空 不传则输出到源文件同目录,命名 原名_c.mp4,重名自动加序号
bitrate Number 1800000 目标码率,会按缩放比例折算并夹到编码器支持区间
frameRate Number 24 目标帧率,上限 60
maxWidth Number 0 0 表示跟随源尺寸;指定后以此宽度为第一档再逐档降
timeoutMs Number 120000 单档超时,超时后自动换下一档继续,不整体失败

回调

进度回调走第二个参数,字段 done: false、progress: 0~100,可多次触发:

{ done: false, progress: 45 }

终态只回调一次。

成功:

{ done: true, outPath: '/xxx/xxx_c.mp4', outBytes: 4123456, srcBytes: 41234567 }

失败:

{ done: false, code: 1002, message: '四档降级均失败: 1280px: ...' }

其他方法

// 读取视频信息,用于判断是否值得压缩
vc.info({ inPath: '...' }, (res) => {
    // { done: true, width, height, rotation, durationMs, bitrate, bytes }
});

// 查询队列积压数
vc.pending((res) => { console.log(res.pending); });

// 取消当前任务及队列中后续任务
vc.cancel();

错误码

code 含义 建议处理
1001 源文件不存在、不可读或无视频轨 不要重试,直接用原文件
1002 四档降级全部失败 可重试一次,仍失败则用原文件
1003 解码异常,源文件多半被截断 不要重试
1004 编码异常,codec 被回收 可重试一次
1005 输出文件创建失败 检查剩余存储空间
1006 单档超时 内部已自动降档,一般不会外抛

注意事项

  • 压缩耗时与视频时长、分辨率正相关,1080p、30 秒的视频在低端手持机上约需 20~40 秒,建议在界面上给出进度提示
  • 插件内部串行处理,同时提交多条任务时会依次排队,可用 pending() 取积压数
  • 压缩失败时务必保留原文件,不要直接删除,避免数据丢失
  • 不支持 Kotlin,插件本身为 Java 实现

更新记录

1.0.0

  • 首个版本,支持分辨率降级、旋转保留、音频直通、队列串行与取消

隐私、权限声明

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

无

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

插件不采集任何数据

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

无

许可协议

许可协议

Copyright (c) 2026 yy. All rights reserved.

本插件(yy-videocompress,下称“本插件”)为闭源授权软件,其编译产物 aar 中的代码已做混淆处理。

允许

  • 在任意数量的 uni-app 项目中免费使用本插件,包括商业项目
  • 在项目交付物中一并分发包含本插件的安装包(apk)
  • 为集成目的查阅本文档与公开的调用说明

禁止

  • 反编译、反汇编、逆向工程本插件的 aar,或试图还原其源码
  • 将本插件(含其 aar 文件)单独再分发、转售、出租或作为其他插件市场的商品发布
  • 修改本插件的 aar 后以原名称或其他名称发布
  • 移除或修改本插件中的版权声明

免责

本插件按“现状”提供,不附带任何明示或暗示的担保,包括但不限于对特定用途适用性的担保。在适用法律允许的最大范围内,作者不对因使用本插件产生的任何直接或间接损失承担责任。

视频压缩涉及媒体文件读写与转码,使用方应自行保证源文件留有备份,并对压缩结果在上线前做抽样验证。

联系

如需商用授权、源码授权或定制开发,请通过插件市场的作者联系方式沟通。

暂无用户评论。