
uni-app Android 平板 uni.chooseVideo 录像失败原因与 chooseMedia 兼容方案
uni-app App 端使用 uni.chooseVideo 调起录像时,部分 Android 平板会直接进入 fail 回调。本文分析系统 ROM 相机 Intent 兼容性、CAMERA 与 RECORD_AUDIO 权限、自定义基座等常见原因,并提供使用 uni.chooseMedia 优先、chooseVideo 降级的完整解决方案及排查清单。
问题
uni-app App 端使用 uni.chooseVideo 调起录像,手机正常,部分 Android 平板直接走 fail 回调,无法调起拍摄界面。从相册选择视频则正常。
原因
官方文档在 uni.chooseVideo 的注意事项中明确写了:
camera 部分 Android 手机下由于系统 ROM 不支持无法生效,打开拍摄界面后可操作切换。
maxDuration:Android 取决于 ROM 的拍照组件是否实现此功能,如果没实现此功能则忽略此属性。
chooseVideo 在 App 端依赖系统相机的 Intent,不同厂商平板 ROM 的相机组件实现差异大,部分平板无法正常调起录像 Intent,直接 fail。
解决方案
改用 uni.chooseMedia(App 端需 HBuilderX 4.52+),内部实现不依赖系统相机 Intent,兼容性更好。同时保留 chooseVideo 作为降级。
代码
function chooseVideo(sourceType) {
// 优先使用 uni.chooseMedia(App 端需 HBuilderX 4.52+)
if (typeof uni.chooseMedia === 'function') {
uni.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: [sourceType],
maxDuration: 30,
camera: 'back',
success: (res) => {
const file = res.tempFiles?.[0]
if (file?.tempFilePath) {
// 上传处理
uploadFiles([file.tempFilePath], { duration: file.duration })
}
},
fail: (err) => {
if (err.errMsg && err.errMsg.includes('cancel')) return
console.error('[chooseVideo] chooseMedia fail:', JSON.stringify(err))
// 降级到 chooseVideo
chooseVideoLegacy(sourceType)
}
})
} else {
chooseVideoLegacy(sourceType)
}
}
// 降级方案:旧版 uni.chooseVideo
function chooseVideoLegacy(sourceType) {
uni.chooseVideo({
sourceType: [sourceType],
maxDuration: 60,
success: (res) => {
uploadFiles([res.tempFilePath], { duration: res.duration })
},
fail: (err) => {
if (err.errMsg && err.errMsg.includes('cancel')) return
console.error('[chooseVideo] chooseVideo fail:', JSON.stringify(err))
uni.showToast({ title: '拍摄失败,请检查摄像头/麦克风权限', icon: 'none' })
}
})
}
调用方式
uni.showActionSheet({
itemList: ['拍摄视频', '从相册选择视频'],
success: (res) => {
switch (res.tapIndex) {
case 0: chooseVideo('camera'); break
case 1: chooseVideo('album'); break
}
}
})
注意事项
1. maxDuration 不同
| API | maxDuration 范围 | 默认值 |
|---|---|---|
chooseVideo | 最长 60s | — |
chooseMedia | 3-30s | 10 |
chooseMedia 的 maxDuration 最大只有 30 秒,从 chooseVideo 迁移时需要注意。
2. 返回值结构不同
// chooseVideo 返回
{
tempFilePath: 'xxx.mp4',
duration: 15,
size: 1234567,
// ...
}
// chooseMedia 返回
{
tempFiles: [
{
tempFilePath: 'xxx.mp4',
duration: 15,
size: 1234567,
fileType: 'video',
// ...
}
],
type: 'video'
}
取值从 res.tempFilePath 改为 res.tempFiles[0].tempFilePath。
3. RECORD_AUDIO 权限
视频录制需要同时声明 CAMERA 和 RECORD_AUDIO 权限,在 manifest.json 中:
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>"
声明权限后需要重新云打包或制作自定义基座才生效,HBuilderX 标准基座不包含 RECORD_AUDIO。
4. HBuilderX 版本要求
uni.chooseMedia 在 App 端需要 HBuilderX 4.52+。低版本环境下 typeof uni.chooseMedia 不为 function,会自动走降级逻辑。
排查清单
遇到 chooseVideo 录像失败时,按以下顺序排查:
- 打印错误日志:
fail回调中console.error(JSON.stringify(err)),查看具体错误信息 - 检查权限声明:
manifest.json中是否有CAMERA+RECORD_AUDIO - 检查基座:是否使用包含权限的自定义基座(标准基座无录音权限)
- 检查系统权限:系统设置 → 应用 → 权限 → 摄像头和麦克风是否已开启
- 切换 API:尝试
chooseMedia替代chooseVideo - 检查存储空间:视频录制需要临时空间,空间不足也会 fail