mirror of
https://github.com/zoriya/react-native-omni.git
synced 2026-08-16 02:44:51 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88410ca19d | ||
|
|
be10a769dd | ||
|
|
e95fb80cba | ||
|
|
82675e565a |
@@ -15,6 +15,8 @@ import androidx.media3.common.Player.STATE_READY
|
|||||||
import androidx.media3.common.Timeline
|
import androidx.media3.common.Timeline
|
||||||
import androidx.media3.common.Tracks
|
import androidx.media3.common.Tracks
|
||||||
import androidx.media3.common.VideoSize
|
import androidx.media3.common.VideoSize
|
||||||
|
import com.google.android.gms.cast.MediaStatus
|
||||||
|
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
||||||
import com.margelo.nitro.omni.BoolProperty
|
import com.margelo.nitro.omni.BoolProperty
|
||||||
import com.margelo.nitro.omni.CastStatus
|
import com.margelo.nitro.omni.CastStatus
|
||||||
import com.margelo.nitro.omni.HybridOmniEventMapSpec
|
import com.margelo.nitro.omni.HybridOmniEventMapSpec
|
||||||
@@ -103,6 +105,8 @@ class EventMap(private val tracks: TrackProvider) : HybridOmniEventMapSpec(), Pl
|
|||||||
onTracksChanged(value.currentTracks)
|
onTracksChanged(value.currentTracks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var remote: RemoteMediaClient? = null
|
||||||
|
|
||||||
fun emitCastStatus(status: CastStatus) {
|
fun emitCastStatus(status: CastStatus) {
|
||||||
castStatusListeners.forEach { it(status) }
|
castStatusListeners.forEach { it(status) }
|
||||||
}
|
}
|
||||||
@@ -200,7 +204,13 @@ class EventMap(private val tracks: TrackProvider) : HybridOmniEventMapSpec(), Pl
|
|||||||
|
|
||||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||||
val state = when (player.playbackState) {
|
val state = when (player.playbackState) {
|
||||||
STATE_IDLE -> PlayerStatus.IDLE
|
STATE_IDLE -> {
|
||||||
|
// cast doesn't have STATE_ENDED, so handle this manually
|
||||||
|
if (remote?.mediaStatus?.idleReason == MediaStatus.IDLE_REASON_FINISHED)
|
||||||
|
onEndListeners.forEach { it() }
|
||||||
|
PlayerStatus.IDLE
|
||||||
|
}
|
||||||
|
|
||||||
STATE_BUFFERING -> PlayerStatus.LOADING
|
STATE_BUFFERING -> PlayerStatus.LOADING
|
||||||
STATE_READY -> PlayerStatus.READYTOPLAY
|
STATE_READY -> PlayerStatus.READYTOPLAY
|
||||||
STATE_ENDED -> {
|
STATE_ENDED -> {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import androidx.media3.session.MediaSession
|
|||||||
import androidx.media3.session.MediaSessionService
|
import androidx.media3.session.MediaSessionService
|
||||||
import androidx.mediarouter.app.MediaRouteChooserDialog
|
import androidx.mediarouter.app.MediaRouteChooserDialog
|
||||||
import androidx.mediarouter.app.SystemOutputSwitcherDialogController
|
import androidx.mediarouter.app.SystemOutputSwitcherDialogController
|
||||||
|
import com.google.android.gms.cast.MediaStatus
|
||||||
import com.google.android.gms.cast.framework.CastContext
|
import com.google.android.gms.cast.framework.CastContext
|
||||||
import com.google.android.gms.cast.framework.CastState
|
import com.google.android.gms.cast.framework.CastState
|
||||||
import com.google.android.gms.cast.framework.CastStateListener
|
import com.google.android.gms.cast.framework.CastStateListener
|
||||||
@@ -110,7 +111,9 @@ class OmniPlayer(
|
|||||||
// their own), so they ask us to do it when something else - google home, the
|
// their own), so they ask us to do it when something else - google home, the
|
||||||
// assistant, ... - requests a prev/next. same path as our own buttons.
|
// assistant, ... - requests a prev/next. same path as our own buttons.
|
||||||
private fun listenToReceiver() {
|
private fun listenToReceiver() {
|
||||||
val session = castContext?.sessionManager?.currentCastSession ?: return
|
val session = castContext?.sessionManager?.currentCastSession
|
||||||
|
eventMap.remote = session?.remoteMediaClient
|
||||||
|
if (session == null) return
|
||||||
try {
|
try {
|
||||||
session.setMessageReceivedCallbacks(OMNI_NAMESPACE) { _, _, message ->
|
session.setMessageReceivedCallbacks(OMNI_NAMESPACE) { _, _, message ->
|
||||||
when (JSONObject(message).optString("action")) {
|
when (JSONObject(message).optString("action")) {
|
||||||
@@ -302,6 +305,8 @@ class OmniPlayer(
|
|||||||
|
|
||||||
private fun sourceOf(item: MediaItem): Source {
|
private fun sourceOf(item: MediaItem): Source {
|
||||||
val meta = item.mediaMetadata
|
val meta = item.mediaMetadata
|
||||||
|
val status = castContext?.sessionManager?.currentCastSession
|
||||||
|
?.remoteMediaClient?.mediaStatus
|
||||||
return Source(
|
return Source(
|
||||||
src = VideoSrc(
|
src = VideoSrc(
|
||||||
uri = item.localConfiguration?.uri?.toString() ?: item.mediaId,
|
uri = item.localConfiguration?.uri?.toString() ?: item.mediaId,
|
||||||
@@ -316,9 +321,8 @@ class OmniPlayer(
|
|||||||
album = meta.albumTitle?.toString(),
|
album = meta.albumTitle?.toString(),
|
||||||
artist = meta.artist?.toString(),
|
artist = meta.artist?.toString(),
|
||||||
imageLink = meta.artworkUri?.toString(),
|
imageLink = meta.artworkUri?.toString(),
|
||||||
// we did not load it, we don't know what comes around it.
|
hasPrev = status?.isMediaCommandSupported(MediaStatus.COMMAND_QUEUE_PREVIOUS),
|
||||||
hasPrev = null,
|
hasNext = status?.isMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT),
|
||||||
hasNext = null,
|
|
||||||
),
|
),
|
||||||
mixAudio = null,
|
mixAudio = null,
|
||||||
castId = item.mediaId,
|
castId = item.mediaId,
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ class VlcPlayer(ctx: Context) :
|
|||||||
.setWidth(videoTrack?.width?.takeIf { it > 0 } ?: Format.NO_VALUE)
|
.setWidth(videoTrack?.width?.takeIf { it > 0 } ?: Format.NO_VALUE)
|
||||||
.setHeight(videoTrack?.height?.takeIf { it > 0 } ?: Format.NO_VALUE)
|
.setHeight(videoTrack?.height?.takeIf { it > 0 } ?: Format.NO_VALUE)
|
||||||
.setFrameRate(
|
.setFrameRate(
|
||||||
videoTrack?.takeIf { it.frameRateDen > 0 }
|
videoTrack?.takeIf { it.frameRateDen > 0 && it.frameRateNum > 0 }
|
||||||
?.let { it.frameRateNum.toFloat() / it.frameRateDen }
|
?.let { it.frameRateNum.toFloat() / it.frameRateDen }
|
||||||
?: Format.NO_VALUE.toFloat()
|
?: Format.NO_VALUE.toFloat()
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-13
@@ -119,9 +119,11 @@ export const OmniView = ({
|
|||||||
const headersRef = useRef(source?.src?.headers);
|
const headersRef = useRef(source?.src?.headers);
|
||||||
headersRef.current = source?.src?.headers;
|
headersRef.current = source?.src?.headers;
|
||||||
|
|
||||||
|
const startTime = source?.startTime;
|
||||||
const config = useMemo<HlsMediaConfig>(
|
const config = useMemo<HlsMediaConfig>(
|
||||||
() => ({
|
() => ({
|
||||||
hlsJs: {
|
hlsJs: {
|
||||||
|
...(startTime && { startPosition: startTime }),
|
||||||
xhrSetup: (xhr: XMLHttpRequest) => {
|
xhrSetup: (xhr: XMLHttpRequest) => {
|
||||||
const headers = headersRef.current;
|
const headers = headersRef.current;
|
||||||
if (!headers) return;
|
if (!headers) return;
|
||||||
@@ -131,20 +133,9 @@ export const OmniView = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[],
|
[startTime],
|
||||||
);
|
);
|
||||||
|
|
||||||
const player = usePlayer();
|
|
||||||
const uri = source?.src.uri;
|
|
||||||
const startTime = source?.startTime;
|
|
||||||
const prevUri = useRef<string | undefined>(undefined);
|
|
||||||
useEffect(() => {
|
|
||||||
if (!uri) return;
|
|
||||||
if (startTime) player.currentTime = startTime;
|
|
||||||
if (autoplay && prevUri.current && prevUri.current !== uri) player.play();
|
|
||||||
prevUri.current = uri;
|
|
||||||
}, [player, uri, startTime, autoplay]);
|
|
||||||
|
|
||||||
// While casting, the receiver renders subtitles (the player forwards the
|
// While casting, the receiver renders subtitles (the player forwards the
|
||||||
// selection); skip rendering them locally on the idle <video>.
|
// selection); skip rendering them locally on the idle <video>.
|
||||||
const castStatus = usePlayerState("castStatus");
|
const castStatus = usePlayerState("castStatus");
|
||||||
@@ -156,7 +147,7 @@ export const OmniView = ({
|
|||||||
>
|
>
|
||||||
<Tech
|
<Tech
|
||||||
ref={ref}
|
ref={ref}
|
||||||
src={source?.src.uri}
|
src={source && startTime ? `${source.src.uri}#t=${startTime}` : source?.src.uri}
|
||||||
config={config}
|
config={config}
|
||||||
autoPlay={autoplay}
|
autoPlay={autoplay}
|
||||||
playsInline
|
playsInline
|
||||||
|
|||||||
Reference in New Issue
Block a user