Android FFMPEG 开发Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android FFMPEG 开发Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式相关的知识,希望对你有一定的参考价值。





一、前置操作 ( 移植 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 将 PCM 采样转为 MP3 格式的命令



FFMPEG 将 PCM 采样转为 MP3 格式的命令 :

ffmpeg -y -f 采样格式 -ac 声道数 -ar 采样率 -acodec pcm_s16le -i PCM源文件 MP3目标文件

-y : 表示允许覆盖 ;

-f : 表示文件格式 , 一般是 s16le , 其中 s 表示样本是有符号整型 , 16 表示是 16 16 16 位样本 2 2 2 字节 , l 表示小端格式 , 如果是 b 则表示大端格式 ; s16le 表示 无符号 16 16 16 位整型小端格式排列 ;

-ac : 声道个数 , 单声道设置 1 1 1 , 立体声设置 2 2 2 ;

-ar : 采样率 , 48000 48000 48000 表示 48000 Hz 采样率 ;

-acodec : 指定编码器 ;

-i : 指定源文件 ;

最后跟着是转换完成的 MP3 文件路径 ;


Android 中的完整命令 :

ffmpeg -y -f s16be -ac 2 -ar 48000 -acodec pcm_s16le -i /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3

PCM 格式文件 : /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm

MP3 格式文件 : /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3

将 /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm 文件转为 /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3 文件 ;

-y : 允许覆盖 ;

-f s16be : PCM 样本格式是 16 位无符号整型 , 小端格式存储 ;

-ac 2 : PCM 样本是立体声的 ;

-ar 48000 : PCM 样本采样率是 48000 ;

-i /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm : 输入文件是 /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm ;

输出文件是 /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3


命令分行注释 :

ffmpeg // 可执行文件
-y // 允许覆盖
-f s16be // PCM 样本格式是 16 位无符号整型 , 小端格式存储
-ac 2 // 立体声
-ar 48000 // 48000 Hz 采样率
-acodec pcm_s16le // 指定编码器
-i /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm // 输入 PCM 文件
/data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3 // 输出 MP3 文件




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



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

package com.example.ffmpeg_pcm_2_mp3

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) {
        // 将 assets 中的 audio.pcm 拷贝到内置存储中
        CommandUtils.copyAssets2File(
            this,
            "audio.pcm",
            "${mFilePath}/audio.pcm")

        showText()
    }

    /**
     * 执行混音命令
     */
    fun mix(view: View) {
        var cmd = "-y -f s16be -ac 2 -ar 48000 -acodec pcm_s16le -i ${mFilePath}/audio.pcm ${mFilePath}/audio.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
    }
}

执行结果 : 这是格式转换正确的输出内容 ;

2021-06-03 21:08:16.827 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: 执行命令 : -y -f s16be -ac 2 -ar 48000 -acodec pcm_s16le -i /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm /data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3
2021-06-03 21:08:16.841 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onStart
2021-06-03 21:08:16.853 4081-4164/com.example.ffmpeg_pcm_2_mp3 D/FFmpeg: Running publishing updates method
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   built with gcc 4.8 (GCC)
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   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=
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libavutil      55. 17.103 / 55. 17.103
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libavcodec     57. 24.102 / 57. 24.102
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libavformat    57. 25.100 / 57. 25.100
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libavdevice    57.  0.101 / 57.  0.101
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libavfilter     6. 31.100 /  6. 31.100
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libswscale      4.  0.100 /  4.  0.100
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libswresample   2.  0.101 /  2.  0.101
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   libpostproc    54.  0.100 / 54.  0.100
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : [s16be @ 0xea1a7000] Estimating duration from bitrate, this may be inaccurate
2021-06-03 21:08:16.867 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : Guessed Channel Layout for  Input Stream #0.0 : stereo
2021-06-03 21:08:16.868 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : Input #0, s16be, from '/data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.pcm':
2021-06-03 21:08:16.868 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   Duration: 00:00:06.41, bitrate: 1536 kb/s
2021-06-03 21:08:16.868 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :     Stream #0:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : Output #0, mp3, to '/data/user/0/com.example.ffmpeg_pcm_2_mp3/files/audio.mp3':
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   Metadata:
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :     TSSE            : Lavf57.25.100
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :     Stream #0:0: Audio: mp3 (libmp3lame), 48000 Hz, stereo, s16p
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :     Metadata:
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :       encoder         : Lavc57.24.102 libmp3lame
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : Stream mapping:
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress :   Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
2021-06-03 21:08:16.878 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : Press [q] to stop, [?] for help
2021-06-03 21:08:17.381 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : size=      81kB time=00:00:05.16 bitrate= 128.9kbits/s speed=10.3x    
2021-06-03 21:08:17.494 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : size=     101kB time=00:00:06.40 bitrate= 128.8kbits/s speed=10.4x    
2021-06-03 21:08:17.494 4081-4081/com.example.ffmpeg_pcm_2_mp3 I/MainActivity: onProgress : video:0kB audio:100kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.230294%
2021-06-03 21:08:17.498 4081-4081/

以上是关于Android FFMPEG 开发Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式的主要内容,如果未能解决你的问题,请参考以下文章

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

Android FFMPEG 开发Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式

Android FFMPEG 开发Android 中执行 FFMPEG 指令 ( mobile-ffmpeg 开源项目介绍 | 集成 mobile-ffmpeg 框架 )

Android FFMPEG 开发Android 中执行 FFMPEG 指令 ( 集成 mobile-ffmpeg 框架 | 完整代码示例 )

Android NDK开发之旅38--FFmpeg视频添加水印

Android NDK开发之FFmpeg视频添加水印