使用cordova-plugin-media录制音频生成0字节空文件的问题咨询
Cordova 音频录制生成0字节空文件修复方案
问题根因匹配
对应你测试时所有格式都生成0字节空文件的表现,核心触发点有三个:
- 录制逻辑的时序错误:调用
stopRecord()后立刻同步执行release(),插件还没完成音频编码、内存缓冲区刷盘、文件句柄关闭的收尾流程,就被强制释放硬件资源,所有音频数据没有写入磁盘。 - 路径适配错误:手动拼接的存储路径没有经过Cordova文件系统的合法性校验,Android不同版本下插件会直接创建空的文件占位,但无法获得实际的写入权限。
- 权限逻辑不完整:只在配置文件中静态声明了权限,没有在调用录制前触发Android 6.0+要求的动态权限申请,系统允许插件创建空文件占位,但禁止写入实际音频数据。
可直接落地的修复步骤
- 调整录制流程的时序
严格按照「开始录制 → 到时间点调用停止录制 → 等待插件的停止成功回调 → 延迟等待磁盘写入完成 → 释放Media资源」的流程执行,不要把停止录制和释放资源放在同一个同步代码块里连续调用。 - 替换路径生成逻辑
不要手动拼接app.path类的自定义路径,通过cordova-plugin-file提供的resolveLocalFileSystemURL方法,解析cordova.file.externalDataDirectory对应的真实本地路径,再拼接带格式后缀的文件名,避免路径格式不匹配导致的写入失败。 - 补齐动态权限申请
静态声明的权限在Android 6.0+系统不会自动生效,需要在调用录制前,向用户申请RECORD_AUDIO权限。注意cordova.file.externalDataDirectory是应用私有外部存储目录,应用本身拥有完全读写权限,不需要额外申请全量的WRITE_EXTERNAL_STORAGE权限,后者在Android 13+版本上已经被系统废弃,申请了也无法获得对应权限。 - 优先选择兼容性最好的录制格式
不要测试mp3、wav等格式,cordova-plugin-media在Android端的原生录制能力基于系统的MediaRecorder实现,对.m4a格式的兼容性最好,其他格式容易出现编码失败生成空文件的问题。 - 修正播放组件的路径适配
录制完成后插入的音频控件,不能直接使用系统本地文件路径作为src,需要通过webview适配方法把本地路径转换成webview可访问的格式,否则就算音频文件录制成功,播放组件也无法正常读取内容。
修正后的可运行核心代码
// 等待Cordova设备初始化完成后再执行录制逻辑 document.addEventListener('deviceready', () => { // 第一步:动态申请录音权限 cordova.plugins.diagnostic.requestRuntimePermission( cordova.plugins.diagnostic.permission.RECORD_AUDIO, (status) => { if (status !== cordova.plugins.diagnostic.permission.GRANTED) return; // 第二步:解析应用私有外部存储的真实路径 window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, (dirEntry) => { const fileName = `${new Date().getTime()}.m4a`; const fullRecordPath = dirEntry.nativeURL + fileName; // 初始化Media录制对象 const mediaRecorder = new Media( fullRecordPath, // 停止录制成功回调 () => { // 延迟300ms等待磁盘写入完成,再释放资源 setTimeout(() => { mediaRecorder.release(); // 转换webview可访问的音频路径 const playableUrl = window.WkWebView.convertFilePath(fullRecordPath); // 插入可播放的音频组件 const audioDom = `<div><audio controls controlsList="nodownload"><source src="${playableUrl}" type="audio/mp4"></audio></div>`; document.execCommand('insertHTML', false, audioDom); }, 300); }, // 录制错误回调 (error) => { mediaRecorder.release(); console.log('录制异常信息:', error); } ); // 开始录音 mediaRecorder.startRecord(); // 5秒后自动停止录音 setTimeout(() => { mediaRecorder.stopRecord(); }, 5000); }); } ); });
常见排查注意点
- 录制时长不要过短(比如小于1秒),系统MediaRecorder需要时间积累音频缓冲区数据,过短的录制会因为没有采集到有效音频生成空文件
- 不要在录制过程中频繁调用对象的状态切换方法,容易导致插件内部的录制流程异常
- 如果还是出现0字节文件,可以通过Android的日志工具过滤
MediaRecorder关键字,查看系统返回的实际错误码,定位是编码问题还是权限问题
内容的提问来源于stack exchange,提问作者Alvin Stefanus
相关产品推荐
相关产品推荐

