You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
scrcpy/server/src/main/java/com/genymobile/scrcpy/ScreenStreamerSession.java

74 lines
2.5 KiB
Java

package com.genymobile.scrcpy;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class ScreenStreamerSession {
private final Device device;
private final DesktopConnection connection;
private Process screenRecordProcess; // protected by 'this'
private final AtomicBoolean stopped = new AtomicBoolean();
private final byte[] buffer = new byte[0x10000];
public ScreenStreamerSession(Device device, DesktopConnection connection) {
this.device = device;
this.connection = connection;
}
public void streamScreen() throws IOException {
// screenrecord may not record more than 3 minutes, so restart it on EOF
while (!stopped.get() && streamScreenOnce()) ;
}
/**
* Starts screenrecord once and relay its output to the desktop connection.
*
* @return {@code true} if EOF is reached, {@code false} otherwise (i.e. requested to stop).
* @throws IOException if an I/O error occurred
*/
private boolean streamScreenOnce() throws IOException {
Ln.d("Recording...");
Size videoSize = device.getScreenInfo().getVideoSize();
Process process = startScreenRecord(videoSize);
setCurrentProcess(process);
InputStream inputStream = process.getInputStream();
int r;
while ((r = inputStream.read(buffer)) != -1 && !stopped.get()) {
connection.sendVideoStream(buffer, r);
}
return r != -1;
}
public void stop() {
// let the thread stop itself without breaking the video stream
stopped.set(true);
killCurrentProcess();
}
private static Process startScreenRecord(Size videoSize) throws IOException {
List<String> command = new ArrayList<>();
command.add("screenrecord");
command.add("--output-format=h264");
command.add("--size=" + videoSize.getWidth() + "x" + videoSize.getHeight());
command.add("-");
Process process = new ProcessBuilder(command).start();
process.getOutputStream().close();
return process;
}
private synchronized void setCurrentProcess(Process screenRecordProcess) {
this.screenRecordProcess = screenRecordProcess;
}
private synchronized void killCurrentProcess() {
if (screenRecordProcess != null) {
screenRecordProcess.destroy();
screenRecordProcess = null;
}
}
}