【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 : 表示混音文件個數 , 有 222 個文件進行混音 ;
duration=longest : 設置混音時間對齊策略 , longest 表示最長的音頻文件持續時間 , shortest 表示最短輸入的持續時間 , first 表示第一個文件的持續時間 ;
dropout_transition=2 : 表示輸入流結束時 , 音量從滿音量到 000 音量漸弱 222 秒消失 ;
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第 111 個輸入文件是 /data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3 ;
第 222 個輸入文件是 /data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3 ;
amix=inputs=2 表示當前有 222 個輸入文件 ;
duration=longest 表示混音時間是最長輸入持續時間 ;
dropout_transition=2 表示輸入流結束時 , 音量從滿音量到 000 音量漸弱 222 秒消失 ;
最后混音的輸出文件是 /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.Bundle import android.util.Log import android.view.View import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler import com.github.hiteshsondhi88.libffmpeg.FFmpeg import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler import java.io.Fileclass MainActivity : AppCompatActivity() {val TAG = "MainActivity"/*** 應用內置存儲下的 files 目錄*/lateinit var mFilePath: Stringlateinit var ffmpeg: FFmpegoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)mFilePath = this.filesDir.toString()// 初始化 FFMPEGffmpeg = 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/Rain onStart onProgress : ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers onProgress : built with gcc 4.8 (GCC) onProgress : configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-andro onProgress : libavutil 55. 17.103 / 55. 17.103 onProgress : libavcodec 57. 24.102 / 57. 24.102 onProgress : libavformat 57. 25.100 / 57. 25.100 onProgress : libavdevice 57. 0.101 / 57. 0.101 onProgress : libavfilter 6. 31.100 / 6. 31.100 onProgress : libswscale 4. 0.100 / 4. 0.100 onProgress : libswresample 2. 0.101 / 2. 0.101 onProgress : libpostproc 54. 0.100 / 54. 0.100 onProgress : [mp3 @ 0xe8230000] Skipping 0 bytes of junk at 51635. onProgress : [mjpeg @ 0xe80af400] Changing bps to 8 onProgress : Input #0, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/BeardedGrain.mp3': onProgress : Metadata: onProgress : encoder : Lavf57.83.100 onProgress : album : 芒種 onProgress : title : 芒種 onProgress : artist : 步束 onProgress : disc : 01 onProgress : track : 1 onProgress : Duration: 00:03:35.48, start: 0.025056, bitrate: 321 kb/s onProgress : Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s onProgress : Metadata: onProgress : encoder : Lavc57.10 onProgress : Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tb onProgress : 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 8 onProgress : Input #1, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3': onProgress : Metadata: onProgress : encoder : Lavf57.83.100 onProgress : Duration: 00:04:25.85, start: 0.025056, bitrate: 320 kb/s onProgress : Stream #1:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s onProgress : Metadata: onProgress : encoder : Lavc57.10 onProgress : Stream #1:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tb onProgress : Metadata: onProgress : comment : Media (e.g. label side of CD) onProgress : [swscaler @ 0xe7f21000] deprecated pixel format used, make sure you did set range correctly onProgress : [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 2 onProgress : 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 libmp3lame onProgress : Stream #0:1: Video: png, rgb24, 640x640 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tb onProgress : Metadata: onProgress : comment : Media (e.g. label side of CD) onProgress : encoder : Lavc57.24.102 png onProgress : 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 help onProgress : 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 memory onProgress : 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 developersbuilt 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.103libavcodec 57. 24.102 / 57. 24.102libavformat 57. 25.100 / 57. 25.100libavdevice 57. 0.101 / 57. 0.101libavfilter 6. 31.100 / 6. 31.100libswscale 4. 0.100 / 4. 0.100libswresample 2. 0.101 / 2. 0.101libpostproc 54. 0.100 / 54. 0.100[mp3 @ 0xe8230000] Skipping 0 bytes of junk at 51635.[mjpeg @ 0xe80af400] Changing bps to 8Input #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/sStream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/sMetadata:encoder : Lavc57.10Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbcMetadata:comment : Media (e.g. label side of CD)[mp3 @ 0xe8230600] Skipping 0 bytes of junk at 18961.[mjpeg @ 0xe80b0400] Changing bps to 8Input #1, mp3, from '/data/user/0/com.example.ffmpeg_mix/files/RainyDay.mp3':Metadata:encoder : Lavf57.83.100Duration: 00:04:25.85, start: 0.025056, bitrate: 320 kb/sStream #1:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/sMetadata:encoder : Lavc57.10Stream #1:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbcMetadata: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 2Output #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 libmp3lameStream #0:1: Video: png, rgb24, 640x640 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbcMetadata:comment : Media (e.g. label side of CD)encoder : Lavc57.24.102 pngStream mapping:Stream #0:0 (mp3) -> amix:input0 (graph 0)Stream #1:0 (mp3) -> amix:input1 (graph 0)amix (graph 0) -> Stream #0:0 (libmp3lame)Str 2021-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 FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 插件化】“ 插桩式 “
- 下一篇: 【Android 插件化】“ 插桩式 “