mirror of
https://github.com/zoriya/react-native-video.git
synced 2026-05-25 07:45:56 +00:00
fix(web): critical runtime fixes
Fix BigInt(NaN), player.src(undefined), codeMap fallback, videoWidth, quality guard, listener leaks, vid.style, window.videojs, MediaSession SSR.
This commit is contained in:
@@ -74,9 +74,6 @@ class VideoPlayer extends VideoPlayerEvents implements VideoPlayerBase {
|
||||
nativeTextTracks: true,
|
||||
},
|
||||
});
|
||||
// @ts-ignore used for debugging or extending purposes
|
||||
window.videojs = videojs;
|
||||
|
||||
super(new WebEventEmitter(player));
|
||||
|
||||
this.video = video;
|
||||
@@ -110,7 +107,7 @@ class VideoPlayer extends VideoPlayerEvents implements VideoPlayerBase {
|
||||
width: this.player.videoWidth(),
|
||||
height: this.player.videoHeight(),
|
||||
duration: this.duration,
|
||||
fileSize: BigInt(NaN),
|
||||
fileSize: -1n,
|
||||
isHDR: false,
|
||||
isLive: false,
|
||||
orientation: "landscape",
|
||||
|
||||
@@ -80,7 +80,7 @@ const VideoView = forwardRef<VideoViewRef, VideoViewProps>(
|
||||
const vid = player.__getNativeRef();
|
||||
const objectFit: CSSProperties["objectFit"] =
|
||||
resizeMode === "stretch" ? "fill" : resizeMode;
|
||||
vid.style = `position: absolute; inset: 0; width: 100%; height: 100%; object-fit: ${objectFit}`;
|
||||
vid.style.cssText = `position: absolute; inset: 0; width: 100%; height: 100%; object-fit: ${objectFit}`;
|
||||
}, [player, resizeMode]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,7 +3,10 @@ import type { CustomVideoMetadata } from "../types/VideoConfig";
|
||||
|
||||
type VideoJsPlayer = ReturnType<typeof videojs>;
|
||||
|
||||
const mediaSession = window.navigator.mediaSession;
|
||||
function getMediaSession(): MediaSession | undefined {
|
||||
if (typeof window === "undefined") return undefined;
|
||||
return window.navigator?.mediaSession;
|
||||
}
|
||||
|
||||
export class MediaSessionHandler {
|
||||
enabled: boolean = false;
|
||||
@@ -11,6 +14,9 @@ export class MediaSessionHandler {
|
||||
constructor(private player: VideoJsPlayer) {}
|
||||
|
||||
enable() {
|
||||
const mediaSession = getMediaSession();
|
||||
if (!mediaSession) return;
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
const defaultSkipTime = 15;
|
||||
@@ -133,6 +139,9 @@ export class MediaSessionHandler {
|
||||
disable() {}
|
||||
|
||||
updateMediaSession(metadata: CustomVideoMetadata | undefined) {
|
||||
const mediaSession = getMediaSession();
|
||||
if (!mediaSession) return;
|
||||
|
||||
if (!metadata) {
|
||||
mediaSession.metadata = null;
|
||||
return;
|
||||
|
||||
@@ -106,6 +106,8 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
|
||||
this.player.off("durationchange", this._onDurationChange);
|
||||
|
||||
this.player.off("loadstart", this._onLoadStart);
|
||||
|
||||
this.player.off("play", this._onPlay);
|
||||
this.player.off("pause", this._onPause);
|
||||
|
||||
@@ -127,7 +129,6 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
|
||||
this.player.videoTracks().off("change", this._onVideoTrackChange);
|
||||
|
||||
this._onQualityChange = this._onQualityChange.bind(this);
|
||||
// @ts-expect-error this isn't typed
|
||||
this.player.qualityLevels().off("change", this._onQualityChange);
|
||||
}
|
||||
@@ -309,8 +310,8 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
this._emit("onLoad", {
|
||||
currentTime: this.player.currentTime() ?? 0,
|
||||
duration: this.player.duration() ?? NaN,
|
||||
width: this.player.width() ?? NaN,
|
||||
height: this.player.height() ?? NaN,
|
||||
width: this.player.videoWidth() ?? NaN,
|
||||
height: this.player.videoHeight() ?? NaN,
|
||||
orientation: "unknown",
|
||||
});
|
||||
}
|
||||
@@ -324,19 +325,19 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
this._emit("onLoadStart", {
|
||||
sourceType: "network",
|
||||
source: {
|
||||
uri: this.player.src(undefined)!,
|
||||
uri: this.player.currentSrc(),
|
||||
config: {
|
||||
uri: this.player.src(undefined)!,
|
||||
uri: this.player.currentSrc(),
|
||||
externalSubtitles: [],
|
||||
},
|
||||
getAssetInformationAsync: async () => {
|
||||
return {
|
||||
duration: this.player.duration() ?? NaN,
|
||||
height: this.player.height() ?? NaN,
|
||||
width: this.player.width() ?? NaN,
|
||||
height: this.player.videoHeight() ?? NaN,
|
||||
width: this.player.videoWidth() ?? NaN,
|
||||
orientation: "unknown",
|
||||
bitrate: NaN,
|
||||
fileSize: BigInt(NaN),
|
||||
fileSize: -1n,
|
||||
isHDR: false,
|
||||
isLive: false,
|
||||
};
|
||||
@@ -399,7 +400,7 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
number,
|
||||
LibraryError | PlayerError | SourceError | UnknownError
|
||||
>;
|
||||
this._emit("onError", new VideoError(codeMap[err.code]!, err.message));
|
||||
this._emit("onError", new VideoError(codeMap[err.code] ?? "unknown/unknown", err.message));
|
||||
}
|
||||
|
||||
_onTextTrackChange() {
|
||||
@@ -450,7 +451,9 @@ export class WebEventEmitter implements VideoPlayerEventEmitterBase {
|
||||
_onQualityChange() {
|
||||
// @ts-expect-error this isn't typed
|
||||
const levels: VideoJsQualityArray = this.player.qualityLevels();
|
||||
const quality = levels[levels.selectedIndex]!;
|
||||
if (levels.selectedIndex < 0) return;
|
||||
const quality = levels[levels.selectedIndex];
|
||||
if (!quality) return;
|
||||
|
||||
this._emit("onQualityChange", {
|
||||
id: quality.id,
|
||||
|
||||
Reference in New Issue
Block a user