Merge branch 'master' of gitlab.futo.org:videostreaming/grayjay

This commit is contained in:
Kelvin 2024-03-19 20:41:56 +01:00
commit 40b86cb5de
3 changed files with 46 additions and 34 deletions

View file

@ -163,24 +163,25 @@ class AirPlayCastingDevice : CastingDevice {
} }
connectionState = CastConnectionState.CONNECTED; connectionState = CastConnectionState.CONNECTED;
delay(1000);
val progressIndex = progressInfo.lowercase().indexOf("position: "); val progressIndex = progressInfo.lowercase().indexOf("position: ");
if (progressIndex == -1) { if (progressIndex == -1) {
delay(1000);
continue; continue;
} }
val progress = progressInfo.substring(progressIndex + "position: ".length).toDoubleOrNull() ?: continue; val progress = progressInfo.substring(progressIndex + "position: ".length).toDoubleOrNull() ?: continue;
setTime(progress); setTime(progress);
val durationIndex = progressInfo.lowercase().indexOf("duration: "); val durationIndex = progressInfo.lowercase().indexOf("duration: ");
if (durationIndex == -1) { if (durationIndex == -1) {
delay(1000);
continue; continue;
} }
val duration = progressInfo.substring(durationIndex + "duration: ".length).toDoubleOrNull() ?: continue; val duration = progressInfo.substring(durationIndex + "duration: ".length).toDoubleOrNull() ?: continue;
setDuration(duration); setDuration(duration);
delay(1000);
} catch (e: Throwable) { } catch (e: Throwable) {
Logger.w(TAG, "Failed to get server info from AirPlay device.", e) Logger.w(TAG, "Failed to get server info from AirPlay device.", e)
} }

View file

@ -44,7 +44,9 @@ class ChromecastCastingDevice : CastingDevice {
private var _socket: SSLSocket? = null; private var _socket: SSLSocket? = null;
private var _outputStream: DataOutputStream? = null; private var _outputStream: DataOutputStream? = null;
private var _outputStreamLock = Object();
private var _inputStream: DataInputStream? = null; private var _inputStream: DataInputStream? = null;
private var _inputStreamLock = Object();
private var _scopeIO: CoroutineScope? = null; private var _scopeIO: CoroutineScope? = null;
private var _requestId = 1; private var _requestId = 1;
private var _started: Boolean = false; private var _started: Boolean = false;
@ -383,39 +385,44 @@ class ChromecastCastingDevice : CastingDevice {
getStatus(); getStatus();
val buffer = ByteArray(4096); val buffer = ByteArray(409600);
Logger.i(TAG, "Started receiving."); Logger.i(TAG, "Started receiving.");
while (_scopeIO?.isActive == true) { while (_scopeIO?.isActive == true) {
try { try {
val inputStream = _inputStream ?: break; val inputStream = _inputStream ?: break;
Log.d(TAG, "Receiving next packet...");
val b1 = inputStream.readUnsignedByte();
val b2 = inputStream.readUnsignedByte();
val b3 = inputStream.readUnsignedByte();
val b4 = inputStream.readUnsignedByte();
val size = ((b1.toLong() shl 24) or (b2.toLong() shl 16) or (b3.toLong() shl 8) or b4.toLong()).toInt();
if (size > buffer.size) {
Logger.w(TAG, "Skipping packet that is too large $size bytes.")
inputStream.skip(size.toLong());
continue;
}
Log.d(TAG, "Received header indicating $size bytes. Waiting for message."); synchronized(_inputStreamLock)
inputStream.read(buffer, 0, size); {
Log.d(TAG, "Receiving next packet...");
val b1 = inputStream.readUnsignedByte();
val b2 = inputStream.readUnsignedByte();
val b3 = inputStream.readUnsignedByte();
val b4 = inputStream.readUnsignedByte();
val size =
((b1.toLong() shl 24) or (b2.toLong() shl 16) or (b3.toLong() shl 8) or b4.toLong()).toInt();
if (size > buffer.size) {
Logger.w(TAG, "Skipping packet that is too large $size bytes.")
inputStream.skip(size.toLong());
return@synchronized
}
//TODO: In the future perhaps this size-1 will cause issues, why is there a 0 on the end? Log.d(TAG, "Received header indicating $size bytes. Waiting for message.");
val messageBytes = buffer.sliceArray(IntRange(0, size - 1)); inputStream.read(buffer, 0, size);
Log.d(TAG, "Received $size bytes: ${messageBytes.toHexString()}.");
val message = ChromeCast.CastMessage.parseFrom(messageBytes);
if (message.namespace != "urn:x-cast:com.google.cast.tp.heartbeat") {
Logger.i(TAG, "Received message: $message");
}
try { //TODO: In the future perhaps this size-1 will cause issues, why is there a 0 on the end?
handleMessage(message); val messageBytes = buffer.sliceArray(IntRange(0, size - 1));
} catch (e:Throwable) { Log.d(TAG, "Received $size bytes: ${messageBytes.toHexString()}.");
Logger.w(TAG, "Failed to handle message.", e); val message = ChromeCast.CastMessage.parseFrom(messageBytes);
if (message.namespace != "urn:x-cast:com.google.cast.tp.heartbeat") {
Logger.i(TAG, "Received message: $message");
}
try {
handleMessage(message);
} catch (e: Throwable) {
Logger.w(TAG, "Failed to handle message.", e);
}
} }
} catch (e: java.net.SocketException) { } catch (e: java.net.SocketException) {
Logger.e(TAG, "Socket exception while receiving.", e); Logger.e(TAG, "Socket exception while receiving.", e);
@ -588,13 +595,16 @@ class ChromecastCastingDevice : CastingDevice {
return; return;
} }
val serializedSizeBE = ByteArray(4); synchronized(_outputStreamLock)
serializedSizeBE[0] = (data.size shr 24 and 0xff).toByte(); {
serializedSizeBE[1] = (data.size shr 16 and 0xff).toByte(); val serializedSizeBE = ByteArray(4);
serializedSizeBE[2] = (data.size shr 8 and 0xff).toByte(); serializedSizeBE[0] = (data.size shr 24 and 0xff).toByte();
serializedSizeBE[3] = (data.size and 0xff).toByte(); serializedSizeBE[1] = (data.size shr 16 and 0xff).toByte();
outputStream.write(serializedSizeBE); serializedSizeBE[2] = (data.size shr 8 and 0xff).toByte();
outputStream.write(data); serializedSizeBE[3] = (data.size and 0xff).toByte();
outputStream.write(serializedSizeBE);
outputStream.write(data);
}
//Log.d(TAG, "Sent ${data.size} bytes."); //Log.d(TAG, "Sent ${data.size} bytes.");
} }

View file

@ -242,6 +242,7 @@ class StateCasting {
jmDNS.addServiceListener("_googlecast._tcp.local.", _chromecastServiceListener); jmDNS.addServiceListener("_googlecast._tcp.local.", _chromecastServiceListener);
jmDNS.addServiceListener("_airplay._tcp.local.", _airPlayServiceListener); jmDNS.addServiceListener("_airplay._tcp.local.", _airPlayServiceListener);
jmDNS.addServiceListener("_fastcast._tcp.local.", _fastCastServiceListener); jmDNS.addServiceListener("_fastcast._tcp.local.", _fastCastServiceListener);
jmDNS.addServiceListener("_fcast._tcp.local.", _fastCastServiceListener);
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
jmDNS.addServiceTypeListener(_serviceTypeListener); jmDNS.addServiceTypeListener(_serviceTypeListener);