mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-03 14:49:29 +00:00
Use a streamer to send the audio stream
Send each encoded audio packet using a streamer.
This commit is contained in:
parent
1355ed6b33
commit
0b19079386
4 changed files with 58 additions and 3 deletions
46
server/src/main/java/com/genymobile/scrcpy/AudioCodec.java
Normal file
46
server/src/main/java/com/genymobile/scrcpy/AudioCodec.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import android.media.MediaFormat;
|
||||||
|
|
||||||
|
public enum AudioCodec implements Codec {
|
||||||
|
OPUS(0x6f_70_75_73, "opus", MediaFormat.MIMETYPE_AUDIO_OPUS);
|
||||||
|
|
||||||
|
private final int id; // 4-byte ASCII representation of the name
|
||||||
|
private final String name;
|
||||||
|
private final String mimeType;
|
||||||
|
|
||||||
|
AudioCodec(int id, String name, String mimeType) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return Type.AUDIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AudioCodec findByName(String name) {
|
||||||
|
for (AudioCodec codec : values()) {
|
||||||
|
if (codec.name.equals(name)) {
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,8 @@ public final class AudioEncoder {
|
||||||
private static final int BUFFER_MS = 15; // milliseconds
|
private static final int BUFFER_MS = 15; // milliseconds
|
||||||
private static final int BUFFER_SIZE = SAMPLE_RATE * CHANNELS * BUFFER_MS / 1000;
|
private static final int BUFFER_SIZE = SAMPLE_RATE * CHANNELS * BUFFER_MS / 1000;
|
||||||
|
|
||||||
|
private final Streamer streamer;
|
||||||
|
|
||||||
private AudioRecord recorder;
|
private AudioRecord recorder;
|
||||||
private MediaCodec mediaCodec;
|
private MediaCodec mediaCodec;
|
||||||
|
|
||||||
|
@ -61,6 +63,10 @@ public final class AudioEncoder {
|
||||||
|
|
||||||
private boolean ended;
|
private boolean ended;
|
||||||
|
|
||||||
|
public AudioEncoder(Streamer streamer) {
|
||||||
|
this.streamer = streamer;
|
||||||
|
}
|
||||||
|
|
||||||
private static AudioFormat createAudioFormat() {
|
private static AudioFormat createAudioFormat() {
|
||||||
AudioFormat.Builder builder = new AudioFormat.Builder();
|
AudioFormat.Builder builder = new AudioFormat.Builder();
|
||||||
builder.setEncoding(AudioFormat.ENCODING_PCM_16BIT);
|
builder.setEncoding(AudioFormat.ENCODING_PCM_16BIT);
|
||||||
|
@ -138,11 +144,13 @@ public final class AudioEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputThread() throws IOException, InterruptedException {
|
private void outputThread() throws IOException, InterruptedException {
|
||||||
|
streamer.writeHeader();
|
||||||
|
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
OutputTask task = outputTasks.take();
|
OutputTask task = outputTasks.take();
|
||||||
ByteBuffer buffer = mediaCodec.getOutputBuffer(task.index);
|
ByteBuffer buffer = mediaCodec.getOutputBuffer(task.index);
|
||||||
try {
|
try {
|
||||||
Ln.i("Audio packet [pts=" + task.bufferInfo.presentationTimeUs + "] " + buffer.remaining() + " bytes");
|
streamer.writePacket(buffer, task.bufferInfo);
|
||||||
} finally {
|
} finally {
|
||||||
mediaCodec.releaseOutputBuffer(task.index, false);
|
mediaCodec.releaseOutputBuffer(task.index, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.genymobile.scrcpy;
|
||||||
|
|
||||||
public interface Codec {
|
public interface Codec {
|
||||||
|
|
||||||
enum Type {VIDEO}
|
enum Type {VIDEO, AUDIO}
|
||||||
|
|
||||||
Type getType();
|
Type getType();
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ public final class Server {
|
||||||
|
|
||||||
AudioEncoder audioEncoder = null;
|
AudioEncoder audioEncoder = null;
|
||||||
if (audio) {
|
if (audio) {
|
||||||
audioEncoder = new AudioEncoder();
|
Streamer audioStreamer = new Streamer(connection.getAudioFd(), AudioCodec.OPUS, options.getSendCodecId(), options.getSendFrameMeta());
|
||||||
|
audioEncoder = new AudioEncoder(audioStreamer);
|
||||||
audioEncoder.start();
|
audioEncoder.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue