【Android FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作

举报
韩曙亮 发表于 2022/01/11 00:07:09 2022/01/11
【摘要】 文章目录 一、前置操作 ( 移植 FFMPEG )二、FFMPEG 混音命令三、Android FFMPEG 混音源代码完整示例四、博客源码 一、前置操作 ( 移植 FFMP...





一、前置操作 ( 移植 FFMPEG )



参考 【Android FFMPEG 开发】Android 中执行 FFMPEG 指令 博客 ;

在应用的 build.gradle 构建脚本中导入如下依赖 ;

dependencies {
	implementation 'com.writingminds:FFmpegAndroid:0.3.2'
}

  
 
  • 1
  • 2
  • 3

然后按照 【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=声音渐弱时间 输出文件

  
 
  • 1

-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 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 // 输出文件

  
 
  • 1
  • 2
  • 3
  • 4




三、Android FFMPEG 混音源代码完整示例



Android FFMPEG 混音源代码完整示例 :

package com.example.ffmpeg_mix

import 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.File

class 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
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103

执行结果 : 这是混音正确的输出内容 ;

执行命令 : -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 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)
      Str
2021-06-03 20:16:57.824 30155-30155/com.example.ffmpeg_mix I/MainActivity: onStart

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

文件内容 : ffmpeg 是可执行文件 , Mix.mp3 是由其余两个 mp3 文件混音而来的 ;

在这里插入图片描述





四、博客源码



博客源码 :

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/117526698

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。