scrcpy icon indicating copy to clipboard operation
scrcpy copied to clipboard

Audio from phone is forwarded but no longer plays from phone when connected

Open Justanoviceuser opened this issue 2 years ago • 8 comments

Hello, I'm new to to scrcpy and coding in general so I apologize if this question causes you any inconvenience. As the title suggests, scrcpy (2.0 - win64 build) runs fine, but mutes all audio from my phone when running, i.e. plays it only from the computer. When I shut down scrcpy, it plays audio just fine. I always open the app through the "open a terminal here" and my parameters are as follows: scrcpy -b 4M --max-fps 60 -m 1280 I can't seem to find a list of commands/parameters to control the app anywhere I look that explains it in simple enough terms for me to follow. I'll appreciate any advice you can offer. Thanks for reading.

Justanoviceuser avatar Apr 04 '23 16:04 Justanoviceuser

https://github.com/Genymobile/scrcpy/blob/master/doc/audio.md scrcpy --no-audio

jjit avatar Apr 04 '23 16:04 jjit

When audio is captured, it is disabled on the device. See #3875.

So the only way to keep the audio on the device is to disable audio forwarding:

scrcpy --no-audio

rom1v avatar Apr 04 '23 16:04 rom1v

Thanks for the replies. Just to clarify, if I do want the audio to play on both, will I have to resort to using sndcpy (a second programme)?

Justanoviceuser avatar Apr 04 '23 18:04 Justanoviceuser

Currently, I have no technical solution to both capture and play on the device.

rom1v avatar Apr 04 '23 19:04 rom1v

Regards, a question and if I have it without audio and I want to turn the volume up and down... is it possible? since when I add the no audio command the volume bar no longer appears

MMMDbot avatar Apr 06 '23 21:04 MMMDbot

MOD+ and MOD+ (shortcuts)

rom1v avatar Apr 07 '23 06:04 rom1v

Since some audio is not captured, I think we can playback what we just recorded to emulate mirroring (instead of forwarding). I made up a quick test and this works:

diff --git a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
index c940db16..56ff81a8 100644
--- a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
+++ b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
@@ -6,9 +6,11 @@ import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioRecord;
 import android.media.AudioTimestamp;
+import android.media.AudioTrack;
 import android.media.MediaCodec;
 import android.media.MediaRecorder;
 import android.os.Build;
@@ -25,6 +27,7 @@ public final class AudioCapture {
     public static final int BYTES_PER_SAMPLE = 2;
 
     private AudioRecord recorder;
+    private AudioTrack track;
 
     private final AudioTimestamp timestamp = new AudioTimestamp();
     private long previousPts = 0;
@@ -112,6 +115,16 @@ public final class AudioCapture {
         } else {
             startRecording();
         }
+
+        AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder();
+        attributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION);
+        AudioTrack.Builder trackBuilder = new AudioTrack.Builder();
+        trackBuilder.setAudioAttributes(attributesBuilder.build());
+        trackBuilder.setAudioFormat(createAudioFormat());
+        trackBuilder.setTransferMode(AudioTrack.MODE_STREAM);
+        track = trackBuilder.build();
+        track.play();
     }
 
     public void stop() {
@@ -128,6 +141,10 @@ public final class AudioCapture {
             return r;
         }
 
+        int position = directBuffer.position();
+        track.write(directBuffer, size, AudioTrack.WRITE_BLOCKING);
+        directBuffer.position(position);
+
         long pts;
 
         int ret = recorder.getTimestamp(timestamp, AudioTimestamp.TIMEBASE_MONOTONIC);

EDIT: It's not perfect. The capture volume is controlled by media volume (#3790), and the playback volume is controlled by notification volume, so it can be quieter than normal.

yume-chan avatar Apr 09 '23 07:04 yume-chan

Hi, please yo can shared the finish verison of this code of the file AudioCapture.java? I compiled and tried adjust de code but not work. thanks!

pigogames avatar Apr 18 '23 06:04 pigogames

Since some audio is not captured, I think we can playback what we just recorded to emulate mirroring (instead of forwarding). I made up a quick test and this works:

diff --git a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
index c940db16..56ff81a8 100644
--- a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
+++ b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java
@@ -6,9 +6,11 @@ import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioRecord;
 import android.media.AudioTimestamp;
+import android.media.AudioTrack;
 import android.media.MediaCodec;
 import android.media.MediaRecorder;
 import android.os.Build;
@@ -25,6 +27,7 @@ public final class AudioCapture {
     public static final int BYTES_PER_SAMPLE = 2;
 
     private AudioRecord recorder;
+    private AudioTrack track;
 
     private final AudioTimestamp timestamp = new AudioTimestamp();
     private long previousPts = 0;
@@ -112,6 +115,16 @@ public final class AudioCapture {
         } else {
             startRecording();
         }
+
+        AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder();
+        attributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION);
+        AudioTrack.Builder trackBuilder = new AudioTrack.Builder();
+        trackBuilder.setAudioAttributes(attributesBuilder.build());
+        trackBuilder.setAudioFormat(createAudioFormat());
+        trackBuilder.setTransferMode(AudioTrack.MODE_STREAM);
+        track = trackBuilder.build();
+        track.play();
     }
 
     public void stop() {
@@ -128,6 +141,10 @@ public final class AudioCapture {
             return r;
         }
 
+        int position = directBuffer.position();
+        track.write(directBuffer, size, AudioTrack.WRITE_BLOCKING);
+        directBuffer.position(position);
+
         long pts;
 
         int ret = recorder.getTimestamp(timestamp, AudioTimestamp.TIMEBASE_MONOTONIC);

EDIT: It's not perfect. The capture volume is controlled by media volume (#3790), and the playback volume is controlled by notification volume, so it can be quieter than normal.

Great idea! I figured mirroring would be possible.

Does it introduce a lot of latency? I was excited about scrcpy now being able to forward sound to stream my mobile rhythm games, but the sound on PC is just too late (even if it's like 200-500ms and looks in sync with the phone on most apps, it's still way too much to play a rhythm game 😅). I assume most of the latency comes from the video encoding-decoding, not from the capture itself, but I can't be too sure.

Cyxo avatar Jun 03 '23 12:06 Cyxo

but the sound on PC is just too late (even if it's like 200-500ms …)

It should not be that high, more like 50~60ms (unless you use a bluetooth headset on your computer).

rom1v avatar Jun 03 '23 13:06 rom1v

I used a wired headset on my computer but I know it still adds some latency. However I made a small app that plays a repetitive sound to tap to and test the latency. With the phone's audio I had about 200ms latency, but through scrcpy it climbed up to 400ms.

However, like I said, in most cases even a 400ms latency isn't really noticeable. But I'm still looking forward for the audio mirroring if you make this a feature!

Cyxo avatar Jun 04 '23 23:06 Cyxo

+1 for the ability to hear the sound both on the Android device and the receiving computer from my side!

ludzeller avatar Jul 07 '23 07:07 ludzeller

I also need to hear audio in both, my computer and my android device!! Isn't that possible somehow? Thanks

Gamusok avatar Jul 31 '23 15:07 Gamusok

I hope developers can make a huge breakthrough in the audio mirroring function! If the audio mirroring feature is released, I will not hesitate to donate it to support developers!

bombshit avatar Sep 10 '23 13:09 bombshit

Please test #5102.

Closing as duplicate of #3875.

rom1v avatar Jul 16 '24 19:07 rom1v