import React, {forwardRef, memo, useCallback} from 'react'; import {Indicator} from './Indicator.tsx'; import {View} from 'react-native'; import styles from '../styles.tsx'; import ToggleControl from '../ToggleControl.tsx'; import { isAndroid, isIos, samplePoster, textTracksSelectionBy, } from '../constants'; import MultiValueControl, { MultiValueControlPropType, } from '../MultiValueControl.tsx'; import { AudioTrack, EnumValues, ResizeMode, SelectedTrack, SelectedTrackType, SelectedVideoTrack, SelectedVideoTrackType, TextTrack, VideoDecoderProperties, VideoRef, VideoTrack, } from 'react-native-video'; import { toast, Seeker, AudioTrackSelector, TextTrackSelector, VideoTrackSelector, TopControl, } from '../components'; type Props = { channelDown: () => void; channelUp: () => void; fullscreen: boolean; setFullscreen: (value: boolean) => void; controls: boolean; setControls: (value: boolean) => void; decoration: boolean; setDecoration: (value: boolean) => void; showNotificationControls: boolean; setShowNotificationControls: (value: boolean) => void; selectedAudioTrack: SelectedTrack | undefined; setSelectedAudioTrack: (value: SelectedTrack | undefined) => void; selectedTextTrack: SelectedTrack | undefined; setSelectedTextTrack: (value: SelectedTrack | undefined) => void; selectedVideoTrack: SelectedVideoTrack; setSelectedVideoTrack: (value: SelectedVideoTrack) => void; setIsSeeking: (value: boolean) => void; rate: number; setRate: (value: number) => void; volume: number; setVolume: (value: number) => void; resizeMode: EnumValues; setResizeMode: (value: EnumValues) => void; isLoading: boolean; srcListId: number; useCache: boolean; setUseCache: (value: boolean) => void; paused: boolean; setPaused: (value: boolean) => void; repeat: boolean; setRepeat: (value: boolean) => void; poster: string | undefined; setPoster: (value: string | undefined) => void; muted: boolean; setMuted: (value: boolean) => void; currentTime: number; duration: number; isSeeking: boolean; audioTracks: AudioTrack[]; textTracks: TextTrack[]; videoTracks: VideoTrack[]; }; const _Overlay = forwardRef((props, ref) => { const { channelUp, channelDown, setFullscreen, fullscreen, setControls, controls, setDecoration, decoration, setShowNotificationControls, showNotificationControls, setSelectedAudioTrack, setSelectedTextTrack, setSelectedVideoTrack, setIsSeeking, rate, setRate, volume, setVolume, resizeMode, setResizeMode, isLoading, srcListId, setUseCache, useCache, paused, setPaused, setRepeat, repeat, setPoster, poster, setMuted, muted, duration, isSeeking, currentTime, textTracks, videoTracks, audioTracks, selectedAudioTrack, selectedVideoTrack, selectedTextTrack, } = props; const popupInfo = useCallback(() => { VideoDecoderProperties.getWidevineLevel().then((widevineLevel: number) => { VideoDecoderProperties.isHEVCSupported().then((hevc: string) => { VideoDecoderProperties.isCodecSupported('video/avc', 1920, 1080).then( (avc: string) => { toast( true, 'Widevine level: ' + widevineLevel + '\n hevc: ' + hevc + '\n avc: ' + avc, ); }, ); }); }); }, []); const toggleFullscreen = () => { setFullscreen(!fullscreen); }; const toggleControls = () => { setControls(!controls); }; const toggleDecoration = () => { setDecoration(!decoration); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error ref.current?.setFullScreen(!decoration); }; const toggleShowNotificationControls = () => { setShowNotificationControls(!showNotificationControls); }; const onSelectedAudioTrackChange = (itemValue: string) => { console.log('on audio value change ' + itemValue); if (itemValue === 'none') { setSelectedAudioTrack({ type: SelectedTrackType.DISABLED, }); } else { setSelectedAudioTrack({ type: SelectedTrackType.INDEX, value: itemValue, }); } }; const onSelectedTextTrackChange = (itemValue: string) => { console.log('on value change ' + itemValue); const type = textTracksSelectionBy === 'index' ? SelectedTrackType.INDEX : SelectedTrackType.LANGUAGE; setSelectedTextTrack({type, value: itemValue}); }; const onSelectedVideoTrackChange = (itemValue: string) => { console.log('on value change ' + itemValue); if (itemValue === undefined || itemValue === 'auto') { setSelectedVideoTrack({ type: SelectedVideoTrackType.AUTO, }); } else { setSelectedVideoTrack({ type: SelectedVideoTrackType.INDEX, value: itemValue, }); } }; const videoSeek = (position: number) => { setIsSeeking(true); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error ref.current?.seek(position); }; const onRateSelected = (value: MultiValueControlPropType) => { if (typeof value === 'number') { setRate(value); } }; const onVolumeSelected = (value: MultiValueControlPropType) => { if (typeof value === 'number') { setVolume(value); } }; const onResizeModeSelected = (value: MultiValueControlPropType) => { if (typeof value === 'string') { setResizeMode(value as EnumValues); } }; const toggleCache = () => setUseCache(!useCache); const togglePause = () => setPaused(!paused); const toggleRepeat = () => setRepeat(!repeat); const togglePoster = () => setPoster(poster ? undefined : samplePoster); const toggleMuted = () => setMuted(!muted); return ( <> {!controls ? ( <> {isAndroid ? ( ) : null} {/* shall be replaced by slider */} {/* shall be replaced by slider */} {isIos ? ( { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error ref.current ?.save({}) ?.then((response: unknown) => { console.log('Downloaded URI', response); }) .catch((error: unknown) => { console.log('error during save ', error); }); }} text="save" /> ) : null} videoSeek(prop)} isUISeeking={isSeeking} /> ) : null} ); }); export const Overlay = memo(_Overlay);