Android錄音並進行本地轉碼爲MP3

**

Android錄音並進行本地轉碼

**
通過安卓手機進行錄音,
錄音後,使用lame進行轉碼操作

開發中需要使用這個功能,只是一個簡單的進行轉碼的工具,具體的代碼信息如下
項目的基本結構圖
項目的結構圖
1、下載工具包
下載lame工具包
使用的最新版本
安裝NDK環境
這裏寫圖片描述
這裏寫圖片描述

2、lame內容複製
首先在 src/main/目錄下新建一個 cpp文件夾,Lame源碼中 libmp3lame拷貝到 cpp文件夾下,可以重命名,例如我命名爲 lamemp3
將Lame源碼中的 include文件夾下的 lame.h複製到 lamemp3文件夾中
剔除 lamemp3中不必要的文件和目錄,.rc/am/in文件都可以刪除,Android這裏用不到,只保留 .c和 .h文件
修改 util.h的源碼。在570行找到 ieee754_float32_t數據類型,將其修改爲 float類型,因爲 ieee754_float32_t是Linux或者是Unix下支持的數據類型,在Android下並不支持。
set_get.h中24行將 include

defaultConfig {
        applicationId "com.example.gz.testmp3"
        minSdkVersion 23
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild{
            cmake{
                cppFlags "-frtti -fexceptions" //設置cpp配置參數,c文件請使用CFlags
                abiFilters 'armeabi-v7a', "armeabi"
            }
        }
        ndk{
            abiFilters 'armeabi-v7a',"armeabi"
        }
    }
    sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }

如果下載的是最新的NDK與cmake,報出了一下的錯誤,

abis [mips64, armeabi, mips] are not supported for platform. supported
abis are [armeabi-v7a, arm64-v8a, x86, x86_64].

解決辦法將gradle中cmake abiFilters配置改爲:abiFilters ‘x86’, ‘x86_64’,’arm64-v8a’, ‘armeabi-v7a’
Google NDK r18解釋: Support for ARMv5 (armeabi), MIPS, and MIPS64 has been removed. Attempting to build any of these ABIs will result in an error
我這裏的abiFilters 只寫了兩個

4、編寫Java native方法 MP3Converter

public class MP3Converter {
    static {
        System.loadLibrary("lame-mp3-utils");//這裏一定要寫對名稱
    }
    //測試lame環境是否安裝成功
    public static native String getLameVersion();
    /**
     * init lame
     * @param inSampleRate
     *              input sample rate in Hz
     * @param channel
     *              number of channels
     * @param mode
     *              0 = CBR, 1 = VBR, 2 = ABR.  default = 0
     * @param outSampleRate
     *              output sample rate in Hz
     * @param outBitRate
     *              rate compression ratio in KHz
     * @param quality
     *              quality=0..9. 0=best (very slow). 9=worst.<br />
     *              recommended:<br />
     *              2 near-best quality, not too slow<br />
     *              5 good quality, fast<br />
     *              7 ok quality, really fast
     */
    public native static void init(int inSampleRate, int channel, int mode,
                                   int outSampleRate, int outBitRate, int quality);
    /**
     * file convert to mp3
     * it may cost a lot of time and better put it in a thread
     * @param inputPath
     *          file path to be converted
     * @param mp3Path
     *          mp3 output file path
     */
    public native  static void convertMp3(String inputPath, String mp3Path);
    /**
     * get converted bytes in inputBuffer
     * @return
     *          converted bytes in inputBuffer
     *          to ignore the deviation of the file size,when return to -1 represents convert complete
     */
    public native static long getConvertBytes();
}```

**5、編寫調用C/C++的cpp**
這個直接使用的是百度上的,僅限於能看懂,對於c++不懂

extern “C”
JNIEXPORT void JNICALL
Java_jaygoo_library_converter_MP3Converter_convertMp3(JNIEnv * env, jobject obj, jstring jInputPath, jstring jMp3Path) {
const char* cInput = env->GetStringUTFChars(jInputPath, 0);
const char* cMp3 = env->GetStringUTFChars(jMp3Path, 0);
//open input file and output file
FILE* fInput = fopen(cInput,”rb”);
FILE* fMp3 = fopen(cMp3,”wb”);
short int inputBuffer[BUFFER_SIZE * 2];
unsigned char mp3Buffer[BUFFER_SIZE];//You must specified at least 7200
int read = 0; // number of bytes in inputBuffer, if in the end return 0
int write = 0;// number of bytes output in mp3buffer. can be 0
long total = 0; // the bytes of reading input file
nowConvertBytes = 0;
//if you don’t init lame, it will init lame use the default value
if(lame == NULL){
lameInit(44100, 2, 0, 44100, 96, 7);
}

//convert to mp3
do{
    read = static_cast<int>(fread(inputBuffer, sizeof(short int) * 2, BUFFER_SIZE, fInput));
    total +=  read * sizeof(short int)*2;
    nowConvertBytes = total;
    if(read != 0){
        write = lame_encode_buffer_interleaved(lame, inputBuffer, read, mp3Buffer, BUFFER_SIZE);
        //write the converted buffer to the file
        fwrite(mp3Buffer, sizeof(unsigned char), static_cast<size_t>(write), fMp3);
    }
    //if in the end flush
    if(read == 0){
        lame_encode_flush(lame,mp3Buffer, BUFFER_SIZE);
    }
}while(read != 0);

//release resources
resetLame();
fclose(fInput);
fclose(fMp3);
env->ReleaseStringUTFChars(jInputPath, cInput);
env->ReleaseStringUTFChars(jMp3Path, cMp3);
nowConvertBytes = -1;

}


**6、剩下就是調用了**

/**
* 開始錄音
* @param mFlag
*/
public void recode(int mFlag){
if(mState != -1){
Log.e(mState+”1”, “mState: “+mState );
Message msg = new Message();
Bundle b = new Bundle();// 存放數據
b.putInt(“cmd”,CMD_RECORDFAIL);
b.putInt(“msg”, ErrorCode.E_STATE_RECODING);
msg.setData(b);
uiHandler.sendMessage(msg); // 向Handler發送消息,更新UI
return;
}
int mResult = -1;
AudioRecorderWav mRecord_1 = AudioRecorderWav.getInstance();
mResult = mRecord_1.startRecordAndFile(MainActivity.this);
if(mResult == ErrorCode.SUCCESS){
mState = mFlag;
uiThread = new UIThread();
new Thread(uiThread).start();
}else{
Message msg = new Message();
Bundle b = new Bundle();// 存放數據
b.putInt(“cmd”,CMD_RECORDFAIL);
b.putInt(“msg”, mResult);
msg.setData(b);
uiHandler.sendMessage(msg); // 向Handler發送消息,更新UI
}
}
“`
可能遇到的問題:

rg.gradle.api.internal.tasks.compile.CompilationFailedException:
Compilation failed

Compilation failed; see the compiler error output for details.

解決過程
terminal 輸入
gradlew compileDebugSources
查看錯誤信息

代碼下載地址
TestMp3

參考文章:
教你如何使用Android NDK實現一個MP3轉碼庫
Android NDK開發(六)——使用開源LAME轉碼mp3

應用界面如下
首頁
開始錄音
停止錄音
轉碼結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章