mirror of
https://github.com/zoriya/react-native-omni.git
synced 2026-08-16 02:44:51 +00:00
feat(chromecast): support custom subtitle broadcast
This commit is contained in:
+13
-17
@@ -244,26 +244,22 @@ export class WebOmniPlayer implements OmniPlayer {
|
||||
this.setOverlaySubtitle(overlay ?? null);
|
||||
|
||||
if (this.castStatus === "connected") {
|
||||
try {
|
||||
// if the cast receiver handles overlay subtitles like us, send this message.
|
||||
const ctx = (
|
||||
window as unknown as {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: cast sender SDK global
|
||||
cast?: { framework?: { CastContext?: { getInstance(): any } } };
|
||||
}
|
||||
).cast?.framework?.CastContext?.getInstance?.();
|
||||
ctx
|
||||
?.getCurrentSession?.()
|
||||
?.sendMessage("urn:x-cast:dev.zoriya.omni", {
|
||||
subtitle: overlay?.id ?? null,
|
||||
})
|
||||
?.catch?.(() => {});
|
||||
} catch {
|
||||
// no active cast session / sender SDK not loaded
|
||||
}
|
||||
window.cast.framework.CastContext.getInstance()
|
||||
.getCurrentSession()
|
||||
?.sendMessage("urn:x-cast:dev.zoriya.omni", {
|
||||
subtitle: overlay?.id ?? null,
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
// To be used on a callback of a chromecast session, it only changes the local state
|
||||
applyRemoteSubtitle(id: string | null): void {
|
||||
this.setOverlaySubtitle(
|
||||
id ? (this.overlaySubtitles.find((s) => s.id === id) ?? null) : null,
|
||||
);
|
||||
}
|
||||
|
||||
private setOverlaySubtitle(sub: Subtitle | null): void {
|
||||
if (this.overlaySubtitle === sub) return;
|
||||
this.overlaySubtitle = sub;
|
||||
|
||||
@@ -72,6 +72,44 @@ const PlayerInitializer = ({
|
||||
player.showNotification = showNotification;
|
||||
}, [showNotification]);
|
||||
|
||||
useEffect(() => {
|
||||
const ctx = window.cast?.framework?.CastContext?.getInstance();
|
||||
if (!window.cast?.framework || !ctx) return;
|
||||
|
||||
let attached: cast.framework.CastSession | null = null;
|
||||
|
||||
const onSessionChange = () => {
|
||||
const session = ctx.getCurrentSession();
|
||||
if (!session || session === attached) return;
|
||||
attached = session;
|
||||
session.addMessageListener(
|
||||
"urn:x-cast:dev.zoriya.omni",
|
||||
(_ns: string, message: string) => {
|
||||
let data: unknown;
|
||||
try {
|
||||
data = JSON.parse(message);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (data && typeof data === "object" && "subtitle" in data) {
|
||||
const id = (data as { subtitle?: unknown }).subtitle;
|
||||
player.applyRemoteSubtitle(typeof id === "string" ? id : null);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
onSessionChange();
|
||||
ctx.addEventListener(
|
||||
window.cast?.framework.CastContextEventType.SESSION_STATE_CHANGED,
|
||||
onSessionChange,
|
||||
);
|
||||
return () =>
|
||||
ctx.removeEventListener(
|
||||
window.cast?.framework.CastContextEventType.SESSION_STATE_CHANGED,
|
||||
onSessionChange,
|
||||
);
|
||||
}, []);
|
||||
|
||||
return <PlayerCtx.Provider value={player}>{children}</PlayerCtx.Provider>;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user