mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-09-12 12:32:27 +00:00
casting: update SDK to 0.2.1
This commit is contained in:
parent
0fd83cbd74
commit
5a74b714b8
5 changed files with 41 additions and 26 deletions
|
@ -233,5 +233,8 @@ dependencies {
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
|
||||||
//Rust casting SDK
|
//Rust casting SDK
|
||||||
implementation "net.java.dev.jna:jna:5.12.0@aar"
|
implementation('org.futo.gitlab.videostreaming.fcast-sdk-jitpack:sender-sdk-minimal:0.2.1') {
|
||||||
|
// Polycentricandroid includes this
|
||||||
|
exclude group: 'net.java.dev.jna'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,12 @@ class ConnectedCastingDialog(context: Context?) : AlertDialog(context) {
|
||||||
_buttonClose.setOnClickListener { dismiss(); };
|
_buttonClose.setOnClickListener { dismiss(); };
|
||||||
_buttonDisconnect.setOnClickListener {
|
_buttonDisconnect.setOnClickListener {
|
||||||
if (Settings.instance.casting.experimentalCasting) {
|
if (Settings.instance.casting.experimentalCasting) {
|
||||||
ExpStateCasting.instance.activeDevice?.device?.stopCasting()
|
try {
|
||||||
|
ExpStateCasting.instance.activeDevice?.device?.stopPlayback()
|
||||||
|
ExpStateCasting.instance.activeDevice?.device?.disconnect()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
StateCasting.instance.activeDevice?.stopCasting();
|
StateCasting.instance.activeDevice?.stopCasting();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.net.InetAddress
|
||||||
import org.fcast.sender_sdk.CastingDevice as RsCastingDevice;
|
import org.fcast.sender_sdk.CastingDevice as RsCastingDevice;
|
||||||
import org.fcast.sender_sdk.DeviceEventHandler as RsDeviceEventHandler;
|
import org.fcast.sender_sdk.DeviceEventHandler as RsDeviceEventHandler;
|
||||||
import org.fcast.sender_sdk.DeviceConnectionState
|
import org.fcast.sender_sdk.DeviceConnectionState
|
||||||
|
import org.fcast.sender_sdk.LoadRequest
|
||||||
|
|
||||||
class CastingDeviceHandle {
|
class CastingDeviceHandle {
|
||||||
class EventHandler : RsDeviceEventHandler {
|
class EventHandler : RsDeviceEventHandler {
|
||||||
|
@ -64,6 +65,10 @@ class CastingDeviceHandle {
|
||||||
override fun mediaEvent(event: GenericMediaEvent) {
|
override fun mediaEvent(event: GenericMediaEvent) {
|
||||||
// Unreachable
|
// Unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun playbackError(message: String) {
|
||||||
|
Logger.e(TAG, "Playback error: $message")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventHandler = EventHandler()
|
val eventHandler = EventHandler()
|
||||||
|
@ -91,17 +96,16 @@ class CastingDeviceHandle {
|
||||||
eventHandler.onConnectionStateChanged.subscribe { newState ->
|
eventHandler.onConnectionStateChanged.subscribe { newState ->
|
||||||
if (newState == DeviceConnectionState.Disconnected) {
|
if (newState == DeviceConnectionState.Disconnected) {
|
||||||
try {
|
try {
|
||||||
Logger.i("CastingDeviceHandle", "Stopping device")
|
Logger.i(TAG, "Stopping device")
|
||||||
device.disconnect()
|
device.disconnect()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Logger.e("CastingDeviceHandle", "Failed to stop device: $e")
|
Logger.e(TAG, "Failed to stop device: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadVideo(
|
fun loadVideo(
|
||||||
streamType: String,
|
|
||||||
contentType: String,
|
contentType: String,
|
||||||
contentId: String,
|
contentId: String,
|
||||||
resumePosition: Double,
|
resumePosition: Double,
|
||||||
|
@ -109,9 +113,9 @@ class CastingDeviceHandle {
|
||||||
speed: Double?
|
speed: Double?
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
device.loadVideo(contentType, contentId, resumePosition, speed)
|
device.load(LoadRequest.Video(contentType, contentId, resumePosition, speed, duration))
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Logger.e("CastingDevice", "Failed to load video: $e")
|
Logger.e(TAG, "Failed to load video: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,11 +127,15 @@ class CastingDeviceHandle {
|
||||||
speed: Double?
|
speed: Double?
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
device.loadContent(contentType, content, resumePosition, duration, speed)
|
device.load(LoadRequest.Content(contentType, content, resumePosition, duration, speed))
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Logger.e("CastingDevice", "Failed to load content: $e")
|
Logger.e(TAG, "Failed to load content: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = "ExperimentalCastingDevice"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class CastConnectionState {
|
enum class CastConnectionState {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
|
import com.futo.platformplayer.BuildConfig
|
||||||
import com.futo.platformplayer.R
|
import com.futo.platformplayer.R
|
||||||
import com.futo.platformplayer.Settings
|
import com.futo.platformplayer.Settings
|
||||||
import com.futo.platformplayer.UIDialogs
|
import com.futo.platformplayer.UIDialogs
|
||||||
|
@ -50,6 +51,7 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.fcast.sender_sdk.ApplicationInfo
|
||||||
import java.net.Inet6Address
|
import java.net.Inet6Address
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
|
@ -110,7 +112,9 @@ class ExpStateCasting {
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
org.fcast.sender_sdk.initLogger(org.fcast.sender_sdk.LogLevelFilter.DEBUG)
|
if (BuildConfig.DEBUG) {
|
||||||
|
org.fcast.sender_sdk.initLogger(org.fcast.sender_sdk.LogLevelFilter.DEBUG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleUrl(context: Context, url: String) {
|
fun handleUrl(context: Context, url: String) {
|
||||||
|
@ -382,7 +386,13 @@ class ExpStateCasting {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
device.device.connect(device.eventHandler)
|
device.device.connect(
|
||||||
|
ApplicationInfo(
|
||||||
|
"grayjay android",
|
||||||
|
"${BuildConfig.VERSION_NAME}-${BuildConfig.FLAVOR}",
|
||||||
|
"Grayjay"
|
||||||
|
), device.eventHandler
|
||||||
|
)
|
||||||
Logger.i(TAG, "Requested manager to start device")
|
Logger.i(TAG, "Requested manager to start device")
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Logger.w(TAG, "Failed to connect to device.");
|
Logger.w(TAG, "Failed to connect to device.");
|
||||||
|
@ -415,7 +425,7 @@ class ExpStateCasting {
|
||||||
val rsDeviceInfo = device.device.getDeviceInfo()
|
val rsDeviceInfo = device.device.getDeviceInfo()
|
||||||
val deviceInfo = CastingDeviceInfo(
|
val deviceInfo = CastingDeviceInfo(
|
||||||
name = device.device.name(),
|
name = device.device.name(),
|
||||||
type = when (rsDeviceInfo.type) {
|
type = when (rsDeviceInfo.protocol) {
|
||||||
ProtocolType.CHROMECAST -> com.futo.platformplayer.casting.CastProtocolType.CHROMECAST
|
ProtocolType.CHROMECAST -> com.futo.platformplayer.casting.CastProtocolType.CHROMECAST
|
||||||
ProtocolType.F_CAST -> com.futo.platformplayer.casting.CastProtocolType.FCAST
|
ProtocolType.F_CAST -> com.futo.platformplayer.casting.CastProtocolType.FCAST
|
||||||
},
|
},
|
||||||
|
@ -547,7 +557,6 @@ class ExpStateCasting {
|
||||||
val videoUrl = if (proxyStreams) url + videoPath else videoSource.getVideoUrl();
|
val videoUrl = if (proxyStreams) url + videoPath else videoSource.getVideoUrl();
|
||||||
Logger.i(TAG, "Casting as singular video");
|
Logger.i(TAG, "Casting as singular video");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
videoSource.container,
|
videoSource.container,
|
||||||
videoUrl,
|
videoUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -559,7 +568,6 @@ class ExpStateCasting {
|
||||||
val audioUrl = if (proxyStreams) url + audioPath else audioSource.getAudioUrl();
|
val audioUrl = if (proxyStreams) url + audioPath else audioSource.getAudioUrl();
|
||||||
Logger.i(TAG, "Casting as singular audio");
|
Logger.i(TAG, "Casting as singular audio");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
audioSource.container,
|
audioSource.container,
|
||||||
audioUrl,
|
audioUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -579,7 +587,6 @@ class ExpStateCasting {
|
||||||
} else {
|
} else {
|
||||||
Logger.i(TAG, "Casting as non-proxied HLS");
|
Logger.i(TAG, "Casting as non-proxied HLS");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
videoSource.container,
|
videoSource.container,
|
||||||
videoSource.url,
|
videoSource.url,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -600,7 +607,6 @@ class ExpStateCasting {
|
||||||
} else {
|
} else {
|
||||||
Logger.i(TAG, "Casting as non-proxied audio HLS");
|
Logger.i(TAG, "Casting as non-proxied audio HLS");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
audioSource.container,
|
audioSource.container,
|
||||||
audioSource.url,
|
audioSource.url,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -716,7 +722,6 @@ class ExpStateCasting {
|
||||||
|
|
||||||
Logger.i(TAG, "Casting local video (videoUrl: $videoUrl).");
|
Logger.i(TAG, "Casting local video (videoUrl: $videoUrl).");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
"BUFFERED",
|
|
||||||
videoSource.container,
|
videoSource.container,
|
||||||
videoUrl,
|
videoUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -747,7 +752,6 @@ class ExpStateCasting {
|
||||||
|
|
||||||
Logger.i(TAG, "Casting local audio (audioUrl: $audioUrl).");
|
Logger.i(TAG, "Casting local audio (audioUrl: $audioUrl).");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
"BUFFERED",
|
|
||||||
audioSource.container,
|
audioSource.container,
|
||||||
audioUrl,
|
audioUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -941,7 +945,6 @@ class ExpStateCasting {
|
||||||
"added new castLocalHls handlers (hlsPath: $hlsPath, videoPath: $videoPath, audioPath: $audioPath, subtitlePath: $subtitlePath)."
|
"added new castLocalHls handlers (hlsPath: $hlsPath, videoPath: $videoPath, audioPath: $audioPath, subtitlePath: $subtitlePath)."
|
||||||
)
|
)
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
"BUFFERED",
|
|
||||||
"application/vnd.apple.mpegurl",
|
"application/vnd.apple.mpegurl",
|
||||||
hlsUrl,
|
hlsUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -1021,7 +1024,6 @@ class ExpStateCasting {
|
||||||
"added new castLocalDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath, subtitlePath: $subtitlePath)."
|
"added new castLocalDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath, subtitlePath: $subtitlePath)."
|
||||||
);
|
);
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
"BUFFERED",
|
|
||||||
"application/dash+xml",
|
"application/dash+xml",
|
||||||
dashUrl,
|
dashUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -1297,7 +1299,6 @@ class ExpStateCasting {
|
||||||
val hackfixResumePosition =
|
val hackfixResumePosition =
|
||||||
if (ad.device.castingProtocol() == ProtocolType.CHROMECAST && !video.isLive && resumePosition == 0.0) 0.1 else resumePosition;
|
if (ad.device.castingProtocol() == ProtocolType.CHROMECAST && !video.isLive && resumePosition == 0.0) 0.1 else resumePosition;
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
"application/vnd.apple.mpegurl",
|
"application/vnd.apple.mpegurl",
|
||||||
hlsUrl,
|
hlsUrl,
|
||||||
hackfixResumePosition,
|
hackfixResumePosition,
|
||||||
|
@ -1570,7 +1571,6 @@ class ExpStateCasting {
|
||||||
|
|
||||||
Logger.i(TAG, "added new castHls handlers (hlsPath: $hlsPath).");
|
Logger.i(TAG, "added new castHls handlers (hlsPath: $hlsPath).");
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
"application/vnd.apple.mpegurl",
|
"application/vnd.apple.mpegurl",
|
||||||
hlsUrl,
|
hlsUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -1686,7 +1686,6 @@ class ExpStateCasting {
|
||||||
"added new castDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath)."
|
"added new castDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath)."
|
||||||
);
|
);
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
"application/dash+xml",
|
"application/dash+xml",
|
||||||
dashUrl,
|
dashUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -1955,7 +1954,6 @@ class ExpStateCasting {
|
||||||
"added new castDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath)."
|
"added new castDash handlers (dashPath: $dashPath, videoPath: $videoPath, audioPath: $audioPath)."
|
||||||
);
|
);
|
||||||
ad.loadVideo(
|
ad.loadVideo(
|
||||||
if (video.isLive) "LIVE" else "BUFFERED",
|
|
||||||
"application/dash+xml",
|
"application/dash+xml",
|
||||||
dashUrl,
|
dashUrl,
|
||||||
resumePosition,
|
resumePosition,
|
||||||
|
@ -1971,7 +1969,7 @@ class ExpStateCasting {
|
||||||
deviceInfo.addresses.map { org.fcast.sender_sdk.tryIpAddrFromStr(it) } // Throws!
|
deviceInfo.addresses.map { org.fcast.sender_sdk.tryIpAddrFromStr(it) } // Throws!
|
||||||
val rsDeviceInfo = RsDeviceInfo(
|
val rsDeviceInfo = RsDeviceInfo(
|
||||||
name = deviceInfo.name,
|
name = deviceInfo.name,
|
||||||
type = when (deviceInfo.type) {
|
protocol = when (deviceInfo.type) {
|
||||||
com.futo.platformplayer.casting.CastProtocolType.CHROMECAST -> ProtocolType.CHROMECAST
|
com.futo.platformplayer.casting.CastProtocolType.CHROMECAST -> ProtocolType.CHROMECAST
|
||||||
com.futo.platformplayer.casting.CastProtocolType.FCAST -> ProtocolType.F_CAST
|
com.futo.platformplayer.casting.CastProtocolType.FCAST -> ProtocolType.F_CAST
|
||||||
else -> throw IllegalArgumentException()
|
else -> throw IllegalArgumentException()
|
||||||
|
|
|
@ -74,7 +74,8 @@ class DeviceViewHolder : ViewHolder {
|
||||||
if (dev.handle.device.isReady()) {
|
if (dev.handle.device.isReady()) {
|
||||||
// NOTE: we assume experimental casting is used
|
// NOTE: we assume experimental casting is used
|
||||||
try {
|
try {
|
||||||
ExpStateCasting.instance.activeDevice?.device?.stopCasting()
|
ExpStateCasting.instance.activeDevice?.device?.stopPlayback()
|
||||||
|
ExpStateCasting.instance.activeDevice?.device?.disconnect()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
//Ignored
|
//Ignored
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue