Android应用FFmpeg剪切音频保存到外部存储后无法读取如何解决
解决方案
核心原因
通过FFmpeg生成MP3文件后,系统媒体库(MediaStore)不会自动识别新增的媒体文件,你当前读取音频的逻辑是从MediaStore中拉取数据,自然查不到还没录入索引的新剪切文件。另外你的FFmpeg剪切音频的参数存在冗余错误,也可能导致生成的文件无法被媒体库正确识别。
调整步骤
- 主动触发媒体库扫描新文件
在execffmpegBinary的成功回调(returnCode == RETURN_CODE_SUCCESS)中添加以下代码,通知系统扫描你刚生成的MP3文件:
如果你的应用targetSdkVersion >= 29,建议将生成的MP3文件保存到系统公共的Music目录下,不要在根目录自定义独立文件夹,避免分区存储限制导致媒体库无法扫描。// 通知媒体库更新单个文件索引 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri contentUri = Uri.fromFile(dest); mediaScanIntent.setData(contentUri); getActivity().sendBroadcast(mediaScanIntent); } else { getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); } - 优化FFmpeg剪切音频的参数
你当前的命令添加了不必要的视频编码参数,剪切纯音频不需要保留视频轨道,修改命令如下,避免生成的文件封装异常:command = new String[]{ "-ss", "" + startMs / 1000, "-y", "-i", original_path, "-t", "" + (endMs - startMs) / 1000, "-vn", // 丢弃视频轨道 "-acodec", "libmp3lame", // 指定MP3音频编码器 "-b:a", "128k", // 音频比特率可根据需求调整 "-ac", "2", "-ar", "44100", filePath }; - 优化音频读取逻辑
你当前读取音频的代码中直接用MediaPlayer.create获取时长,没有释放MediaPlayer资源,会导致内存泄漏,也可能影响文件读取,直接从MediaStore的查询结果中读取时长即可,不需要单独创建MediaPlayer:// 修改查询的projection,添加时长字段 String[] projection = { MediaStore.Audio.AudioColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM, MediaStore.Audio.ArtistColumns.ARTIST, MediaStore.Audio.AudioColumns.DURATION }; // 遍历cursor时直接取对应的时长字段 long duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DURATION)); - 权限检查
确认你的应用已经申请了对应存储权限:Android 12及以下版本需要申请READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限,Android 13及以上版本需要申请READ_MEDIA_AUDIO权限,否则无法读取公共目录的音频文件。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

