1. ホーム
  2. アンドロイド

Androidでの録音とMP3へのローカルトランスコード

2022-02-09 07:11:30
<パス

**

ローカルトランスコードによるAndroid録画

**
Android携帯電話による録音。
録画後、トランスコード操作にlameを使用する。

これは開発時に必要なもので、単純にトランスコードするためのツールで、以下のようなコード情報があります。
プロジェクトの基本構造

1. ツールキットのダウンロード
ダウンロード ラームツールキット
使用した最新バージョン
NDK環境のインストール

2. ダサいコンテンツコピー
まず、src/main/ ディレクトリに新しい cpp フォルダを作成し、Lame のソースコードから libmp3lame を cpp フォルダにコピーしてください。
Lameソースコードのincludeフォルダにあるlame.hをlamemp3フォルダにコピーします。
lamemp3内の不要なファイルやディレクトリを削除する。.rc/am/inファイルは削除してもよい。Androidはここでは使用せず、.cと.hファイルのみを残す。
util.hのソースコードを修正します。ieee754_float32_tはLinuxやUnixではサポートされているが、Androidではサポートされていないデータ型なので、570行目のieee754_float32_tを探し、floatに変更する。
24行目の set_get.h の include<lame.h> を include"lame.h" に置き換える。
id3tag.c と machine.h ファイルで、HAVE_STRCHR と HAVE_MEMCPY の ifdef 構造体をコメントアウトすると、コンパイル時にエラーになります。

3. build.gradleの設定
Androidstudioが最新に更新されたため

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" //set cpp configuration parameters, c files please use CFlags
                abiFilters 'armeabi-v7a', "armeabi"
            }
        }
        ndk{
            abiFilters 'armeabi-v7a', "armeabi"
        }
    }
    sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }


cmakeで最新のNDKをダウンロードした場合、以下のようなエラーが発生します。

abis [mips64, armeabi, mips] are not supported for platform. <対応
abisは[armeabi-v7a, arm64-v8a, x86, x86_64]です。

解決策は、gradle の cmake abiFilters 設定を次のように変更します:abiFilters 'x86', 'x86_64', 'arm64-v8a ', 'armeabi-v7a'.
Google NDK r18の説明です。ARMv5 (armeabi)、MIPS、および MIPS64 のサポートが削除されました。これらのABIのいずれかをビルドしようとすると、エラーが発生します。
私のabiFiltersは、ここでは2つだけです。

4. JavaネイティブメソッドMP3Converterの作成

public class MP3Converter {
    static {
        System.loadLibrary("lame-mp3-utils");// make sure to write the right name here
    }
    // test the lame environment is installed successfully
    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
     */@return
    public native static long getConvertBytes();
}


5. C/C++を呼び出すcppを書く
この直接の使用は、Baiduの上にある、読むことができるように限定され、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 specify 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_ca

6. を呼び出すことが残っています。

/**
     * Start recording
     * @param mFlag
     */
    public void recode(int mFlag){
        if(mState ! = -1){
            Log.e(mState+"1", "mState: "+mState );
            Message msg = new Message();
            Bundle b = new Bundle();// store data
            b.putInt("cmd",CMD_RECORDFAIL);
            b.putInt("msg", ErrorCode.E_STATE_RECODING);
            msg.setData(b);
            uiHandler.sendMessage(msg); // send message to Handler, update 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();// store data
            b.putInt("cmd",CMD_RECORDFAIL);
            b.putInt("msg", mResult);
            msg.setData(b);
            uiHandler.sendMessage(msg); // send message to Handler, update UI
        }
    }


発生した可能性のある問題

rg.gradle.api.internal.tasks.compile.CompilationFailedException:
コンパイルに失敗しました。

コンパイルに失敗しました。詳細はコンパイラのエラー出力をご覧ください。

解決プロセス
端末入力
gradlew compileDebugSourcesを実行します。
エラーメッセージの表示

コードダウンロード先
テストMp3

参考記事
Android NDKを使用したMP3トランスコードライブラリの実装方法を紹介
Android NDKの開発(VI) - オープンソースLAMEを使ったmp3のトランスコーディング

アプリケーションのインターフェースは以下の通りです。