From 1f0137608a541118dcf0b419c74b4fdf4f75f008 Mon Sep 17 00:00:00 2001
From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com>
Date: Sat, 7 Oct 2023 23:14:09 +0200
Subject: [PATCH] feat(sample): merge ios and android samples (#3015)
* chore: split components
---
examples/basic/ios/Podfile.lock | 12 +-
.../ios/videoplayer.xcodeproj/project.pbxproj | 8 +-
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
examples/basic/src/MultiValueControl.tsx | 67 ++
examples/basic/src/ToggleControl.tsx | 68 ++
examples/basic/src/VideoPlayer.ios.tsx | 475 ------------
...ideoPlayer.android.tsx => VideoPlayer.tsx} | 680 ++++++++----------
7 files changed, 463 insertions(+), 855 deletions(-)
create mode 100644 examples/basic/ios/videoplayer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 examples/basic/src/MultiValueControl.tsx
create mode 100644 examples/basic/src/ToggleControl.tsx
delete mode 100644 examples/basic/src/VideoPlayer.ios.tsx
rename examples/basic/src/{VideoPlayer.android.tsx => VideoPlayer.tsx} (55%)
diff --git a/examples/basic/ios/Podfile.lock b/examples/basic/ios/Podfile.lock
index cb4b91ef..89b3029e 100644
--- a/examples/basic/ios/Podfile.lock
+++ b/examples/basic/ios/Podfile.lock
@@ -75,9 +75,9 @@ PODS:
- hermes-engine/Pre-built (0.72.5)
- libevent (2.1.12)
- OpenSSL-Universal (1.1.1100)
- - PromisesObjC (2.3.1)
- - PromisesSwift (2.3.1):
- - PromisesObjC (= 2.3.1)
+ - PromisesObjC (2.2.0)
+ - PromisesSwift (2.2.0):
+ - PromisesObjC (= 2.2.0)
- RCT-Folly (2021.07.22.00):
- boost
- DoubleConversion
@@ -691,8 +691,8 @@ SPEC CHECKSUMS:
hermes-engine: f6cf92a471053245614d9d8097736f6337d5b86c
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
- PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
- PromisesSwift: 28dca69a9c40779916ac2d6985a0192a5cb4a265
+ PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
+ PromisesSwift: cf9eb58666a43bbe007302226e510b16c1e10959
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
RCTRequired: df81ab637d35fac9e6eb94611cfd20f0feb05455
RCTTypeSafety: 4636e4a36c7c2df332bda6d59b19b41c443d4287
@@ -733,4 +733,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 6899e375fcfa0d3a42aa6cb55266008b8f7419cb
-COCOAPODS: 1.13.0
+COCOAPODS: 1.12.1
diff --git a/examples/basic/ios/videoplayer.xcodeproj/project.pbxproj b/examples/basic/ios/videoplayer.xcodeproj/project.pbxproj
index f7a31159..d33eb0db 100644
--- a/examples/basic/ios/videoplayer.xcodeproj/project.pbxproj
+++ b/examples/basic/ios/videoplayer.xcodeproj/project.pbxproj
@@ -525,7 +525,7 @@
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
- PRODUCT_NAME = videoplayer;
+ PRODUCT_NAME = videoplayer;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
@@ -602,10 +602,7 @@
);
OTHER_LDFLAGS = (
"$(inherited)",
- "-Wl",
- "-ld_classic",
" ",
- "-Wl -ld_classic ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
@@ -678,10 +675,7 @@
);
OTHER_LDFLAGS = (
"$(inherited)",
- "-Wl",
- "-ld_classic",
" ",
- "-Wl -ld_classic ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
diff --git a/examples/basic/ios/videoplayer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/basic/ios/videoplayer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/examples/basic/ios/videoplayer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/examples/basic/src/MultiValueControl.tsx b/examples/basic/src/MultiValueControl.tsx
new file mode 100644
index 00000000..522f55eb
--- /dev/null
+++ b/examples/basic/src/MultiValueControl.tsx
@@ -0,0 +1,67 @@
+import React from 'react';
+
+import {
+ StyleSheet,
+ Text,
+ TextStyle,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+
+/*
+* MultiValueControl displays a list clickable text view
+*/
+
+interface MultiValueControlType {
+ // a list a string or number to be displayed
+ values: Array
+ // The selected value in values
+ selected?: string | number
+ // callback to press onPress
+ onPress: (arg: string | number) => any
+}
+
+const MultiValueControl = ({ values, selected, onPress }: MultiValueControlType) => {
+ const selectedStyle: TextStyle = StyleSheet.flatten([
+ styles.option,
+ {fontWeight: 'bold'},
+ ]);
+
+ const unselectedStyle: TextStyle = StyleSheet.flatten([
+ styles.option,
+ {fontWeight: 'normal'},
+ ]);
+
+ return
+ {values.map((value: string | number) => {
+ const _style = value === selected ? selectedStyle : unselectedStyle
+ return (
+ {
+ onPress?.(value)
+ }}>
+ {value}
+ )
+ })}
+
+}
+
+const styles = StyleSheet.create({
+ option: {
+ alignSelf: 'center',
+ fontSize: 11,
+ color: 'white',
+ paddingLeft: 2,
+ paddingRight: 2,
+ lineHeight: 12,
+ },
+ container: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+});
+
+export default MultiValueControl;
diff --git a/examples/basic/src/ToggleControl.tsx b/examples/basic/src/ToggleControl.tsx
new file mode 100644
index 00000000..65b30c72
--- /dev/null
+++ b/examples/basic/src/ToggleControl.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+
+import {
+ StyleSheet,
+ Text,
+ TextStyle,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+
+/*
+* ToggleControl displays a 2 states clickable text
+*/
+
+interface ToggleControlType {
+ // boolean indicating if text is selected state
+ isSelected?: boolean
+ // value of text when selected
+ selectedText?: string
+ // value of text when NOT selected
+ unselectedText?: string
+ // default text if no only one text field is needed
+ text?: string
+ // callback called when pressing the component
+ onPress: () => any
+}
+
+const ToggleControl = ({ isSelected, selectedText, unselectedText, text, onPress }: ToggleControlType) => {
+ const selectedStyle: TextStyle = StyleSheet.flatten([
+ styles.controlOption,
+ {fontWeight: 'bold'},
+ ]);
+
+ const unselectedStyle: TextStyle = StyleSheet.flatten([
+ styles.controlOption,
+ {fontWeight: 'normal'},
+ ]);
+
+ const style = isSelected ? selectedStyle : unselectedStyle;
+ const _text = text ? text : isSelected ? selectedText : unselectedText;
+ return (
+
+
+ {_text}
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ controlOption: {
+ alignSelf: 'center',
+ fontSize: 11,
+ color: 'white',
+ paddingLeft: 2,
+ paddingRight: 2,
+ lineHeight: 12,
+ },
+ resizeModeControl: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+});
+
+export default ToggleControl;
diff --git a/examples/basic/src/VideoPlayer.ios.tsx b/examples/basic/src/VideoPlayer.ios.tsx
deleted file mode 100644
index b8d916c5..00000000
--- a/examples/basic/src/VideoPlayer.ios.tsx
+++ /dev/null
@@ -1,475 +0,0 @@
-'use strict';
-import React, {
- Component
-} from 'react';
-
-import {
- Alert,
- Platform,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
-} from 'react-native';
-
-import Video,{FilterType} 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
-];
-
-class VideoPlayer extends Component {
- constructor(props: any) {
- super(props);
- this.onLoad = this.onLoad.bind(this);
- this.onProgress = this.onProgress.bind(this);
- this.onBuffer = this.onBuffer.bind(this);
- }
- video = React.createRef();
-
- state = {
- rate: 1,
- volume: 1,
- muted: false,
- resizeMode: 'contain',
- duration: 0.0,
- currentTime: 0.0,
- controls: false,
- paused: true,
- skin: 'custom',
- ignoreSilentSwitch: null,
- mixWithOthers: null,
- isBuffering: false,
- filter: FilterType.NONE,
- filterEnabled: true
- };
-
- onLoad(data: any) {
- console.log('On load fired!');
- this.setState({duration: data.duration});
- }
-
- onProgress(data: any) {
- this.setState({currentTime: data.currentTime});
- }
-
- onBuffer({ isBuffering }: { isBuffering: boolean }) {
- this.setState({ isBuffering });
- }
-
- 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) {
- 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: string) {
- 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: string) {
- const isSelected = (this.state.ignoreSilentSwitch == ignoreSilentSwitch);
-
- return (
- { this.setState({ignoreSilentSwitch: ignoreSilentSwitch}) }}>
-
- {ignoreSilentSwitch}
-
-
- )
- }
-
- renderFullscreenControl(fullscreen: string) {
- return (
- {
- if (fullscreen === 'fullscreen') {
- this.video.presentFullscreenPlayer()
- }
- }}>
-
- {fullscreen}
-
-
- )
- }
-
- renderMixWithOthersControl(mixWithOthers: string) {
- 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('cover')}
- {this.renderResizeModeControl('contain')}
- {this.renderResizeModeControl('stretch')}
-
-
-
- {
- (Platform.OS === 'ios') ?
- <>
-
- {this.renderIgnoreSilentSwitchControl('ignore')}
- {this.renderIgnoreSilentSwitchControl('obey')}
-
-
- {this.renderMixWithOthersControl('mix')}
- {this.renderMixWithOthersControl('duck')}
-
-
- {this.renderFullscreenControl('fullscreen')}
-
- > : 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('cover')}
- {this.renderResizeModeControl('contain')}
- {this.renderResizeModeControl('stretch')}
-
-
-
- {
- (Platform.OS === 'ios') ?
- <>
-
- {this.renderIgnoreSilentSwitchControl('ignore')}
- {this.renderIgnoreSilentSwitchControl('obey')}
-
-
- {this.renderMixWithOthersControl('mix')}
- {this.renderMixWithOthersControl('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
\ No newline at end of file
diff --git a/examples/basic/src/VideoPlayer.android.tsx b/examples/basic/src/VideoPlayer.tsx
similarity index 55%
rename from examples/basic/src/VideoPlayer.android.tsx
rename to examples/basic/src/VideoPlayer.tsx
index 8b9fb620..bee804af 100644
--- a/examples/basic/src/VideoPlayer.android.tsx
+++ b/examples/basic/src/VideoPlayer.tsx
@@ -1,8 +1,6 @@
'use strict';
-import React, {
- Component
-} from 'react';
+import React, {Component} from 'react';
import {
StyleSheet,
@@ -12,14 +10,18 @@ import {
ActivityIndicator,
PanResponder,
ToastAndroid,
+ Platform,
+ PanResponderInstance,
+ Alert,
} from 'react-native';
-import { Picker } from '@react-native-picker/picker'
+import {Picker} from '@react-native-picker/picker';
-import Video, { VideoDecoderProperties, TextTrackType } from 'react-native-video';
+import Video, {VideoDecoderProperties} from 'react-native-video';
+import ToggleControl from './ToggleControl';
+import MultiValueControl from './MultiValueControl';
class VideoPlayer extends Component {
-
state = {
rate: 1,
volume: 1,
@@ -46,10 +48,38 @@ class VideoPlayer extends Component {
showRNVControls: false,
};
- seekerWidth = 0
+ seekerWidth = 0;
- srcList = [
+ srcAllPlatformList = [
require('./broadchurch.mp4'),
+ {
+ description: '(hls|live) red bull tv',
+ uri: 'https://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/master_928.m3u8',
+ },
+ {
+ description: 'invalid URL',
+ uri: 'mmt://www.youtube.com',
+ type: 'mpd',
+ },
+ {description: '(no url) Stopped playback', uri: undefined},
+ {
+ description: '(no view) no View',
+ noView: true,
+ },
+ {
+ description: 'Another live sample',
+ uri: 'https://live.forstreet.cl/live/livestream.m3u8',
+ },
+ ];
+
+ srcIosList = [
+ ]
+
+ srcAndroidList = [
+ {
+ description: 'Another live sample',
+ uri: 'https://live.forstreet.cl/live/livestream.m3u8',
+ },
{
description: '(dash) sintel subtitles',
uri: 'https://bitmovin-a.akamaihd.net/content/sintel/sintel.mpd',
@@ -58,31 +88,26 @@ class VideoPlayer extends Component {
description: '(mp4) big buck bunny',
uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
},
- {
- description: '(hls|live) red bull tv',
- uri: 'https://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/master_928.m3u8'
- },
{
description: '(mp4|subtitles) demo with sintel Subtitles',
- uri:
- 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
+ uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
type: 'mpd',
},
{
- description: 'invalid URL',
- uri:
- 'mmt://www.youtube.com',
- type: 'mpd',
+ description: '(mp4) big buck bunny With Ads',
+ adTagUrl:
+ 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=',
+ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
},
- { description: '(no url) Stopped playback', uri: undefined },
- {
- description: '(no view) no View',
- noView: true,
- },
- ]
+ ];
- video: Video;
- seekPanResponder: PanResponder | undefined;
+
+ srcList = this.srcAllPlatformList.concat(
+ Platform.OS === 'android' ? this.srcAndroidList : this.srcIosList,
+ );
+
+ video?: Video;
+ seekPanResponder?: PanResponderInstance;
popupInfo = () => {
VideoDecoderProperties.getWidevineLevel().then((widevineLevel: number) => {
@@ -105,52 +130,49 @@ class VideoPlayer extends Component {
};
onLoad = (data: any) => {
- this.setState({ duration: data.duration, loading: false, });
- this.onAudioTracks(data)
- this.onTextTracks(data)
+ this.setState({duration: data.duration, loading: false});
+ this.onAudioTracks(data);
+ this.onTextTracks(data);
};
onProgress = (data: any) => {
if (!this.state.seeking) {
- const position = this.calculateSeekerPosition()
- this.setSeekerPosition(position)
+ const position = this.calculateSeekerPosition();
+ this.setSeekerPosition(position);
}
- this.setState({ currentTime: data.currentTime })
+ this.setState({currentTime: data.currentTime});
};
-
onVideoLoadStart = () => {
- console.log('onVideoLoadStart')
- this.setState({ isLoading: true })
- }
-
+ console.log('onVideoLoadStart');
+ this.setState({isLoading: true});
+ };
onAudioTracks = (data: any) => {
const selectedTrack = data.audioTracks?.find((x: any) => {
- return x.selected
- })
+ return x.selected;
+ });
this.setState({
audioTracks: data.audioTracks,
- })
+ });
if (selectedTrack?.language) {
this.setState({
selectedAudioTrack: {
type: 'language',
value: selectedTrack?.language,
},
- })
-
+ });
}
- }
+ };
onTextTracks = (data: any) => {
const selectedTrack = data.textTracks?.find((x: any) => {
- return x.selected
- })
+ return x.selected;
+ });
this.setState({
textTracks: data.textTracks,
- })
+ });
if (selectedTrack?.language) {
this.setState({
textTracks: data,
@@ -158,38 +180,34 @@ class VideoPlayer extends Component {
type: 'language',
value: selectedTrack?.language,
},
- })
+ });
}
- }
+ };
onAspectRatio = (data: any) => {
- console.log('onAspectRadio called ' + JSON.stringify(data))
+ console.log('onAspectRadio called ' + JSON.stringify(data));
this.setState({
videoWidth: data.width,
videoHeight: data.height,
- })
- }
-
- onVideoBuffer = (param: any) => {
- console.log('onVideoBuffer')
-
- this.setState({ isLoading: param.isBuffering })
- }
-
-
- onReadyForDisplay = () => {
- console.log('onReadyForDisplay')
-
- this.setState({ isLoading: false })
- }
-
-
- onAudioBecomingNoisy = () => {
- this.setState({ paused: true })
+ });
};
- onAudioFocusChanged = (event: { hasAudioFocus: boolean }) => {
- this.setState({ paused: !event.hasAudioFocus })
+ onVideoBuffer = (param: any) => {
+ console.log('onVideoBuffer');
+ this.setState({isLoading: param.isBuffering});
+ };
+
+ onReadyForDisplay = () => {
+ console.log('onReadyForDisplay');
+ this.setState({isLoading: false});
+ };
+
+ onAudioBecomingNoisy = () => {
+ this.setState({paused: true});
+ };
+
+ onAudioFocusChanged = (event: {hasAudioFocus: boolean}) => {
+ this.setState({paused: !event.hasAudioFocus});
};
getCurrentTimePercentage = () => {
@@ -199,80 +217,44 @@ class VideoPlayer extends Component {
return 0;
};
- renderRateControl(rate: number) {
- const isSelected = (this.state.rate === rate);
-
- return (
- { this.setState({ rate }) }}>
-
- {rate}
-
-
- );
- }
-
- renderResizeModeControl(resizeMode: string) {
- const isSelected = (this.state.resizeMode === resizeMode);
-
- return (
- { this.setState({ resizeMode }) }}>
-
- {resizeMode}
-
-
- )
- }
-
- renderVolumeControl(volume: number) {
- const isSelected = (this.state.volume === volume);
-
- return (
- { this.setState({ volume }) }}>
-
- {volume * 100}%
-
-
- )
- }
-
-
toast = (visible: boolean, message: string) => {
if (visible) {
- ToastAndroid.showWithGravityAndOffset(
- message,
- ToastAndroid.LONG,
- ToastAndroid.BOTTOM,
- 25,
- 50,
- )
- return null
+ if (Platform.OS === 'android') {
+ ToastAndroid.showWithGravityAndOffset(
+ message,
+ ToastAndroid.LONG,
+ ToastAndroid.BOTTOM,
+ 25,
+ 50,
+ );
+ } else {
+ Alert.alert(message, message);
+ }
}
- return null
- }
-
- onError = (err: any) => {
- console.log(JSON.stringify(err?.error.errorCode))
- this.toast(true, 'error: ' + err?.error.errorCode)
- }
-
- onEnd = () => {
- this.channelUp()
};
+ onError = (err: any) => {
+ console.log(JSON.stringify(err?.error.errorCode));
+ this.toast(true, 'error: ' + err?.error.errorCode);
+ };
+
+ onEnd = () => {
+ this.channelUp();
+ };
toggleFullscreen() {
- this.setState({ fullscreen: !this.state.fullscreen })
+ this.setState({fullscreen: !this.state.fullscreen});
}
toggleControls() {
- this.setState({ showRNVControls: !this.state.showRNVControls })
+ this.setState({showRNVControls: !this.state.showRNVControls});
}
toggleDecoration() {
- this.setState({ decoration: !this.state.decoration })
+ this.setState({decoration: !this.state.decoration});
if (this.state.decoration) {
- this.video.dismissFullscreenPlayer()
+ this.video?.dismissFullscreenPlayer();
} else {
- this.video.presentFullscreenPlayer()
+ this.video?.presentFullscreenPlayer();
}
}
@@ -288,115 +270,23 @@ class VideoPlayer extends Component {
textTracks: [],
selectedAudioTrack: undefined,
selectedTextTrack: undefined,
- })
+ });
}
-
channelUp() {
- console.log('channel up')
- this.goToChannel((this.state.srcListId + 1) % this.srcList.length)
+ console.log('channel up');
+ this.goToChannel((this.state.srcListId + 1) % this.srcList.length);
}
channelDown() {
- console.log('channel down')
- this.goToChannel((this.state.srcListId + this.srcList.length - 1) % this.srcList.length)
+ console.log('channel down');
+ this.goToChannel(
+ (this.state.srcListId + this.srcList.length - 1) % this.srcList.length,
+ );
}
componentDidMount() {
- this.initSeekPanResponder()
- }
-
- renderDecorationsControl() {
- return (
- {
- this.toggleDecoration()
- }}
- >
- {'decoration'}
-
- )
- }
-
- renderInfoControl() {
- return (
- {
- this.popupInfo()
- }}
- >
- {'decoderInfo'}
-
- )
- }
-
- renderFullScreenControl() {
- return (
- {
- this.toggleFullscreen()
- }}
- >
- {'fullscreen'}
-
- )
- }
-
- renderPause() {
- return (
- {
- this.setState({ paused: !this.state.paused })
- }}
- >
-
- {this.state.paused ? 'pause' : 'playing'}
-
-
- )
- }
-
- renderRepeatModeControl() {
- return (
- {
- this.setState({ loop: !this.state.loop })
- }}
- >
-
- {this.state.loop ? 'loop enable' : 'loop disable'}
-
-
- )
- }
-
- renderLeftControl() {
- return (
-
- {
- this.channelDown()
- }}
- >
- {'ChDown'}
-
-
- // onTimelineUpdated
- )
- }
-
- renderRightControl() {
- return (
-
- {
- this.channelUp()
- }}
- >
- {'ChUp'}
-
-
- )
+ this.initSeekPanResponder();
}
/**
@@ -413,11 +303,11 @@ class VideoPlayer extends Component {
*/
constrainToSeekerMinMax(val = 0) {
if (val <= 0) {
- return 0
+ return 0;
} else if (val >= this.seekerWidth) {
- return this.seekerWidth
+ return this.seekerWidth;
}
- return val
+ return val;
}
/**
@@ -428,17 +318,17 @@ class VideoPlayer extends Component {
* @param {float} position position in px of seeker handle}
*/
setSeekerPosition(position = 0) {
- const state = this.state
- position = this.constrainToSeekerMinMax(position)
+ const state = this.state;
+ position = this.constrainToSeekerMinMax(position);
- state.seekerFillWidth = position
- state.seekerPosition = position
+ state.seekerFillWidth = position;
+ state.seekerPosition = position;
if (!state.seeking) {
- state.seekerOffset = position
+ state.seekerOffset = position;
}
- this.setState(state)
+ this.setState(state);
}
/**
@@ -448,8 +338,8 @@ class VideoPlayer extends Component {
* @return {float} position of seeker handle in px based on currentTime
*/
calculateSeekerPosition() {
- const percent = this.state.currentTime / this.state.duration
- return this.seekerWidth * percent
+ const percent = this.state.currentTime / this.state.duration;
+ return this.seekerWidth * percent;
}
/**
@@ -459,8 +349,8 @@ class VideoPlayer extends Component {
* @return {float} time in ms based on seekerPosition.
*/
calculateTimeFromSeekerPosition() {
- const percent = this.state.seekerPosition / this.seekerWidth
- return this.state.duration * percent
+ const percent = this.state.seekerPosition / this.seekerWidth;
+ return this.state.duration * percent;
}
/**
@@ -469,29 +359,29 @@ class VideoPlayer extends Component {
initSeekPanResponder() {
this.seekPanResponder = PanResponder.create({
// Ask to be the responder.
- onStartShouldSetPanResponder: (evt, gestureState) => true,
- onMoveShouldSetPanResponder: (evt, gestureState) => true,
+ 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 state = this.state
+ onPanResponderGrant: (evt, _gestureState) => {
+ const state = this.state;
// this.clearControlTimeout()
- const position = evt.nativeEvent.locationX
- this.setSeekerPosition(position)
- state.seeking = true
- this.setState(state)
+ const position = evt.nativeEvent.locationX;
+ this.setSeekerPosition(position);
+ state.seeking = true;
+ this.setState(state);
},
/**
* When panning, update the seekbar position, duh.
*/
onPanResponderMove: (evt, gestureState) => {
- const position = this.state.seekerOffset + gestureState.dx
- this.setSeekerPosition(position)
+ const position = this.state.seekerOffset + gestureState.dx;
+ this.setSeekerPosition(position);
},
/**
@@ -499,140 +389,193 @@ class VideoPlayer extends Component {
* If you seek to the end of the video we fire the
* onEnd callback
*/
- onPanResponderRelease: (evt, gestureState) => {
- const time = this.calculateTimeFromSeekerPosition()
- const state = this.state
+ onPanResponderRelease: (_evt, _gestureState) => {
+ const time = this.calculateTimeFromSeekerPosition();
+ const state = this.state;
if (time >= state.duration && !state.isLoading) {
- state.paused = true
- this.onEnd()
+ state.paused = true;
+ this.onEnd();
} else {
- this.video?.seek(time)
- state.seeking = false
+ this.video?.seek(time);
+ state.seeking = false;
}
- this.setState(state)
+ this.setState(state);
},
- })
+ });
}
renderSeekBar() {
if (!this.seekPanResponder) {
- return null
+ return null;
}
+ const seekerStyle = [
+ styles.seekbarFill,
+ {
+ width: this.state.seekerFillWidth > 0 ? this.state.seekerFillWidth : 0,
+ backgroundColor: '#FFF',
+ },
+ ];
+
+ const seekerPositionStyle = [
+ styles.seekbarHandle,
+ {
+ left: this.state.seekerPosition > 0 ? this.state.seekerPosition : 0,
+ },
+ ];
+
+ const seekerPointerStyle = [
+ styles.seekbarCircle,
+ {backgroundColor: '#FFF'},
+ ];
+
return (
+ {...styles.generalControls}>
(this.seekerWidth = event.nativeEvent.layout.width)}
- pointerEvents={'none'}
- >
- 0 ? this.state.seekerFillWidth : 0,
- backgroundColor: '#FFF',
- },
- ]}
- pointerEvents={'none'}
- />
+ onLayout={event =>
+ (this.seekerWidth = event.nativeEvent.layout.width)
+ }
+ pointerEvents={'none'}>
+
- 0 ? this.state.seekerPosition : 0 },
- ]}
- pointerEvents={'none'}
- >
-
+
+
- )
+ );
}
IndicatorLoadingView() {
- if (this.state.isLoading)
- return
- else return
+ if (this.state.isLoading) {
+ return (
+
+ );
+ } else {
+ return ;
+ }
}
renderTopControl() {
- return (<>
-
- {this.srcList[this.state.srcListId]?.description || 'local file'}
-
-
- {
- this.toggleControls()
- }}
- >
- {this.state.showRNVControls ? 'Hide controls' : 'Show controls'}
-
-
- >)
+ return (
+ <>
+
+ {this.srcList[this.state.srcListId]?.description || 'local file'}
+
+
+ {
+ this.toggleControls();
+ }}>
+
+ {this.state.showRNVControls ? 'Hide controls' : 'Show controls'}
+
+
+
+ >
+ );
}
+ onRateSelected = (value: string | number) => {
+ this.setState({rate: value});
+ }
+ onVolumeSelected = (value: string | number) => {
+ this.setState({volume: value});
+ }
+ onResizeModeSelected = (value: string | number) => {
+ this.setState({resizeMode: value});
+ }
renderOverlay() {
return (
<>
{this.IndicatorLoadingView()}
- {this.renderTopControl()}
+
+ {this.renderTopControl()}
+
{!this.state.showRNVControls ? (
<>
- {this.renderLeftControl()}
-
- {this.renderRightControl()}
-
+ {
+ this.channelDown();
+ }}
+ text='ChDown'
+ />
+
+
+ {
+ this.channelUp();
+ }}
+ text='ChUp'
+ />
+
+
-
- {this.renderInfoControl()}
-
- {this.renderPause()}
-
- {this.renderRepeatModeControl()}
-
-
- {this.renderFullScreenControl()}
-
-
- {this.renderDecorationsControl()}
+ {Platform.OS === 'android' ? (
+
+ {
+ this.popupInfo();
+ }}
+ text='decoderInfo'
+ />
+ ) : null}
+ {
+ this.setState({paused: !this.state.paused});
+ }}
+ selectedText='pause'
+ unselectedText='playing'
+ />
+ {
+ this.setState({loop: !this.state.loop});
+ }}
+ selectedText='loop enable'
+ unselectedText='loop disable'
+ />
+ {
+ this.toggleFullscreen();
+ }}
+ text='fullscreen'
+ />
+ {
+ this.toggleDecoration();
+ }}
+ text='decoration'
+ />
-
- {this.renderRateControl(0.25)}
- {this.renderRateControl(0.5)}
- {this.renderRateControl(1.0)}
- {this.renderRateControl(1.5)}
- {this.renderRateControl(2.0)}
-
-
-
- {this.renderVolumeControl(0.5)}
- {this.renderVolumeControl(1)}
- {this.renderVolumeControl(1.5)}
-
-
-
- {this.renderResizeModeControl('cover')}
- {this.renderResizeModeControl('contain')}
- {this.renderResizeModeControl('stretch')}
-
+
+
+
{this.renderSeekBar()}
@@ -651,14 +594,14 @@ class VideoPlayer extends Component {
value: itemValue,
},
});
- }}
- >
- {this.state.audioTracks.map((track) => {
+ }}>
+ {this.state.audioTracks.map(track => {
return (
+ key={track.language}
+ />
);
})}
@@ -678,35 +621,38 @@ class VideoPlayer extends Component {
value: itemValue,
},
});
- }}
- >
+ }}>
- {this.state.textTracks.map((track) => (
+ {this.state.textTracks.map(track => (
+ key={track.language}
+ />
))}
)}
- >
- ) : null
- }
+
+ >
+ ) : null}
>
- )
+ );
}
renderVideoView() {
- const viewStyle = this.state.fullscreen ? styles.fullScreen : styles.halfScreen
+ const viewStyle = this.state.fullscreen
+ ? styles.fullScreen
+ : styles.halfScreen;
return (
- )
+ );
}
render() {
return (
- {this.srcList[this.state.srcListId]?.noView ? null : this.renderVideoView()}
+ {this.srcList[this.state.srcListId]?.noView
+ ? null
+ : this.renderVideoView()}
{this.renderOverlay()}
- )
+ );
}
-
}
-
const styles = StyleSheet.create({
container: {
flex: 1,
@@ -888,4 +834,4 @@ const styles = StyleSheet.create({
},
});
-export default VideoPlayer
\ No newline at end of file
+export default VideoPlayer;