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