mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-04 23:30:52 +00:00
Removed last mentions of FastCast and added backwards compatibility.
This commit is contained in:
parent
3387c727d1
commit
a5dfa653ad
10 changed files with 51 additions and 37 deletions
|
@ -3,7 +3,6 @@ package com.futo.platformplayer.casting
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.api.http.ManagedHttpClient
|
import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||||
import com.futo.platformplayer.casting.models.FastCastSetVolumeMessage
|
|
||||||
import com.futo.platformplayer.getConnectedSocket
|
import com.futo.platformplayer.getConnectedSocket
|
||||||
import com.futo.platformplayer.models.CastingDeviceInfo
|
import com.futo.platformplayer.models.CastingDeviceInfo
|
||||||
import com.futo.platformplayer.toInetAddress
|
import com.futo.platformplayer.toInetAddress
|
||||||
|
@ -49,7 +48,7 @@ class AirPlayCastingDevice : CastingDevice {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.i(FastCastCastingDevice.TAG, "Start streaming (streamType: $streamType, contentType: $contentType, contentId: $contentId, resumePosition: $resumePosition, duration: $duration)");
|
Logger.i(FCastCastingDevice.TAG, "Start streaming (streamType: $streamType, contentType: $contentType, contentId: $contentId, resumePosition: $resumePosition, duration: $duration)");
|
||||||
|
|
||||||
time = resumePosition;
|
time = resumePosition;
|
||||||
if (resumePosition > 0.0) {
|
if (resumePosition > 0.0) {
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package com.futo.platformplayer.casting
|
package com.futo.platformplayer.casting
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails
|
|
||||||
import com.futo.platformplayer.constructs.Event1
|
import com.futo.platformplayer.constructs.Event1
|
||||||
import com.futo.platformplayer.getNowDiffMiliseconds
|
import com.futo.platformplayer.getNowDiffMiliseconds
|
||||||
import com.futo.platformplayer.models.CastingDeviceInfo
|
import com.futo.platformplayer.models.CastingDeviceInfo
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
@ -14,10 +19,27 @@ enum class CastConnectionState {
|
||||||
CONNECTED
|
CONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable(with = CastProtocolType.CastProtocolTypeSerializer::class)
|
||||||
enum class CastProtocolType {
|
enum class CastProtocolType {
|
||||||
CHROMECAST,
|
CHROMECAST,
|
||||||
AIRPLAY,
|
AIRPLAY,
|
||||||
FASTCAST
|
FCAST;
|
||||||
|
|
||||||
|
object CastProtocolTypeSerializer : KSerializer<CastProtocolType> {
|
||||||
|
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("CastProtocolType", PrimitiveKind.STRING)
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: CastProtocolType) {
|
||||||
|
encoder.encodeString(value.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): CastProtocolType {
|
||||||
|
val name = decoder.decodeString()
|
||||||
|
return when (name) {
|
||||||
|
"FASTCAST" -> FCAST // Handle the renamed case
|
||||||
|
else -> CastProtocolType.valueOf(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CastingDevice {
|
abstract class CastingDevice {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.futo.platformplayer.casting
|
||||||
|
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.futo.platformplayer.casting.models.FastCastSetVolumeMessage
|
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.getConnectedSocket
|
import com.futo.platformplayer.getConnectedSocket
|
||||||
import com.futo.platformplayer.models.CastingDeviceInfo
|
import com.futo.platformplayer.models.CastingDeviceInfo
|
||||||
|
@ -13,7 +12,6 @@ import kotlinx.coroutines.*
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.io.IOException
|
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import javax.net.ssl.SSLContext
|
import javax.net.ssl.SSLContext
|
||||||
|
|
|
@ -30,10 +30,10 @@ enum class Opcode(val value: Byte) {
|
||||||
SET_VOLUME(8)
|
SET_VOLUME(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FastCastCastingDevice : CastingDevice {
|
class FCastCastingDevice : CastingDevice {
|
||||||
//See for more info: TODO
|
//See for more info: TODO
|
||||||
|
|
||||||
override val protocol: CastProtocolType get() = CastProtocolType.FASTCAST;
|
override val protocol: CastProtocolType get() = CastProtocolType.FCAST;
|
||||||
override val isReady: Boolean get() = name != null && addresses != null && addresses?.isNotEmpty() == true && port != 0;
|
override val isReady: Boolean get() = name != null && addresses != null && addresses?.isNotEmpty() == true && port != 0;
|
||||||
override var usedRemoteAddress: InetAddress? = null;
|
override var usedRemoteAddress: InetAddress? = null;
|
||||||
override var localAddress: InetAddress? = null;
|
override var localAddress: InetAddress? = null;
|
||||||
|
@ -72,7 +72,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
Logger.i(TAG, "Start streaming (streamType: $streamType, contentType: $contentType, contentId: $contentId, resumePosition: $resumePosition, duration: $duration)");
|
Logger.i(TAG, "Start streaming (streamType: $streamType, contentType: $contentType, contentId: $contentId, resumePosition: $resumePosition, duration: $duration)");
|
||||||
|
|
||||||
time = resumePosition;
|
time = resumePosition;
|
||||||
sendMessage(Opcode.PLAY, FastCastPlayMessage(
|
sendMessage(Opcode.PLAY, FCastPlayMessage(
|
||||||
container = contentType,
|
container = contentType,
|
||||||
url = contentId,
|
url = contentId,
|
||||||
time = resumePosition.toInt()
|
time = resumePosition.toInt()
|
||||||
|
@ -87,7 +87,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
Logger.i(TAG, "Start streaming content (contentType: $contentType, resumePosition: $resumePosition, duration: $duration)");
|
Logger.i(TAG, "Start streaming content (contentType: $contentType, resumePosition: $resumePosition, duration: $duration)");
|
||||||
|
|
||||||
time = resumePosition;
|
time = resumePosition;
|
||||||
sendMessage(Opcode.PLAY, FastCastPlayMessage(
|
sendMessage(Opcode.PLAY, FCastPlayMessage(
|
||||||
container = contentType,
|
container = contentType,
|
||||||
content = content,
|
content = content,
|
||||||
time = resumePosition.toInt()
|
time = resumePosition.toInt()
|
||||||
|
@ -100,7 +100,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.volume = volume
|
this.volume = volume
|
||||||
sendMessage(Opcode.SET_VOLUME, FastCastSetVolumeMessage(volume))
|
sendMessage(Opcode.SET_VOLUME, FCastSetVolumeMessage(volume))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun seekVideo(timeSeconds: Double) {
|
override fun seekVideo(timeSeconds: Double) {
|
||||||
|
@ -108,7 +108,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(Opcode.SEEK, FastCastSeekMessage(
|
sendMessage(Opcode.SEEK, FCastSeekMessage(
|
||||||
time = timeSeconds.toInt()
|
time = timeSeconds.toInt()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val playbackUpdate = Json.decodeFromString<FastCastPlaybackUpdateMessage>(json);
|
val playbackUpdate = Json.decodeFromString<FCastPlaybackUpdateMessage>(json);
|
||||||
time = playbackUpdate.time.toDouble();
|
time = playbackUpdate.time.toDouble();
|
||||||
isPlaying = when (playbackUpdate.state) {
|
isPlaying = when (playbackUpdate.state) {
|
||||||
1 -> true
|
1 -> true
|
||||||
|
@ -295,7 +295,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val volumeUpdate = Json.decodeFromString<FastCastVolumeUpdateMessage>(json);
|
val volumeUpdate = Json.decodeFromString<FCastVolumeUpdateMessage>(json);
|
||||||
volume = volumeUpdate.volume;
|
volume = volumeUpdate.volume;
|
||||||
}
|
}
|
||||||
else -> { }
|
else -> { }
|
||||||
|
@ -398,7 +398,7 @@ class FastCastCastingDevice : CastingDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeviceInfo(): CastingDeviceInfo {
|
override fun getDeviceInfo(): CastingDeviceInfo {
|
||||||
return CastingDeviceInfo(name!!, CastProtocolType.FASTCAST, addresses!!.filter { a -> a.hostAddress != null }.map { a -> a.hostAddress!! }.toTypedArray(), port);
|
return CastingDeviceInfo(name!!, CastProtocolType.FCAST, addresses!!.filter { a -> a.hostAddress != null }.map { a -> a.hostAddress!! }.toTypedArray(), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
|
@ -345,7 +345,7 @@ class StateCasting {
|
||||||
} else {
|
} else {
|
||||||
StateApp.instance.scope.launch(Dispatchers.IO) {
|
StateApp.instance.scope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
if (ad is FastCastCastingDevice) {
|
if (ad is FCastCastingDevice) {
|
||||||
Logger.i(TAG, "Casting as DASH direct");
|
Logger.i(TAG, "Casting as DASH direct");
|
||||||
castDashDirect(contentResolver, video, videoSource as IVideoUrlSource?, audioSource as IAudioUrlSource?, subtitleSource, resumePosition);
|
castDashDirect(contentResolver, video, videoSource as IVideoUrlSource?, audioSource as IAudioUrlSource?, subtitleSource, resumePosition);
|
||||||
} else if (ad is AirPlayCastingDevice) {
|
} else if (ad is AirPlayCastingDevice) {
|
||||||
|
@ -961,7 +961,7 @@ class StateCasting {
|
||||||
|
|
||||||
private suspend fun castDashIndirect(contentResolver: ContentResolver, video: IPlatformVideoDetails, videoSource: IVideoUrlSource?, audioSource: IAudioUrlSource?, subtitleSource: ISubtitleSource?, resumePosition: Double) : List<String> {
|
private suspend fun castDashIndirect(contentResolver: ContentResolver, video: IPlatformVideoDetails, videoSource: IVideoUrlSource?, audioSource: IAudioUrlSource?, subtitleSource: ISubtitleSource?, resumePosition: Double) : List<String> {
|
||||||
val ad = activeDevice ?: return listOf();
|
val ad = activeDevice ?: return listOf();
|
||||||
val proxyStreams = ad !is FastCastCastingDevice;
|
val proxyStreams = ad !is FCastCastingDevice;
|
||||||
|
|
||||||
val url = "http://${ad.localAddress.toString().trim('/')}:${_castServer.port}";
|
val url = "http://${ad.localAddress.toString().trim('/')}:${_castServer.port}";
|
||||||
val id = UUID.randomUUID();
|
val id = UUID.randomUUID();
|
||||||
|
@ -1042,8 +1042,8 @@ class StateCasting {
|
||||||
CastProtocolType.AIRPLAY -> {
|
CastProtocolType.AIRPLAY -> {
|
||||||
AirPlayCastingDevice(deviceInfo);
|
AirPlayCastingDevice(deviceInfo);
|
||||||
}
|
}
|
||||||
CastProtocolType.FASTCAST -> {
|
CastProtocolType.FCAST -> {
|
||||||
FastCastCastingDevice(deviceInfo);
|
FCastCastingDevice(deviceInfo);
|
||||||
}
|
}
|
||||||
else -> throw Exception("${deviceInfo.type} is not a valid casting protocol")
|
else -> throw Exception("${deviceInfo.type} is not a valid casting protocol")
|
||||||
}
|
}
|
||||||
|
@ -1090,8 +1090,8 @@ class StateCasting {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addOrUpdateFastCastDevice(name: String, addresses: Array<InetAddress>, port: Int) {
|
private fun addOrUpdateFastCastDevice(name: String, addresses: Array<InetAddress>, port: Int) {
|
||||||
return addOrUpdateCastDevice<FastCastCastingDevice>(name,
|
return addOrUpdateCastDevice<FCastCastingDevice>(name,
|
||||||
deviceFactory = { FastCastCastingDevice(name, addresses, port) },
|
deviceFactory = { FCastCastingDevice(name, addresses, port) },
|
||||||
deviceUpdater = { d ->
|
deviceUpdater = { d ->
|
||||||
if (d.isReady) {
|
if (d.isReady) {
|
||||||
return@addOrUpdateCastDevice false;
|
return@addOrUpdateCastDevice false;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.futo.platformplayer.casting.models
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class FastCastPlayMessage(
|
data class FCastPlayMessage(
|
||||||
val container: String,
|
val container: String,
|
||||||
val url: String? = null,
|
val url: String? = null,
|
||||||
val content: String? = null,
|
val content: String? = null,
|
||||||
|
@ -11,23 +11,23 @@ data class FastCastPlayMessage(
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class FastCastSeekMessage(
|
data class FCastSeekMessage(
|
||||||
val time: Int
|
val time: Int
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class FastCastPlaybackUpdateMessage(
|
data class FCastPlaybackUpdateMessage(
|
||||||
val time: Int,
|
val time: Int,
|
||||||
val state: Int
|
val state: Int
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class FastCastVolumeUpdateMessage(
|
data class FCastVolumeUpdateMessage(
|
||||||
val volume: Double
|
val volume: Double
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class FastCastSetVolumeMessage(
|
data class FCastSetVolumeMessage(
|
||||||
val volume: Double
|
val volume: Double
|
||||||
)
|
)
|
|
@ -12,10 +12,7 @@ import com.futo.platformplayer.UIDialogs
|
||||||
import com.futo.platformplayer.casting.CastProtocolType
|
import com.futo.platformplayer.casting.CastProtocolType
|
||||||
import com.futo.platformplayer.casting.StateCasting
|
import com.futo.platformplayer.casting.StateCasting
|
||||||
import com.futo.platformplayer.models.CastingDeviceInfo
|
import com.futo.platformplayer.models.CastingDeviceInfo
|
||||||
import com.futo.platformplayer.states.StateApp
|
|
||||||
import com.futo.platformplayer.toInetAddress
|
import com.futo.platformplayer.toInetAddress
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
|
|
||||||
class CastingAddDialog(context: Context?) : AlertDialog(context) {
|
class CastingAddDialog(context: Context?) : AlertDialog(context) {
|
||||||
|
@ -62,7 +59,7 @@ class CastingAddDialog(context: Context?) : AlertDialog(context) {
|
||||||
|
|
||||||
_buttonConfirm.setOnClickListener {
|
_buttonConfirm.setOnClickListener {
|
||||||
val castProtocolType: CastProtocolType = when (_spinnerType.selectedItemPosition) {
|
val castProtocolType: CastProtocolType = when (_spinnerType.selectedItemPosition) {
|
||||||
0 -> CastProtocolType.FASTCAST
|
0 -> CastProtocolType.FCAST
|
||||||
1 -> CastProtocolType.CHROMECAST
|
1 -> CastProtocolType.CHROMECAST
|
||||||
2 -> CastProtocolType.AIRPLAY
|
2 -> CastProtocolType.AIRPLAY
|
||||||
else -> {
|
else -> {
|
||||||
|
|
|
@ -16,9 +16,7 @@ import com.futo.platformplayer.casting.*
|
||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.google.android.material.slider.Slider
|
import com.google.android.material.slider.Slider
|
||||||
import com.google.android.material.slider.Slider.OnChangeListener
|
import com.google.android.material.slider.Slider.OnChangeListener
|
||||||
import com.google.android.material.slider.Slider.OnSliderTouchListener
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
|
@ -105,7 +103,7 @@ class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
} else if (d is AirPlayCastingDevice) {
|
} else if (d is AirPlayCastingDevice) {
|
||||||
_imageDevice.setImageResource(R.drawable.ic_airplay);
|
_imageDevice.setImageResource(R.drawable.ic_airplay);
|
||||||
_textType.text = "AirPlay";
|
_textType.text = "AirPlay";
|
||||||
} else if (d is FastCastCastingDevice) {
|
} else if (d is FCastCastingDevice) {
|
||||||
_imageDevice.setImageResource(R.drawable.ic_fc);
|
_imageDevice.setImageResource(R.drawable.ic_fc);
|
||||||
_textType.text = "FastCast";
|
_textType.text = "FastCast";
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,9 +74,9 @@ class DeviceViewHolder : ViewHolder {
|
||||||
} else if (d is AirPlayCastingDevice) {
|
} else if (d is AirPlayCastingDevice) {
|
||||||
_imageDevice.setImageResource(R.drawable.ic_airplay);
|
_imageDevice.setImageResource(R.drawable.ic_airplay);
|
||||||
_textType.text = "AirPlay";
|
_textType.text = "AirPlay";
|
||||||
} else if (d is FastCastCastingDevice) {
|
} else if (d is FCastCastingDevice) {
|
||||||
_imageDevice.setImageResource(R.drawable.ic_fc);
|
_imageDevice.setImageResource(R.drawable.ic_fc);
|
||||||
_textType.text = "FastCast";
|
_textType.text = "FCast";
|
||||||
}
|
}
|
||||||
|
|
||||||
_textName.text = d.name;
|
_textName.text = d.name;
|
||||||
|
|
|
@ -839,7 +839,7 @@
|
||||||
<item>Russian</item>
|
<item>Russian</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="casting_device_type_array" translatable="false">
|
<string-array name="casting_device_type_array" translatable="false">
|
||||||
<item>FastCast</item>
|
<item>FCast</item>
|
||||||
<item>ChromeCast</item>
|
<item>ChromeCast</item>
|
||||||
<item>AirPlay</item>
|
<item>AirPlay</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue