feat: bump up fabric example react-native iOS (#3951)
* feat: 🔥 version bump react native for ios FabricExample * feat: ✨ copied newly created basic example TS files
This commit is contained in:
		@@ -0,0 +1,53 @@
 | 
			
		||||
import {Picker} from '@react-native-picker/picker';
 | 
			
		||||
import {Text} from 'react-native';
 | 
			
		||||
import {AudioTrack, SelectedTrack} from 'react-native-video';
 | 
			
		||||
import styles from '../styles';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export interface AudioTrackSelectorType {
 | 
			
		||||
  audioTracks: Array<AudioTrack>;
 | 
			
		||||
  selectedAudioTrack: SelectedTrack | undefined;
 | 
			
		||||
  onValueChange: (arg0: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const AudioTrackSelector = ({
 | 
			
		||||
  audioTracks,
 | 
			
		||||
  selectedAudioTrack,
 | 
			
		||||
  onValueChange,
 | 
			
		||||
}: AudioTrackSelectorType) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Text style={styles.controlOption}>AudioTrack</Text>
 | 
			
		||||
      <Picker
 | 
			
		||||
        style={styles.picker}
 | 
			
		||||
        itemStyle={styles.pickerItem}
 | 
			
		||||
        selectedValue={selectedAudioTrack?.value}
 | 
			
		||||
        onValueChange={itemValue => {
 | 
			
		||||
          if (itemValue !== 'empty') {
 | 
			
		||||
            console.log('on audio value change ' + itemValue);
 | 
			
		||||
            onValueChange(`${itemValue}`);
 | 
			
		||||
          }
 | 
			
		||||
        }}>
 | 
			
		||||
        {audioTracks?.length <= 0 ? (
 | 
			
		||||
          <Picker.Item label={'empty'} value={'empty'} key={'empty'} />
 | 
			
		||||
        ) : (
 | 
			
		||||
          <Picker.Item label={'none'} value={'none'} key={'none'} />
 | 
			
		||||
        )}
 | 
			
		||||
        {audioTracks.map(track => {
 | 
			
		||||
          if (!track) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          return (
 | 
			
		||||
            <Picker.Item
 | 
			
		||||
              label={`${track.language} - ${track.title} - ${track.selected}`}
 | 
			
		||||
              value={`${track.index}`}
 | 
			
		||||
              key={`${track.index}`}
 | 
			
		||||
            />
 | 
			
		||||
          );
 | 
			
		||||
        })}
 | 
			
		||||
      </Picker>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default AudioTrackSelector;
 | 
			
		||||
							
								
								
									
										154
									
								
								examples/FabricExample/src/components/Seeker.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								examples/FabricExample/src/components/Seeker.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
import React, {useCallback, useEffect, useState} from 'react';
 | 
			
		||||
import {PanResponder, View} from 'react-native';
 | 
			
		||||
import styles from '../styles';
 | 
			
		||||
 | 
			
		||||
interface SeekerProps {
 | 
			
		||||
  currentTime: number;
 | 
			
		||||
  duration: number;
 | 
			
		||||
  isLoading: boolean;
 | 
			
		||||
  isUISeeking: boolean;
 | 
			
		||||
  videoSeek: (arg0: number) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Seeker = ({
 | 
			
		||||
  currentTime,
 | 
			
		||||
  duration,
 | 
			
		||||
  isLoading,
 | 
			
		||||
  isUISeeking,
 | 
			
		||||
  videoSeek,
 | 
			
		||||
}: SeekerProps) => {
 | 
			
		||||
  const [seeking, setSeeking] = useState(false);
 | 
			
		||||
  const [seekerPosition, setSeekerPosition] = useState(0);
 | 
			
		||||
  const [seekerWidth, setSeekerWidth] = useState(0);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the position of the seekbar's components
 | 
			
		||||
   * (both fill and handle) according to the
 | 
			
		||||
   * position supplied.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {float} position position in px of seeker handle}
 | 
			
		||||
   */
 | 
			
		||||
  const updateSeekerPosition = useCallback(
 | 
			
		||||
    (position = 0) => {
 | 
			
		||||
      if (position <= 0) {
 | 
			
		||||
        position = 0;
 | 
			
		||||
      } else if (position >= seekerWidth) {
 | 
			
		||||
        position = seekerWidth;
 | 
			
		||||
      }
 | 
			
		||||
      setSeekerPosition(position);
 | 
			
		||||
    },
 | 
			
		||||
    [seekerWidth],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the time that the video should be at
 | 
			
		||||
   * based on where the seeker handle is.
 | 
			
		||||
   *
 | 
			
		||||
   * @return {float} time in ms based on seekerPosition.
 | 
			
		||||
   */
 | 
			
		||||
  const calculateTimeFromSeekerPosition = () => {
 | 
			
		||||
    const percent = seekerPosition / seekerWidth;
 | 
			
		||||
    return duration * percent;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get our seekbar responder going
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  const seekPanResponder = PanResponder.create({
 | 
			
		||||
    // Ask to be the responder.
 | 
			
		||||
    onStartShouldSetPanResponder: (_evt, _gestureState) => true,
 | 
			
		||||
    onMoveShouldSetPanResponder: (_evt, _gestureState) => true,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * When we start the pan tell the machine that we're
 | 
			
		||||
     * seeking. This stops it from updating the seekbar
 | 
			
		||||
     * position in the onProgress listener.
 | 
			
		||||
     */
 | 
			
		||||
    onPanResponderGrant: (evt, _gestureState) => {
 | 
			
		||||
      const position = evt.nativeEvent.locationX;
 | 
			
		||||
      updateSeekerPosition(position);
 | 
			
		||||
      setSeeking(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * When panning, update the seekbar position, duh.
 | 
			
		||||
     */
 | 
			
		||||
    onPanResponderMove: (evt, _gestureState) => {
 | 
			
		||||
      const position = evt.nativeEvent.locationX;
 | 
			
		||||
      updateSeekerPosition(position);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * On release we update the time and seek to it in the video.
 | 
			
		||||
     * If you seek to the end of the video we fire the
 | 
			
		||||
     * onEnd callback
 | 
			
		||||
     */
 | 
			
		||||
    onPanResponderRelease: (_evt, _gestureState) => {
 | 
			
		||||
      const time = calculateTimeFromSeekerPosition();
 | 
			
		||||
      if (time >= duration && !isLoading) {
 | 
			
		||||
        // FIXME ...
 | 
			
		||||
        // state.paused = true;
 | 
			
		||||
        // this.onEnd();
 | 
			
		||||
      } else {
 | 
			
		||||
        videoSeek(time);
 | 
			
		||||
        setSeeking(false);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (!isLoading && !seeking && !isUISeeking) {
 | 
			
		||||
      const percent = currentTime / duration;
 | 
			
		||||
      const position = seekerWidth * percent;
 | 
			
		||||
      updateSeekerPosition(position);
 | 
			
		||||
    }
 | 
			
		||||
  }, [
 | 
			
		||||
    currentTime,
 | 
			
		||||
    duration,
 | 
			
		||||
    isLoading,
 | 
			
		||||
    seekerWidth,
 | 
			
		||||
    seeking,
 | 
			
		||||
    isUISeeking,
 | 
			
		||||
    updateSeekerPosition,
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  if (!seekPanResponder) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
  const seekerStyle = [
 | 
			
		||||
    styles.seekbarFill,
 | 
			
		||||
    {
 | 
			
		||||
      width: seekerPosition > 0 ? seekerPosition : 0,
 | 
			
		||||
      backgroundColor: '#FFF',
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  const seekerPositionStyle = [
 | 
			
		||||
    styles.seekbarHandle,
 | 
			
		||||
    {
 | 
			
		||||
      left: seekerPosition > 0 ? seekerPosition : 0,
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  const seekerPointerStyle = [styles.seekbarCircle, {backgroundColor: '#FFF'}];
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <View
 | 
			
		||||
      style={styles.seekbarContainer}
 | 
			
		||||
      {...seekPanResponder.panHandlers}
 | 
			
		||||
      {...styles.generalControls}>
 | 
			
		||||
      <View
 | 
			
		||||
        style={styles.seekbarTrack}
 | 
			
		||||
        onLayout={event => setSeekerWidth(event.nativeEvent.layout.width)}
 | 
			
		||||
        pointerEvents={'none'}>
 | 
			
		||||
        <View style={seekerStyle} pointerEvents={'none'} />
 | 
			
		||||
      </View>
 | 
			
		||||
      <View style={seekerPositionStyle} pointerEvents={'none'}>
 | 
			
		||||
        <View style={seekerPointerStyle} pointerEvents={'none'} />
 | 
			
		||||
      </View>
 | 
			
		||||
    </View>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Seeker;
 | 
			
		||||
							
								
								
									
										64
									
								
								examples/FabricExample/src/components/TextTracksSelector.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								examples/FabricExample/src/components/TextTracksSelector.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
import {Picker} from '@react-native-picker/picker';
 | 
			
		||||
import {Text} from 'react-native';
 | 
			
		||||
import {TextTrack, SelectedTrack} from 'react-native-video';
 | 
			
		||||
import styles from '../styles';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export interface TextTrackSelectorType {
 | 
			
		||||
  textTracks: Array<TextTrack>;
 | 
			
		||||
  selectedTextTrack: SelectedTrack | undefined;
 | 
			
		||||
  onValueChange: (arg0: string) => void;
 | 
			
		||||
  textTracksSelectionBy: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const TextTrackSelector = ({
 | 
			
		||||
  textTracks,
 | 
			
		||||
  selectedTextTrack,
 | 
			
		||||
  onValueChange,
 | 
			
		||||
  textTracksSelectionBy,
 | 
			
		||||
}: TextTrackSelectorType) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Text style={styles.controlOption}>TextTrack</Text>
 | 
			
		||||
      <Picker
 | 
			
		||||
        style={styles.picker}
 | 
			
		||||
        itemStyle={styles.pickerItem}
 | 
			
		||||
        selectedValue={`${selectedTextTrack?.value}`}
 | 
			
		||||
        onValueChange={itemValue => {
 | 
			
		||||
          if (itemValue !== 'empty') {
 | 
			
		||||
            onValueChange(itemValue);
 | 
			
		||||
          }
 | 
			
		||||
        }}>
 | 
			
		||||
        {textTracks?.length <= 0 ? (
 | 
			
		||||
          <Picker.Item label={'empty'} value={'empty'} key={'empty'} />
 | 
			
		||||
        ) : (
 | 
			
		||||
          <Picker.Item label={'none'} value={'none'} key={'none'} />
 | 
			
		||||
        )}
 | 
			
		||||
        {textTracks.map(track => {
 | 
			
		||||
          if (!track) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (textTracksSelectionBy === 'index') {
 | 
			
		||||
            return (
 | 
			
		||||
              <Picker.Item
 | 
			
		||||
                label={`${track.index}`}
 | 
			
		||||
                value={track.index}
 | 
			
		||||
                key={track.index}
 | 
			
		||||
              />
 | 
			
		||||
            );
 | 
			
		||||
          } else {
 | 
			
		||||
            return (
 | 
			
		||||
              <Picker.Item
 | 
			
		||||
                label={track.language}
 | 
			
		||||
                value={track.language}
 | 
			
		||||
                key={track.language}
 | 
			
		||||
              />
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        })}
 | 
			
		||||
      </Picker>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default TextTrackSelector;
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
import {Picker} from '@react-native-picker/picker';
 | 
			
		||||
import {Text} from 'react-native';
 | 
			
		||||
import {
 | 
			
		||||
  SelectedVideoTrack,
 | 
			
		||||
  SelectedVideoTrackType,
 | 
			
		||||
  VideoTrack,
 | 
			
		||||
} from 'react-native-video';
 | 
			
		||||
import styles from '../styles';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export interface VideoTrackSelectorType {
 | 
			
		||||
  videoTracks: Array<VideoTrack>;
 | 
			
		||||
  selectedVideoTrack: SelectedVideoTrack | undefined;
 | 
			
		||||
  onValueChange: (arg0: string) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const VideoTrackSelector = ({
 | 
			
		||||
  videoTracks,
 | 
			
		||||
  selectedVideoTrack,
 | 
			
		||||
  onValueChange,
 | 
			
		||||
}: VideoTrackSelectorType) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Text style={styles.controlOption}>VideoTrack</Text>
 | 
			
		||||
      <Picker
 | 
			
		||||
        style={styles.picker}
 | 
			
		||||
        itemStyle={styles.pickerItem}
 | 
			
		||||
        selectedValue={
 | 
			
		||||
          selectedVideoTrack === undefined ||
 | 
			
		||||
          selectedVideoTrack?.type === SelectedVideoTrackType.AUTO
 | 
			
		||||
            ? 'auto'
 | 
			
		||||
            : `${selectedVideoTrack?.value}`
 | 
			
		||||
        }
 | 
			
		||||
        onValueChange={itemValue => {
 | 
			
		||||
          if (itemValue !== 'empty') {
 | 
			
		||||
            onValueChange(itemValue);
 | 
			
		||||
          }
 | 
			
		||||
        }}>
 | 
			
		||||
        <Picker.Item label={'auto'} value={'auto'} key={'auto'} />
 | 
			
		||||
        {videoTracks?.length <= 0 || videoTracks?.length <= 0 ? (
 | 
			
		||||
          <Picker.Item label={'empty'} value={'empty'} key={'empty'} />
 | 
			
		||||
        ) : (
 | 
			
		||||
          <Picker.Item label={'none'} value={'none'} key={'none'} />
 | 
			
		||||
        )}
 | 
			
		||||
        {videoTracks?.map(track => {
 | 
			
		||||
          if (!track) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          return (
 | 
			
		||||
            <Picker.Item
 | 
			
		||||
              label={`${track.width}x${track.height} ${Math.floor(
 | 
			
		||||
                (track.bitrate || 0) / 8 / 1024,
 | 
			
		||||
              )} Kbps`}
 | 
			
		||||
              value={`${track.index}`}
 | 
			
		||||
              key={track.index}
 | 
			
		||||
            />
 | 
			
		||||
          );
 | 
			
		||||
        })}
 | 
			
		||||
      </Picker>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default VideoTrackSelector;
 | 
			
		||||
		Reference in New Issue
	
	Block a user