'use strict'; import React, {Component, createRef} from 'react'; import { Alert, GestureResponderEvent, Platform, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import Video, {FilterType, VideoRef, ResizeMode, IgnoreSilentSwitchType, MixWithOthersType} from 'react-native-video'; const filterTypes = [ FilterType.NONE, FilterType.INVERT, FilterType.MONOCHROME, FilterType.POSTERIZE, FilterType.FALSE, FilterType.MAXIMUMCOMPONENT, FilterType.MINIMUMCOMPONENT, FilterType.CHROME, FilterType.FADE, FilterType.INSTANT, FilterType.MONO, FilterType.NOIR, FilterType.PROCESS, FilterType.TONAL, FilterType.TRANSFER, FilterType.SEPIA, ]; type SkinType = 'custom' | 'native' | 'embed' type State = { rate: number, volume: number, muted: boolean, resizeMode: ResizeMode, duration: number, currentTime: number, controls: boolean, paused: boolean, skin: SkinType, ignoreSilentSwitch: IgnoreSilentSwitchType, mixWithOthers: MixWithOthersType, isBuffering: boolean, filter: FilterType, filterEnabled: boolean, } class VideoPlayer extends Component<{}, State> { controlRef: React.RefObject; videoRef: React.RefObject; constructor(props: any) { super(props); this.onLoad = this.onLoad.bind(this); this.onProgress = this.onProgress.bind(this); this.onBuffer = this.onBuffer.bind(this); this.onTouchControl = this.onTouchControl.bind(this); this.controlRef = createRef(); this.videoRef = createRef(); } state: State = { rate: 1, volume: 1, muted: false, resizeMode: ResizeMode.CONTAIN, duration: 0.0, currentTime: 0.0, controls: false, paused: true, skin: 'custom', ignoreSilentSwitch: IgnoreSilentSwitchType.IGNORE, mixWithOthers: MixWithOthersType.DUCK, isBuffering: false, filter: FilterType.NONE, filterEnabled: true, }; onLoad(data: any) { console.log('On load fired!'); console.log(data.duration); this.setState({duration: data.duration}); } onProgress(data: any) { this.setState({currentTime: data.currentTime}); } onBuffer({isBuffering}: {isBuffering: boolean}) { this.setState({isBuffering}); } onTouchControl(e: GestureResponderEvent) { if (!this.controlRef.current || !this.videoRef.current) return; const videoCommands = this.videoRef.current; const touchX = e.nativeEvent.pageX; const duration = this.state.duration; this.controlRef.current.measureInWindow((x, y, width, height) => { const relativeX = touchX - x; const nextTime = (relativeX / width) * duration; videoCommands.seek(nextTime); }); } getCurrentTimePercentage() { if (this.state.currentTime > 0 && this.state.duration !== 0) { return this.state.currentTime / this.state.duration; } else { return 0; } } setFilter(step: number) { let index = filterTypes.indexOf(this.state.filter) + step; if (index === filterTypes.length) { index = 0; } else if (index === -1) { index = filterTypes.length - 1; } this.setState({ filter: filterTypes[index], }); } renderSkinControl(skin: 'custom' | 'native' | 'embed') { const isSelected = this.state.skin == skin; const selectControls = skin == 'native' || skin == 'embed'; return ( { this.setState({ controls: selectControls, skin: skin, }); }}> {skin} ); } renderRateControl(rate: number) { const isSelected = this.state.rate == rate; return ( { this.setState({rate: rate}); }}> {rate}x ); } renderResizeModeControl(resizeMode: ResizeMode) { const isSelected = this.state.resizeMode == resizeMode; return ( { this.setState({resizeMode: resizeMode}); }}> {resizeMode} ); } renderVolumeControl(volume: number) { const isSelected = this.state.volume == volume; return ( { this.setState({volume: volume}); }}> {volume * 100}% ); } renderIgnoreSilentSwitchControl(ignoreSilentSwitch: IgnoreSilentSwitchType) { const isSelected = this.state.ignoreSilentSwitch == ignoreSilentSwitch; return ( { this.setState({ignoreSilentSwitch: ignoreSilentSwitch}); }}> {ignoreSilentSwitch} ); } renderMixWithOthersControl(mixWithOthers: MixWithOthersType) { const isSelected = this.state.mixWithOthers == mixWithOthers; return ( { this.setState({mixWithOthers: mixWithOthers}); }}> {mixWithOthers} ); } renderCustomSkin() { const flexCompleted = this.getCurrentTimePercentage() * 100; const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100; return ( { this.setState({paused: !this.state.paused}); }}> {this.renderSkinControl('custom')} {this.renderSkinControl('native')} {this.renderSkinControl('embed')} {this.state.filterEnabled ? ( { this.setFilter(-1); }}> Previous Filter { this.setFilter(1); }}> Next Filter ) : null} {this.renderRateControl(0.5)} {this.renderRateControl(1.0)} {this.renderRateControl(2.0)} {this.renderVolumeControl(0.5)} {this.renderVolumeControl(1)} {this.renderVolumeControl(1.5)} {this.renderResizeModeControl(ResizeMode.COVER)} {this.renderResizeModeControl(ResizeMode.CONTAIN)} {this.renderResizeModeControl(ResizeMode.STRETCH)} {Platform.OS === 'ios' ? ( <> {this.renderIgnoreSilentSwitchControl(IgnoreSilentSwitchType.IGNORE)} {this.renderIgnoreSilentSwitchControl(IgnoreSilentSwitchType.OBEY)} {this.renderMixWithOthersControl(MixWithOthersType.MIX)} {this.renderMixWithOthersControl(MixWithOthersType.DUCK)} ) : null} ); } renderNativeSkin() { const videoStyle = this.state.skin == 'embed' ? styles.nativeVideoControls : styles.fullScreen; return ( {this.renderSkinControl('custom')} {this.renderSkinControl('native')} {this.renderSkinControl('embed')} {this.state.filterEnabled ? ( { this.setFilter(-1); }}> Previous Filter { this.setFilter(1); }}> Next Filter ) : null} {this.renderRateControl(0.5)} {this.renderRateControl(1.0)} {this.renderRateControl(2.0)} {this.renderVolumeControl(0.5)} {this.renderVolumeControl(1)} {this.renderVolumeControl(1.5)} {this.renderResizeModeControl(ResizeMode.COVER)} {this.renderResizeModeControl(ResizeMode.CONTAIN)} {this.renderResizeModeControl(ResizeMode.STRETCH)} {Platform.OS === 'ios' ? ( <> {this.renderIgnoreSilentSwitchControl(IgnoreSilentSwitchType.IGNORE)} {this.renderIgnoreSilentSwitchControl(IgnoreSilentSwitchType.OBEY)} {this.renderMixWithOthersControl(MixWithOthersType.MIX)} {this.renderMixWithOthersControl(MixWithOthersType.DUCK)} ) : null} ); } render() { return this.state.controls ? this.renderNativeSkin() : this.renderCustomSkin(); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'black', }, fullScreen: { position: 'absolute', top: 0, left: 0, bottom: 0, right: 0, }, controls: { backgroundColor: 'transparent', borderRadius: 5, position: 'absolute', bottom: 44, left: 4, right: 4, }, progress: { flex: 1, flexDirection: 'row', borderRadius: 3, overflow: 'hidden', }, innerProgressCompleted: { height: 20, backgroundColor: '#cccccc', }, innerProgressRemaining: { height: 20, backgroundColor: '#2C2C2C', }, generalControls: { flex: 1, flexDirection: 'row', overflow: 'hidden', paddingBottom: 10, }, skinControl: { flex: 1, flexDirection: 'row', justifyContent: 'center', }, rateControl: { flex: 1, flexDirection: 'row', justifyContent: 'center', }, volumeControl: { flex: 1, flexDirection: 'row', justifyContent: 'center', }, resizeModeControl: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, ignoreSilentSwitchControl: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, mixWithOthersControl: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, controlOption: { alignSelf: 'center', fontSize: 11, color: 'white', paddingLeft: 2, paddingRight: 2, lineHeight: 12, }, nativeVideoControls: { top: 184, height: 300, }, trackingControls: { flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, }); export default VideoPlayer;