Video Controller

 avatar
unknown
plain_text
10 months ago
2.4 kB
13
Indexable
import { useEffect, useRef, useState } from 'react';
import { View } from 'react-native';

import { QualitySelector } from './QualitySelector';
import { VideoPlayer } from './VideoPlayer';

import { ErrorScreen } from '~components';
import i18n from '~locales';
import { PlayerState, Quality } from '~types';

type Props = {
  qualities: Quality[];
  thumb?: string;
};

export const PlayerController = ({ qualities, thumb }: Props) => {
  const [active, setActive] = useState(0);
  const [switching, setSwitching] = useState(false);

  const [players, setPlayers] = useState<PlayerState[]>([
    { quality: 0, currentTime: 0, ref: useRef(null), loading: true },
    { quality: null, currentTime: 0, ref: useRef(null), loading: true },
  ]);

  const updatePlayer = (i: number, patch: Partial<PlayerState>) => {
    setPlayers(prev => {
      const updated = [...prev];
      updated[i] = { ...updated[i], ...patch };
      return updated;
    });
  };

  const newPlayer = 1 - active;
  const readyToSwitch = () => switching && !players[newPlayer].loading;
  const seekTo = (id: number, time: number) => players[id].ref?.current?.seek(time);
  const exitFullscreen = (id: number) =>
    players[id].ref?.current?.dismissFullscreenPlayer();

  useEffect(() => {
    if (readyToSwitch()) {
      setSwitching(false);
      seekTo(newPlayer, players[active].currentTime);
      exitFullscreen(active);
      updatePlayer(active, { quality: null });
      setActive(newPlayer);
    }
  }, [players, switching, active]);

  const onChangeQuality = (qualityIndex: number) => {
    updatePlayer(newPlayer, {
      quality: qualityIndex,
      loading: true,
    });

    setSwitching(true);
  };

  if (!qualities || qualities.length === 0) {
    return <ErrorScreen data={{ message: i18n.t('errorMsg') }} />;
  }

  return (
    <View style={{ flex: 1 }}>
      {[0, 1].map(i => (
        <VideoPlayer
          key={i}
          active={active === i}
          state={players[i]}
          updateState={state => updatePlayer(i, state)}
          thumbUrl={thumb}
          videoUrl={
            players[i].quality !== null ? qualities[players[i].quality].url : null
          }
        />
      ))}

      <QualitySelector
        qualities={qualities}
        selectedQuality={players[active].quality}
        onSelectQuality={onChangeQuality}
        disabled={switching}
      />
    </View>
  );
};
Editor is loading...
Leave a Comment