切換語言為:簡體

投屏工具scrcpy導致Android裝置聲音播放問題

  • 爱糖宝
  • 2024-08-01
  • 2181
  • 0
  • 0

一、問題背景:

音樂播放器播放music,發現能夠播放但是沒有聲音,但是用tinyplay播放又有聲音。

二、問題分析:

無聲是必現的,抓取log分析,發現播放音訊時並沒有走primary module,而是走的r_submix module,這個無聲問題就能解釋通了,音訊流並沒有走到adsp。

07-24 11:59:21.285 1015 1859 I AudioFlinger: openOutput() this 0xb4000077f35ce9c0, module 26 Device AUDIO_DEVICE_OUT_REMOTE_SUBMIX, @:0, SamplingRate 48000, Format 0x000001, Channels 0x3, flags 0

07-24 11:59:21.286 907 930 D r_submix: adev_open_output_stream(address=0)

07-24 11:59:21.287 907 930 I r_submix: adev_open_output_stream(): about to create pipe at index 9, rate 48000, pipe size 4096

07-24 11:59:21.287 907 930 D r_submix: submix_audio_device_create_pipe_l(addr=0, idx=9)

07-24 11:59:21.287 907 930 D r_submix: now using address 0 for route 9

為什麼會走到AUDIO_DEVICE_OUT_REMOTE_SUBMIX這個裝置出去呢? 從官網上查詢到REMOTE_SUBMIX這個音訊型別,描述上看就是捕獲裝置音訊流投到遠端裝置上。

投屏工具scrcpy導致Android裝置聲音播放問題

參考官網:MediaRecorder.AudioSource  |  Android Developers (google.cn)

從log上看,確實有錄音動作,AUDIO_SOURCE_REMOTE_SUBMIX這個就是REMOTE_SUBMIX這個音源型別

7-24 11:59:21.235 1015 1015 V APM_AudioPolicyManager: getInputForAttr() source 8, sampling rate 48000, format 0x1, channel mask 0xc, session 225, flags 0 attributes={ Content type: AUDIO_CONTENT_TYPE_UNKNOWN Usage: AUDIO_USAGE_UNKNOWN Source: AUDIO_SOURCE_REMOTE_SUBMIX Flags: 0x800 Tags: } requested device ID 0

07-24 11:59:21.236 1015 1015 V APM_AudioPolicyManager: getInputForAttr found device type is 0x80000100

07-24 11:59:21.238 907 930 D r_submix: adev_open_input_stream(addr=0)

07-24 11:59:21.239 907 930 I r_submix: adev_open_input_stream(): about to create pipe at index 9, rate 48000, pipe size 4096

07-24 11:59:21.239 907 930 D r_submix: submix_audio_device_create_pipe_l(addr=0, idx=9)

07-24 11:59:21.240 907 930 D r_submix: now using address 0 for route 9

同測試溝通,瞭解到使用了scrcpy投屏工具,這就對上了

三、scrcpy音訊錄製分析:

下載scrcpy原始碼:github.com/Genymobile/…

原始碼中確實有錄音動作,AudioCapture.java中會建立AudioRecord scrcpy/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java

private static AudioRecord createAudioRecord(int audioSource) {
    AudioRecord.Builder builder = new AudioRecord.Builder();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        // On older APIs, Workarounds.fillAppInfo() must be called beforehand
        builder.setContext(FakeContext.get());
    }   
    builder.setAudioSource(audioSource);
    builder.setAudioFormat(createAudioFormat());
    int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, ENCODING);
    // This buffer size does not impact latency
    builder.setBufferSizeInBytes(8 * minBufferSize);
    return builder.build();
}


跟蹤audioSource來源,發現是MediaRecorder.AudioSource.REMOTE_SUBMIX這個音訊源,這個又對上了

Options.java

private AudioSource audioSource = AudioSource.OUTPUT;

AudioSource.java

OUTPUT("output", MediaRecorder.AudioSource.REMOTE_SUBMIX),

scrcpy錄製Android裝置音訊原理:原始碼中的java程式碼編譯打包到scrcpy-server,然後push到Android裝置,執行app_process執行scrcpy-server

四、總結:

scrcpy投屏工具將Android裝置音訊流錄製後投到PC端,PC端插上耳機後能聽到Android裝置播放的music

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.