【Android(安卓)FFMPEG 开发】Android(安卓)中使用 FFMPEG 对 MP3 文件进行混音操作
文章目录
- 一、前置操作 ( 移植 FFMPEG )
- 二、FFMPEG 混音命令
- 三、Android FFMPEG 混音源代码完整示例
- 四、博客源码
一、前置操作 ( 移植 FFMPEG )
参考 【Android FFMPEG 开发】Android 中执行 FFMPEG 指令 博客 ;
在应用的 build.gradle 构建脚本中导入如下依赖 ;
dependencies { implementation 'com.writingminds:FFmpegAndroid:0.3.2'}
然后按照 【Android FFMPEG 开发】Android 中执行 FFMPEG 指令 二、Android 中执行 FFMPEG 指令 中的流程进行开发 , 将拼接好的 FFMPEG 指令传入 ffmpeg.execute 方法 ;
二、FFMPEG 混音命令
FFMPEG 混音命令 :
ffmpeg -i 输入文件1 -i 输入文件2 -i 输入文件3 -filter_complex amix=inputs=输入文件个数:duration=混音时间对齐策略:dropout_transition=声音渐弱时间 输出文件
-i : 输入文件的完整绝对路径 ;
amix=inputs=2 : 表示混音文件个数 , 有 2 2 2 个文件进行混音 ;
duration=longest : 设置混音时间对齐策略 , longest 表示最长的音频文件持续时间 , shortest 表示最短输入的持续时间 , first 表示第一个文件的持续时间 ;
dropout_transition=2 : 表示输入流结束时 , 音量从满音量到 0 0 0 音量渐弱 2 2 2 秒消失 ;
Android 中的完整命令 :
-i /data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3 -i /data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3 -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 /data/user/0/com.example.ffmpeg_mix/files/Mix.mp3
第 1 1 1 个输入文件是 /data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3 ;
第 2 2 2 个输入文件是 /data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3 ;
amix=inputs=2 表示当前有 2 2 2 个输入文件 ;
duration=longest 表示混音时间是最长输入持续时间 ;
dropout_transition=2 表示输入流结束时 , 音量从满音量到 0 0 0 音量渐弱 2 2 2 秒消失 ;
最后混音的输出文件是 /data/user/0/com.example.ffmpeg_mix/files/Mix.mp3 ;
命令分行注释 :
-i /data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3 // 输入文件 1-i /data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3 // 输入文件 2-filter_complex amix=inputs=2:duration=longest:dropout_transition=2 // 混音参数/data/user/0/com.example.ffmpeg_mix/files/Mix.mp3 // 输出文件
三、Android FFMPEG 混音源代码完整示例
Android FFMPEG 混音源代码完整示例 :
package com.example.ffmpeg_miximport android.os.Bundleimport android.util.Logimport android.view.Viewimport android.widget.TextViewimport androidx.appcompat.app.AppCompatActivityimport com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandlerimport com.github.hiteshsondhi88.libffmpeg.FFmpegimport com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandlerimport java.io.Fileclass MainActivity : AppCompatActivity() { val TAG = "MainActivity" /** * 应用内置存储下的 files 目录 */ lateinit var mFilePath: String lateinit var ffmpeg: FFmpeg override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mFilePath = this.filesDir.toString() // 初始化 FFMPEG ffmpeg = FFmpeg.getInstance(this) // 加载 FFMPEG 可执行文件 ffmpeg.loadBinary(LoadBinaryResponseHandler()) } /** * 拷贝文件 */ fun copy(view: View) { CommandUtils.copyAssets2File( this, "BeardedGrain.mp3", "${mFilePath}/BeardedGrain.mp3") CommandUtils.copyAssets2File( this, "RainyDay.mp3", "${mFilePath}/RainyDay.mp3") showText() } /** * 执行混音命令 */ fun mix(view: View) { var cmd = "-i ${mFilePath}/BeardedGrain.mp3 -i ${mFilePath}/RainyDay.mp3 -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 ${mFilePath}/Mix.mp3" Log.i(TAG, "执行命令 : $cmd") var cmdArraay = cmd.split(" ").toTypedArray(); ffmpeg.execute(cmdArraay, object : ExecuteBinaryResponseHandler(){ override fun onStart() { super.onStart() Log.i(TAG, "onStart") } override fun onFinish() { super.onFinish() Log.i(TAG, "onStart") showText() } override fun onSuccess(message: String?) { super.onSuccess(message) Log.i(TAG, "onSuccess : $message") } override fun onProgress(message: String?) { super.onProgress(message) Log.i(TAG, "onProgress : $message") } override fun onFailure(message: String?) { super.onFailure(message) Log.i(TAG, "onFailure : $message") } }) } /** * 显示内置存储目录 */ fun showText(){ var fileString = "" var files = File(mFilePath).listFiles() files.forEach { fileString += "${it}\n" } findViewById<TextView>(R.id.text).text = fileString }}
执行结果 : 这是混音正确的输出内容 ;
执行命令 : -i /data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3 -i /data/user/0/com.example.ffmpeg_mix/files/RainonStartonProgress : ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developersonProgress : built with gcc 4.8 (GCC)onProgress : configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-androonProgress : libavutil 55. 17.103 / 55. 17.103onProgress : libavcodec 57. 24.102 / 57. 24.102onProgress : libavformat 57. 25.100 / 57. 25.100onProgress : libavdevice 57. 0.101 / 57. 0.101onProgress : libavfilter 6. 31.100 / 6. 31.100onProgress : libswscale 4. 0.100 / 4. 0.100onProgress : libswresample 2. 0.101 / 2. 0.101onProgress : libpostproc 54. 0.100 / 54. 0.100onProgress : [mp3 @ 0xe8230000] Skipping 0 bytes of junk at 51635.onProgress : [mjpeg @ 0xe80af400] Changing bps to 8onProgress : Input #0, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3':onProgress : Metadata:onProgress : encoder : Lavf57.83.100onProgress : album : 芒种onProgress : title : 芒种onProgress : artist : 步束onProgress : disc : 01onProgress : track : 1onProgress : Duration: 00:03:35.48, start: 0.025056, bitrate: 321 kb/sonProgress : Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/sonProgress : Metadata:onProgress : encoder : Lavc57.10onProgress : Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbonProgress : Metadata:onProgress : comment : Media (e.g. label side of CD)onProgress : [mp3 @ 0xe8230600] Skipping 0 bytes of junk at 18961.onProgress : [mjpeg @ 0xe80b0400] Changing bps to 8onProgress : Input #1, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3':onProgress : Metadata:onProgress : encoder : Lavf57.83.100onProgress : Duration: 00:04:25.85, start: 0.025056, bitrate: 320 kb/sonProgress : Stream #1:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/sonProgress : Metadata:onProgress : encoder : Lavc57.10onProgress : Stream #1:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbonProgress : Metadata:onProgress : comment : Media (e.g. label side of CD)onProgress : [swscaler @ 0xe7f21000] deprecated pixel format used, make sure you did set range correctlyonProgress : [swscaler @ 0xe7f21000] No accelerated colorspace conversion found from yuv420p to rgb24.onProgress : [mp3 @ 0xe8230c00] Frame rate very high for a muxer not efficiently supporting it.onProgress : Please consider specifying a lower framerate, a different muxer or -vsync 2onProgress : Output #0, mp3, to '/data/user/0/com.example.ffmpeg_mix/files/Mix.mp3':onProgress : Metadata:onProgress : Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp (default)onProgress : Metadata:onProgress : encoder : Lavc57.24.102 libmp3lameonProgress : Stream #0:1: Video: png, rgb24, 640x640 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbonProgress : Metadata:onProgress : comment : Media (e.g. label side of CD)onProgress : encoder : Lavc57.24.102 pngonProgress : Stream mapping:onProgress : Stream #0:0 (mp3) -> amix:input0 (graph 0)onProgress : Stream #1:0 (mp3) -> amix:input1 (graph 0)onProgress : amix (graph 0) -> Stream #0:0 (libmp3lame)onProgress : Stream #0:1 -> #0:1 (mjpeg (native) -> png (native))onProgress : Press [q] to stop, [?] for helponProgress : frame= 1 fps=0.0 q=0.0 size= 0kB time=00:00:00.00 bitrate= 870.5kbits/s speed=0.00213x onProgress : frame= 1 fps=0.0 q=0.0 size= 0kB time=00:03:31.41 bitrate= 0.0kbits/s speed=3.25x onProgress : frame= 1 fps=0.0 q=0.0 size= 0kB time=00:03:33.00 bitrate= 0.0kbits/s speed=3.25x onProgress : frame= 1 fps=0.0 q=0.0 size= 0kB time=00:03:34.57 bitrate= 0.0kbits/s speed=3.25x onProgress : Error while filtering: Out of memoryonProgress : frame= 1 fps=0.0 q=-0.0 Lsize= 3995kB time=00:03:35.45 bitrate= 151.9kbits/s speed=3.25x onProgress : video:628kB audio:3367kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.008727%onSuccess : ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.8 (GCC) configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-ffprobe --enable-gpl --enable-yasm --disable-doc --disable-shared --enable-static --pkg-config=/home/vagrant/SourceCode/ffmpeg-android/ffmpeg-pkg-config --prefix=/home/vagrant/SourceCode/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-libs='-lpng -lexpat -lm' --extra-cxxflags= libavutil 55. 17.103 / 55. 17.103 libavcodec 57. 24.102 / 57. 24.102 libavformat 57. 25.100 / 57. 25.100 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 31.100 / 6. 31.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.101 / 2. 0.101 libpostproc 54. 0.100 / 54. 0.100 [mp3 @ 0xe8230000] Skipping 0 bytes of junk at 51635. [mjpeg @ 0xe80af400] Changing bps to 8 Input #0, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3': Metadata: Duration: 00:03:35.48, start: 0.025056, bitrate: 321 kb/s Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s Metadata: encoder : Lavc57.10 Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbc Metadata: comment : Media (e.g. label side of CD) [mp3 @ 0xe8230600] Skipping 0 bytes of junk at 18961. [mjpeg @ 0xe80b0400] Changing bps to 8 Input #1, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3': Metadata: encoder : Lavf57.83.100 Duration: 00:04:25.85, start: 0.025056, bitrate: 320 kb/s Stream #1:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s Metadata: encoder : Lavc57.10 Stream #1:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbc Metadata: comment : Media (e.g. label side of CD) [swscaler @ 0xe7f21000] deprecated pixel format used, make sure you did set range correctly [swscaler @ 0xe7f21000] No accelerated colorspace conversion found from yuv420p to rgb24. [mp3 @ 0xe8230c00] Frame rate very high for a muxer not efficiently supporting it. Please consider specifying a lower framerate, a different muxer or -vsync 2 Output #0, mp3, to '/data/user/0/com.example.ffmpeg_mix/files/Mix.mp3': Metadata: Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp (default) Metadata: encoder : Lavc57.24.102 libmp3lame Stream #0:1: Video: png, rgb24, 640x640 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbc Metadata: comment : Media (e.g. label side of CD) encoder : Lavc57.24.102 png Stream mapping: Stream #0:0 (mp3) -> amix:input0 (graph 0) Stream #1:0 (mp3) -> amix:input1 (graph 0) amix (graph 0) -> Stream #0:0 (libmp3lame) Str2021-06-03 20:16:57.824 30155-30155/com.example.ffmpeg_mix I/MainActivity: onStart
文件内容 : ffmpeg 是可执行文件 , Mix.mp3 是由其余两个 mp3 文件混音而来的 ;
四、博客源码
博客源码 :
- GitHub : https://github.com/han1202012/FFMPEG_MIX
- CSDN : https://download.csdn.net/download/han1202012/19372874
更多相关文章
- Android(安卓)系统概要 ——《第一行代码 Android》
- Android导入项目时Android(安卓)jar包丢失的解决
- Android(安卓)EditText输入光标居于开头最开始位置
- Android(安卓)NDK 使用第一步,编译c文件,声明jni并调用。
- Android(安卓)文件系统及权限修改
- Android(安卓)Jni代码示例讲解
- android APK反编译入门
- Android中文件的读写
- Android(安卓)常用开发术语