mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Fix react-native-video typescript
This commit is contained in:
parent
ecc2b70e43
commit
93608c9549
286
front/packages/ui/src/player/react-native-video.d.ts
vendored
286
front/packages/ui/src/player/react-native-video.d.ts
vendored
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 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 <https://github.com/huhuanming>
|
|
||||||
// Nekith <https://github.com/Nekith>
|
|
||||||
// Philip Frank <https://github.com/bananer>
|
|
||||||
// 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<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<VideoProperties> {
|
|
||||||
presentFullscreenPlayer(): void;
|
|
||||||
dismissFullscreenPlayer(): void;
|
|
||||||
restoreUserInterfaceForPictureInPictureStopCompleted(restored: boolean): void;
|
|
||||||
save(): Promise<void>;
|
|
||||||
seek(time: number, tolerance?: number): void;
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,7 +22,7 @@ import { Audio, Episode, Subtitle, useAccount } from "@kyoo/models";
|
|||||||
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||||
import { useAtomCallback } from "jotai/utils";
|
import { useAtomCallback } from "jotai/utils";
|
||||||
import { ElementRef, memo, useEffect, useLayoutEffect, useRef, useState, useCallback } from "react";
|
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";
|
import { Platform } from "react-native";
|
||||||
|
|
||||||
export const playAtom = atom(true);
|
export const playAtom = atom(true);
|
||||||
|
@ -18,17 +18,17 @@
|
|||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "./react-native-video.d.ts";
|
import "react-native-video";
|
||||||
|
|
||||||
declare module "react-native-video" {
|
declare module "react-native-video" {
|
||||||
interface VideoProperties {
|
interface ReactVideoProps {
|
||||||
fonts?: string[];
|
fonts?: string[];
|
||||||
subtitles?: Subtitle[];
|
subtitles?: Subtitle[];
|
||||||
onPlayPause: (isPlaying: boolean) => void;
|
onPlayPause: (isPlaying: boolean) => void;
|
||||||
onMediaUnsupported?: () => void;
|
onMediaUnsupported?: () => void;
|
||||||
}
|
}
|
||||||
export type VideoProps = Omit<VideoProperties, "source"> & {
|
export type VideoProps = Omit<ReactVideoProps, "source"> & {
|
||||||
source: { uri: string; hls: string | null; startPosition?: number | null };
|
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 { IconButton, Menu } from "@kyoo/primitives";
|
||||||
import { ComponentProps, forwardRef, useEffect, useRef } from "react";
|
import { ComponentProps, forwardRef, useEffect, useRef } from "react";
|
||||||
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
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 { useTranslation } from "react-i18next";
|
||||||
import { PlayMode, audioAtom, playModeAtom, subtitleAtom } from "./state";
|
import { PlayMode, audioAtom, playModeAtom, subtitleAtom } from "./state";
|
||||||
import uuid from "react-native-uuid";
|
import uuid from "react-native-uuid";
|
||||||
@ -57,7 +63,7 @@ const videoAtom = atom(0);
|
|||||||
|
|
||||||
const clientId = uuid.v4() as string;
|
const clientId = uuid.v4() as string;
|
||||||
|
|
||||||
const Video = forwardRef<NativeVideo, VideoProps>(function Video(
|
const Video = forwardRef<VideoRef, VideoProps>(function Video(
|
||||||
{ onLoad, onBuffer, source, onPointerDown, subtitles, ...props },
|
{ onLoad, onBuffer, source, onPointerDown, subtitles, ...props },
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
@ -92,21 +98,25 @@ const Video = forwardRef<NativeVideo, VideoProps>(function Video(
|
|||||||
onLoad?.(info);
|
onLoad?.(info);
|
||||||
}}
|
}}
|
||||||
onBuffer={onBuffer}
|
onBuffer={onBuffer}
|
||||||
selectedVideoTrack={video === -1 ? { type: "auto" } : { type: "resolution", value: video }}
|
selectedVideoTrack={
|
||||||
selectedAudioTrack={{ type: "index", value: audio.index }}
|
video === -1
|
||||||
|
? { type: SelectedVideoTrackType.AUDO }
|
||||||
|
: { type: SelectedVideoTrackType.RESOLUTION, value: video }
|
||||||
|
}
|
||||||
|
selectedAudioTrack={{ type: SelectedTrackType.INDEX, value: audio.index }}
|
||||||
textTracks={subtitles?.map((x) => ({
|
textTracks={subtitles?.map((x) => ({
|
||||||
type: MimeTypes.get(x.codec) as any,
|
type: MimeTypes.get(x.codec) as any,
|
||||||
uri: x.link!,
|
uri: x.link!,
|
||||||
title: x.title ?? "Unknown",
|
title: x.title ?? "Unknown",
|
||||||
language: x.language ?? "Unknown",
|
language: x.language ?? ("Unknown" as any),
|
||||||
}))}
|
}))}
|
||||||
selectedTextTrack={
|
selectedTextTrack={
|
||||||
subtitle
|
subtitle
|
||||||
? {
|
? {
|
||||||
type: "index",
|
type: SelectedTrackType.INDEX,
|
||||||
value: subtitles?.indexOf(subtitle),
|
value: subtitles?.indexOf(subtitle),
|
||||||
}
|
}
|
||||||
: { type: "disabled" }
|
: { type: SelectedTrackType.DISABLED }
|
||||||
}
|
}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
@ -128,7 +138,7 @@ export const AudiosMenu = ({ audios, ...props }: CustomMenu & { audios?: Audio[]
|
|||||||
{info.audioTracks.map((x) => (
|
{info.audioTracks.map((x) => (
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key={x.index}
|
key={x.index}
|
||||||
label={audios?.[x.index].displayName ?? x.title}
|
label={audios?.[x.index].displayName ?? x.title ?? x.language ?? "Unknown"}
|
||||||
selected={audio!.index === x.index}
|
selected={audio!.index === x.index}
|
||||||
onSelect={() => setAudio(x as any)}
|
onSelect={() => setAudio(x as any)}
|
||||||
/>
|
/>
|
||||||
|
@ -170,7 +170,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
if (!d.fatal || !hls?.media) return;
|
if (!d.fatal || !hls?.media) return;
|
||||||
console.warn("Hls error", d);
|
console.warn("Hls error", d);
|
||||||
onError?.call(null, {
|
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);
|
onMediaUnsupported?.call(undefined);
|
||||||
else {
|
else {
|
||||||
onError?.call(null, {
|
onError?.call(null, {
|
||||||
error: { "": "", errorString: ref.current?.error?.message ?? "Unknown error" },
|
error: { errorString: ref.current?.error?.message ?? "Unknown error" },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user