This commit is contained in:
Fredrik Burmester
2024-10-11 22:10:47 +02:00
parent 57354e6b06
commit be867a3b10
8 changed files with 773 additions and 512 deletions

View File

@@ -1,7 +1,89 @@
export type ChangeEventPayload = {
value: string;
export type PlaybackStatePayload = {
nativeEvent: {
target: number;
type:
| "Opening"
| "Paused"
| "Stopped"
| "Buffering"
| "Playing"
| "ESAdded"
| "Ended"
| "Error"
| "Unknown";
currentTime: number;
duration: number;
isBuffering?: boolean;
};
};
export type ProgressUpdatePayload = {
nativeEvent: {
currentTime: number;
duration: number;
};
};
export type VideoLoadStartPayload = {
nativeEvent: {
target: number;
};
};
export type VideoStateChangePayload = PlaybackStatePayload;
export type VideoProgressPayload = ProgressUpdatePayload;
export type VlcPlayerSource = {
uri: string;
type?: string;
isNetwork?: boolean;
autoplay?: boolean;
initOptions?: any[];
mediaOptions?: { [key: string]: any };
};
export type TrackInfo = {
name: string;
index: number;
};
export type ChapterInfo = {
name: string;
timeOffset: number;
duration: number;
};
export type VlcPlayerViewProps = {
source: string;
source: VlcPlayerSource;
style?: Object;
progressUpdateInterval?: number;
paused?: boolean;
muted?: boolean;
volume?: number;
videoAspectRatio?: string;
onVideoProgress?: (event: ProgressUpdatePayload) => void;
onVideoStateChange?: (event: PlaybackStatePayload) => void;
onVideoLoadStart?: (event: VideoLoadStartPayload) => void;
};
export interface VlcPlayerViewRef {
play: () => Promise<void>;
pause: () => Promise<void>;
seekTo: (time: number) => Promise<void>;
jumpBackward: (interval: number) => Promise<void>;
jumpForward: (interval: number) => Promise<void>;
setAudioTrack: (trackIndex: number) => Promise<void>;
getAudioTracks: () => Promise<TrackInfo[] | null>;
setSubtitleTrack: (trackIndex: number) => Promise<void>;
getSubtitleTracks: () => Promise<TrackInfo[] | null>;
setSubtitleDelay: (delay: number) => Promise<void>;
setAudioDelay: (delay: number) => Promise<void>;
takeSnapshot: (path: string, width: number, height: number) => Promise<void>;
setRate: (rate: number) => Promise<void>;
nextChapter: () => Promise<void>;
previousChapter: () => Promise<void>;
getChapters: () => Promise<ChapterInfo[] | null>;
setVideoCropGeometry: (geometry: string | null) => Promise<void>;
getVideoCropGeometry: () => Promise<string | null>;
}

View File

@@ -1,13 +0,0 @@
import { EventEmitter } from 'expo-modules-core';
const emitter = new EventEmitter({} as any);
export default {
PI: Math.PI,
async setValueAsync(value: string): Promise<void> {
emitter.emit('onChange', { value });
},
hello() {
return 'Hello world! 👋';
},
};

View File

@@ -1,11 +1,124 @@
import { requireNativeViewManager } from "expo-modules-core";
import * as React from "react";
import { VlcPlayerViewProps } from "./VlcPlayer.types";
import {
VlcPlayerViewProps,
VlcPlayerViewRef,
VlcPlayerSource,
TrackInfo,
ChapterInfo,
} from "./VlcPlayer.types";
const NativeView: React.ComponentType<VlcPlayerViewProps> =
requireNativeViewManager("VlcPlayer");
export default function VlcPlayerView(props: VlcPlayerViewProps) {
return <NativeView {...props} />;
interface NativeViewRef extends VlcPlayerViewRef {
setNativeProps?: (props: Partial<VlcPlayerViewProps>) => void;
}
const NativeViewManager = requireNativeViewManager("VlcPlayer");
// Create a forwarded ref version of the native view
const NativeView = React.forwardRef<NativeViewRef, VlcPlayerViewProps>(
(props, ref) => <NativeViewManager {...props} ref={ref} />
);
const VlcPlayerView = React.forwardRef<VlcPlayerViewRef, VlcPlayerViewProps>(
(props, ref) => {
const nativeRef = React.useRef<NativeViewRef>(null);
React.useImperativeHandle(ref, () => ({
play: async () => {
await nativeRef.current?.play();
},
pause: async () => {
await nativeRef.current?.pause();
},
seekTo: async (time: number) => {
await nativeRef.current?.seekTo(time);
},
jumpBackward: async (interval: number) => {
await nativeRef.current?.jumpBackward(interval);
},
jumpForward: async (interval: number) => {
await nativeRef.current?.jumpForward(interval);
},
setAudioTrack: async (trackIndex: number) => {
await nativeRef.current?.setAudioTrack(trackIndex);
},
getAudioTracks: async () => {
const tracks = await nativeRef.current?.getAudioTracks();
return tracks ?? null;
},
setSubtitleTrack: async (trackIndex: number) => {
await nativeRef.current?.setSubtitleTrack(trackIndex);
},
getSubtitleTracks: async () => {
const tracks = await nativeRef.current?.getSubtitleTracks();
return tracks ?? null;
},
setSubtitleDelay: async (delay: number) => {
await nativeRef.current?.setSubtitleDelay(delay);
},
setAudioDelay: async (delay: number) => {
await nativeRef.current?.setAudioDelay(delay);
},
takeSnapshot: async (path: string, width: number, height: number) => {
await nativeRef.current?.takeSnapshot(path, width, height);
},
setRate: async (rate: number) => {
await nativeRef.current?.setRate(rate);
},
nextChapter: async () => {
await nativeRef.current?.nextChapter();
},
previousChapter: async () => {
await nativeRef.current?.previousChapter();
},
getChapters: async () => {
const chapters = await nativeRef.current?.getChapters();
return chapters ?? null;
},
setVideoCropGeometry: async (geometry: string | null) => {
await nativeRef.current?.setVideoCropGeometry(geometry);
},
getVideoCropGeometry: async () => {
const geometry = await nativeRef.current?.getVideoCropGeometry();
return geometry ?? null;
},
}));
const {
source,
style,
progressUpdateInterval = 500,
paused,
muted,
volume,
videoAspectRatio,
onVideoLoadStart,
onVideoStateChange,
onVideoProgress,
...otherProps
} = props;
const processedSource: VlcPlayerSource =
typeof source === "string" ? { uri: source } : source;
return (
<NativeView
{...otherProps}
ref={nativeRef}
source={processedSource}
style={[{ width: "100%", height: "100%" }, style]}
progressUpdateInterval={progressUpdateInterval}
paused={paused}
muted={muted}
volume={volume}
videoAspectRatio={videoAspectRatio}
onVideoLoadStart={onVideoLoadStart}
onVideoStateChange={onVideoStateChange}
onVideoProgress={onVideoProgress}
/>
);
}
);
export default VlcPlayerView;

View File

@@ -1,11 +0,0 @@
import * as React from 'react';
import { VlcPlayerViewProps } from './VlcPlayer.types';
export default function VlcPlayerView(props: VlcPlayerViewProps) {
return (
<div>
<span>{props.name}</span>
</div>
);
}