diff --git a/front/packages/ui/src/player/react-native-video.d.ts b/front/packages/ui/src/player/react-native-video.d.ts
deleted file mode 100644
index eae2a736..00000000
--- a/front/packages/ui/src/player/react-native-video.d.ts
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Kyoo - A portable and vast media library solution.
- * Copyright (c) Kyoo.
- *
- * See AUTHORS.md and LICENSE file in the project root for full license information.
- *
- * Kyoo is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * Kyoo is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Kyoo. If not, see .
- */
-
-// Type definitions for react-native-video 5.0
-// Project: https://github.com/react-native-community/react-native-video, https://github.com/brentvatne/react-native-video
-// Definitions by: HuHuanming
-// Nekith
-// Philip Frank
-// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
-// TypeScript Version: 2.8
-
-declare module "react-native-video" {
- import * as React from "react";
- import { ViewProps } from "react-native";
-
- export interface OnLoadData {
- canPlayFastForward: boolean;
- canPlayReverse: boolean;
- canPlaySlowForward: boolean;
- canPlaySlowReverse: boolean;
- canStepBackward: boolean;
- canStepForward: boolean;
- currentPosition: number;
- currentTime: number;
- duration: number;
- naturalSize: {
- height: number;
- width: number;
- orientation: "portrait" | "landscape";
- };
- videoTracks: Array<{
- bitrate: number;
- codecs: string;
- width: number;
- height: number;
- trackId: string;
- }>;
- audioTracks: Array<{
- index: number;
- title: string;
- language: string;
- type: string;
- }>;
- textTracks: Array<{
- index: number;
- title: string;
- language: string;
- type: string;
- }>;
- }
-
- export interface OnProgressData {
- currentTime: number;
- playableDuration: number;
- seekableDuration: number;
- }
-
- export interface OnBandwidthUpdateData {
- bitrate: number;
- }
-
- export interface LoadError {
- error: {
- "": string;
- errorString: string;
- };
- }
-
- export interface OnSeekData {
- currentTime: number;
- seekTime: number;
- target?: number | undefined;
- }
-
- export interface OnPlaybackRateData {
- playbackRate: number;
- }
-
- export interface OnPictureInPictureStatusData {
- isActive: boolean;
- }
-
- export interface OnExternalPlaybackChangeData {
- isExternalPlaybackActive: boolean;
- }
-
- export interface OnBufferData {
- isBuffering: boolean;
- }
-
- export interface DRMSettings {
- type: DRMType;
- licenseServer?: string | undefined;
- headers?: { [key: string]: string } | undefined;
- contentId?: string | undefined;
- certificateUrl?: string | undefined;
- base64Certificate?: boolean | undefined;
- getLicense?(spcString: string): Promise;
- }
-
- export const TextTrackType: {
- SRT: "application/x-subrip";
- TTML: "application/ttml+xml";
- VTT: "text/vtt";
- };
-
- export enum FilterType {
- NONE = "",
- INVERT = "CIColorInvert",
- MONOCHROME = "CIColorMonochrome",
- POSTERIZE = "CIColorPosterize",
- FALSE = "CIFalseColor",
- MAXIMUMCOMPONENT = "CIMaximumComponent",
- MINIMUMCOMPONENT = "CIMinimumComponent",
- CHROME = "CIPhotoEffectChrome",
- FADE = "CIPhotoEffectFade",
- INSTANT = "CIPhotoEffectInstant",
- MONO = "CIPhotoEffectMono",
- NOIR = "CIPhotoEffectNoir",
- PROCESS = "CIPhotoEffectProcess",
- TONAL = "CIPhotoEffectTonal",
- TRANSFER = "CIPhotoEffectTransfer",
- SEPIA = "CISepiaTone",
- }
-
- export enum DRMType {
- WIDEVINE = "widevine",
- PLAYREADY = "playready",
- CLEARKEY = "clearkey",
- FAIRPLAY = "fairplay",
- }
-
- export interface VideoProperties extends ViewProps {
- filter?: FilterType | undefined;
- filterEnabled?: boolean | undefined;
-
- /* Native only */
- src?: any;
- seek?: number | undefined;
- fullscreen?: boolean | undefined;
- fullscreenOrientation?: "all" | "landscape" | "portrait" | undefined;
- fullscreenAutorotate?: boolean | undefined;
- onVideoLoadStart?(): void;
- onVideoLoad?(): void;
- onVideoBuffer?(): void;
- onVideoError?(): void;
- onVideoProgress?(): void;
- onVideoSeek?(): void;
- onVideoEnd?(): void;
- onTimedMetadata?(): void;
- onVideoFullscreenPlayerWillPresent?(): void;
- onVideoFullscreenPlayerDidPresent?(): void;
- onVideoFullscreenPlayerWillDismiss?(): void;
- onVideoFullscreenPlayerDidDismiss?(): void;
-
- /* Wrapper component */
- // Opaque type returned by require('./video.mp4')
- source:
- | {
- uri?: string | undefined;
- headers?: { [key: string]: string } | undefined;
- type?: string | undefined;
- }
- | number;
- minLoadRetryCount?: number | undefined;
- maxBitRate?: number | undefined;
- resizeMode?: "stretch" | "contain" | "cover" | "none" | undefined; // via Image#resizeMode
- posterResizeMode?: "stretch" | "contain" | "cover" | "none" | undefined; // via Image#resizeMode
- poster?: string | undefined;
- repeat?: boolean | undefined;
- automaticallyWaitsToMinimizeStalling?: boolean | undefined;
- paused?: boolean | undefined;
- muted?: boolean | undefined;
- volume?: number | undefined;
- bufferConfig?:
- | {
- minBufferMs?: number | undefined;
- maxBufferMs?: number | undefined;
- bufferForPlaybackMs?: number | undefined;
- bufferForPlaybackAfterRebufferMs?: number | undefined;
- }
- | undefined;
- stereoPan?: number | undefined;
- rate?: number | undefined;
- pictureInPicture?: boolean | undefined;
- playInBackground?: boolean | undefined;
- playWhenInactive?: boolean | undefined;
- ignoreSilentSwitch?: "ignore" | "obey" | undefined;
- mixWithOthers?: "inherit" | "mix" | "duck" | undefined;
- reportBandwidth?: boolean | undefined;
- disableFocus?: boolean | undefined;
- controls?: boolean | undefined;
- currentTime?: number | undefined;
- progressUpdateInterval?: number | undefined;
- useTextureView?: boolean | undefined;
- hideShutterView?: boolean | undefined;
- shutterColor?: string;
- frameQuality?: number;
- onFrameChange?: (base64ImageString: string) => void;
- allowsExternalPlayback?: boolean | undefined;
- audioOnly?: boolean | undefined;
- preventsDisplaySleepDuringVideoPlayback?: boolean | undefined;
- drm?: DRMSettings | undefined;
- preferredForwardBufferDuration?: number | undefined;
-
- onLoadStart?(): void;
- onLoad?(data: OnLoadData): void;
- onBuffer?(data: OnBufferData): void;
- onError?(error: LoadError): void;
- onProgress?(data: OnProgressData): void;
- onBandwidthUpdate?(data: OnBandwidthUpdateData): void;
- onSeek?(data: OnSeekData): void;
- onEnd?(): void;
- onFullscreenPlayerWillPresent?(): void;
- onFullscreenPlayerDidPresent?(): void;
- onFullscreenPlayerWillDismiss?(): void;
- onFullscreenPlayerDidDismiss?(): void;
- onReadyForDisplay?(): void;
- onPlaybackStalled?(): void;
- onPlaybackResume?(): void;
- onPlaybackRateChange?(data: OnPlaybackRateData): void;
- onAudioFocusChanged?(): void;
- onAudioBecomingNoisy?(): void;
- onPictureInPictureStatusChanged?(data: OnPictureInPictureStatusData): void;
- onRestoreUserInterfaceForPictureInPictureStop?(): void;
- onExternalPlaybackChange?(data: OnExternalPlaybackChangeData): void;
- selectedAudioTrack?:
- | {
- type: "system" | "disabled" | "title" | "language" | "index";
- value?: string | number | undefined;
- }
- | undefined;
- selectedTextTrack?:
- | {
- type: "system" | "disabled" | "title" | "language" | "index";
- value?: string | number | undefined;
- }
- | undefined;
- selectedVideoTrack?:
- | {
- type: "auto" | "disabled" | "resolution" | "index";
- value?: string | number | undefined;
- }
- | undefined;
- textTracks?:
- | Array<{
- title?: string | undefined;
- language?: string | undefined;
- type: "application/x-subrip" | "application/ttml+xml" | "text/vtt";
- uri: string;
- }>
- | undefined;
-
- /* Required by react-native */
- scaleX?: number | undefined;
- scaleY?: number | undefined;
- translateX?: number | undefined;
- translateY?: number | undefined;
- rotation?: number | undefined;
- }
-
- export default class Video extends React.Component {
- presentFullscreenPlayer(): void;
- dismissFullscreenPlayer(): void;
- restoreUserInterfaceForPictureInPictureStopCompleted(restored: boolean): void;
- save(): Promise;
- seek(time: number, tolerance?: number): void;
- }
-}
diff --git a/front/packages/ui/src/player/state.tsx b/front/packages/ui/src/player/state.tsx
index 63cfdf75..5df8e813 100644
--- a/front/packages/ui/src/player/state.tsx
+++ b/front/packages/ui/src/player/state.tsx
@@ -22,7 +22,7 @@ import { Audio, Episode, Subtitle, useAccount } from "@kyoo/models";
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
import { useAtomCallback } from "jotai/utils";
import { ElementRef, memo, useEffect, useLayoutEffect, useRef, useState, useCallback } from "react";
-import NativeVideo, { VideoProperties as VideoProps } from "./video";
+import NativeVideo, { VideoProps } from "./video";
import { Platform } from "react-native";
export const playAtom = atom(true);
diff --git a/front/packages/ui/src/player/video.tsx b/front/packages/ui/src/player/video.tsx
index 9f65d143..9a8221b7 100644
--- a/front/packages/ui/src/player/video.tsx
+++ b/front/packages/ui/src/player/video.tsx
@@ -18,17 +18,17 @@
* along with Kyoo. If not, see .
*/
-import "./react-native-video.d.ts";
+import "react-native-video";
declare module "react-native-video" {
- interface VideoProperties {
+ interface ReactVideoProps {
fonts?: string[];
subtitles?: Subtitle[];
onPlayPause: (isPlaying: boolean) => void;
onMediaUnsupported?: () => void;
}
- export type VideoProps = Omit & {
- source: { uri: string; hls: string | null; startPosition?: number | null };
+ export type VideoProps = Omit & {
+ source: { uri: string; hls: string | null; startPosition?: number };
};
}
@@ -38,7 +38,13 @@ import { Audio, Subtitle, getToken } from "@kyoo/models";
import { IconButton, Menu } from "@kyoo/primitives";
import { ComponentProps, forwardRef, useEffect, useRef } from "react";
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
-import NativeVideo, { OnLoadData, VideoProps } from "react-native-video";
+import NativeVideo, {
+ VideoRef,
+ OnLoadData,
+ VideoProps,
+ SelectedTrackType,
+ SelectedVideoTrackType,
+} from "react-native-video";
import { useTranslation } from "react-i18next";
import { PlayMode, audioAtom, playModeAtom, subtitleAtom } from "./state";
import uuid from "react-native-uuid";
@@ -57,7 +63,7 @@ const videoAtom = atom(0);
const clientId = uuid.v4() as string;
-const Video = forwardRef(function Video(
+const Video = forwardRef(function Video(
{ onLoad, onBuffer, source, onPointerDown, subtitles, ...props },
ref,
) {
@@ -92,21 +98,25 @@ const Video = forwardRef(function Video(
onLoad?.(info);
}}
onBuffer={onBuffer}
- selectedVideoTrack={video === -1 ? { type: "auto" } : { type: "resolution", value: video }}
- selectedAudioTrack={{ type: "index", value: audio.index }}
+ selectedVideoTrack={
+ video === -1
+ ? { type: SelectedVideoTrackType.AUDO }
+ : { type: SelectedVideoTrackType.RESOLUTION, value: video }
+ }
+ selectedAudioTrack={{ type: SelectedTrackType.INDEX, value: audio.index }}
textTracks={subtitles?.map((x) => ({
type: MimeTypes.get(x.codec) as any,
uri: x.link!,
title: x.title ?? "Unknown",
- language: x.language ?? "Unknown",
+ language: x.language ?? ("Unknown" as any),
}))}
selectedTextTrack={
subtitle
? {
- type: "index",
+ type: SelectedTrackType.INDEX,
value: subtitles?.indexOf(subtitle),
}
- : { type: "disabled" }
+ : { type: SelectedTrackType.DISABLED }
}
{...props}
/>
@@ -128,7 +138,7 @@ export const AudiosMenu = ({ audios, ...props }: CustomMenu & { audios?: Audio[]
{info.audioTracks.map((x) => (
setAudio(x as any)}
/>
diff --git a/front/packages/ui/src/player/video.web.tsx b/front/packages/ui/src/player/video.web.tsx
index 1165c4a5..dfdc55ad 100644
--- a/front/packages/ui/src/player/video.web.tsx
+++ b/front/packages/ui/src/player/video.web.tsx
@@ -170,7 +170,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
if (!d.fatal || !hls?.media) return;
console.warn("Hls error", d);
onError?.call(null, {
- error: { "": "", errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
+ error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
});
});
}
@@ -230,7 +230,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
onMediaUnsupported?.call(undefined);
else {
onError?.call(null, {
- error: { "": "", errorString: ref.current?.error?.message ?? "Unknown error" },
+ error: { errorString: ref.current?.error?.message ?? "Unknown error" },
});
}
}}