androidが音楽を再生しているaudioオーディオストリームを切り取る(バックグラウンドでandroidオーディオストリームを取得)

4780 ワード

本文はプロジェクトの需要をして、android仮想機がオーディオを再生していることを取得して、それから切り取って、ファイルに保存して、取得したデータはPCMコードストリームで、ffplayを通じて再生することができて、プレーヤーは再生できなくて、取得したPCMコードストリームは復号後の原始データです.変更が必要なファイルはAudioTrackです.cpp,パス:ディレクトリの保存/android/frameworks/av/media/libmedia/
androidソースコードをコンパイルする必要があります.赤はコードを追加する必要があります.
ssize_t AudioTrack::write(const void* buffer, size_t userSize, bool blocking)
{
    //  write    mTransfer   TRANSFER_SYNC    timetrack
    if (mTransfer != TRANSFER_SYNC || mIsTimed) {
        return INVALID_OPERATION;
    }
//    flag     direct flag,   flag,   CBLK_UNDERRUN、CBLK_LOOP_CYCLE
    // CBLK_LOOP_FINAL、CBLK_BUFFER_END
    if (isDirect()) {
        AutoMutex lock(mLock);
        int32_t flags = android_atomic_and(
                            ~(CBLK_UNDERRUN | CBLK_LOOP_CYCLE | CBLK_LOOP_FINAL | CBLK_BUFFER_END),
                            &mCblk->mFlags);
        //     flag   CBLK_INVALID flag
        if (flags & CBLK_INVALID) {
            return DEAD_OBJECT;
        }
    }

    if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
        // Sanity-check: user is most-likely passing an error code, and it would
        // make the return value ambiguous (actualSize vs error).
        ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);
        return BAD_VALUE;
    }

    size_t written = 0;
    Buffer audioBuffer;    

    //      ,  userSize  
    while (userSize >= mFrameSize) {
        audioBuffer.frameCount = userSize / mFrameSize;
       //   buffer  ,blocking   true,    ClientProxy::kForever
        status_t err = obtainBuffer(&audioBuffer,
                blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
        //     
        if (err < 0) {
            //               ,   ,       
            if (written > 0) {
                break;
            }
            return ssize_t(err);
        }
        // audioBuffer.size             ,        ,    
        size_t toWrite = audioBuffer.size;
        memcpy(audioBuffer.i8, buffer, toWrite);//copy PCM data to audioflinger,    ,buffer     PCM  

        

// --------------------------------------------------------------------------------------------
        //test::write PCM data to file  
        FILE *fp;  
        if((fp=fopen("/data/audioBuffer.txt","a+"))==NULL) {  //a+             ,       
            ALOGE("failedopen (buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);   
        }  
        else {
            
            fwrite(buffer,toWrite,1, fp);
            
        } 
        fclose(fp);
// --------------------------------------------------------------------------------------------
        buffer = ((const char *) buffer) + toWrite;//             
        userSize -= toWrite;//      
        written += toWrite;//         
        releaseBuffer(&audioBuffer);//   audiobuffer 
    } 
    return written;
}

 
ソースのコンパイル:
source build/envsetup.sh
lunch 6
make-j 8注記:-j 8はコンピュータの構成に関係しています
コンパイルの完了を待ちます.次にadbコマンドでファイル転送を完了する必要があります.コマンドを入力:
emulator & 
次に、次の操作に分けます.
1.仮想マシンは一般的にsdcardがなく、自分でsdcardを作成する必要がある
自分のmksdcardコマンドがあるディレクトリを見つけて、/usr/share/adt-bundle-linux-x 86_64-20140702/sdk/tools
コマンド:./mksdcard -l mycard 100M/home/bruceking90/Documents/workplace/sdcard.img
次に、sdcard付き仮想マシンコマンドを起動します.
emulator -sdcard/home/bruceking90/Documents/workplace/sdcard.img &
2.仮想マシンはプレーヤーを持っていて音楽がなくて、何メートルの音楽を通じてダウンロードするか、あるいは他のルートを通じてmp 3音楽をダウンロードする必要があります.
コマンド:push/home/bruceking 90/downloads/prison_break.mp3/sdcard/Music
3.ubuntuの下に新しいファイルを作成し、データを書き込むためのファイルを準備し、下位の書き込みファイルと同じ名前のaudioBuffer.txt.
そしてファイルにデータを書き込むディレクトリの下にpush/data/audioBuffer.txt.
push/home/bruceking90/Downloads/audioBuffer.txt/data/
4.音楽付きプレーヤーを開き、伝わるmp 3を再生します.データはaudioBufferに書き込まれます.txt、コマンドでファイルを書き出し、接尾辞をmp 3に変更します.
pull/data/audioBuffer.txt push/home/bruceking90/Downloads/
mv audioBuffer.txt audioBuffer.mp 3(手動で変更可能)
5.オーディオデータの取得が正しいかどうかを確認する:オリジナルデータは一般的なオーディオ分析ソフトウェアによってサンプリングレートとチャネル数を得ることができる.このmp 3の元のサンプリングレート44 k、デュアルチャネル.
ffplay-f s 16 le-ar 44 k-ac 2/home/bruceking 90/downloads/audioBuffer.mp3
正常に再生できます.
コンプレックスで発生した問題:
1.再生できない場合は、ubuntuエンド起動仮想マシンディレクトリの下にadb logcatを入力し、再生失敗ログを表示します.android5.0以上、avc deniedの一部は権限が足りない
Androidディレクトリにコマンドを入力:adb shell
Androidメカニズムに入り、書き込みファイルの制限を変更し、コマンド:setenforce 0を入力します.
普通は正常に再生して、txtファイルにデータを書くことができます.
2.「&」はバックグラウンドで実行されることを示し、adbコマンドを現在の端末で使用するのに便利である.誤って端末をオフにすると、emulatorを入力しても反応せずに環境を再ロードする必要があります.
source build/envsetup.sh
lunch 6
仮想マシンemulator-sdcard/home/bruceking 90/documents/workplace/sdcardを再起動します.img &