example app change

This commit is contained in:
jiyong1 2023-04-20 19:42:14 +09:00 committed by yungblud
parent 2c2f812359
commit bc4d2cacc5
5 changed files with 1178 additions and 255 deletions

View File

@ -9,19 +9,11 @@
*/ */
import React, {type PropsWithChildren} from 'react'; import React, {type PropsWithChildren} from 'react';
import { import {StyleSheet, View} from 'react-native';
StyleSheet, import VideoPlayer from './src/VideoPlayer';
View,
} from 'react-native';
import Video from 'react-native-video'
const App = () => { const App = () => {
return <VideoPlayer />;
return (
<View style={{flex: 1}}>
<Video style={{flex:1, backgroundColor: 'blue'}} source={{uri: "https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4"}} />
</View>
);
}; };
export default App; export default App;

View File

@ -31,7 +31,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ {
RCTAppSetupPrepareApp(application); RCTAppSetupPrepareApp(application, true);
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
@ -44,7 +44,7 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
#endif #endif
NSDictionary *initProps = [self prepareInitialProps]; NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"LaftelVideo", initProps); UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"LaftelVideo", initProps, true);
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor]; rootView.backgroundColor = [UIColor systemBackgroundColor];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,538 @@
'use strict';
import React, {Component, createRef} from 'react';
import {
Alert,
GestureResponderEvent,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import Video, {FilterType, VideoRef} 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 {
controlRef: React.RefObject<TouchableOpacity>;
videoRef: React.RefObject<VideoRef>;
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 = {
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!');
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) {
const isSelected = this.state.skin == skin;
const selectControls = skin == 'native' || skin == 'embed';
return (
<TouchableOpacity
onPress={() => {
this.setState({
controls: selectControls,
skin: skin,
});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{skin}
</Text>
</TouchableOpacity>
);
}
renderRateControl(rate: number) {
const isSelected = this.state.rate == rate;
return (
<TouchableOpacity
onPress={() => {
this.setState({rate: rate});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{rate}x
</Text>
</TouchableOpacity>
);
}
renderResizeModeControl(resizeMode: string) {
const isSelected = this.state.resizeMode == resizeMode;
return (
<TouchableOpacity
onPress={() => {
this.setState({resizeMode: resizeMode});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{resizeMode}
</Text>
</TouchableOpacity>
);
}
renderVolumeControl(volume: number) {
const isSelected = this.state.volume == volume;
return (
<TouchableOpacity
onPress={() => {
this.setState({volume: volume});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{volume * 100}%
</Text>
</TouchableOpacity>
);
}
renderIgnoreSilentSwitchControl(ignoreSilentSwitch: string) {
const isSelected = this.state.ignoreSilentSwitch == ignoreSilentSwitch;
return (
<TouchableOpacity
onPress={() => {
this.setState({ignoreSilentSwitch: ignoreSilentSwitch});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{ignoreSilentSwitch}
</Text>
</TouchableOpacity>
);
}
renderMixWithOthersControl(mixWithOthers: string) {
const isSelected = this.state.mixWithOthers == mixWithOthers;
return (
<TouchableOpacity
onPress={() => {
this.setState({mixWithOthers: mixWithOthers});
}}>
<Text
style={[
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]}>
{mixWithOthers}
</Text>
</TouchableOpacity>
);
}
renderCustomSkin() {
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.fullScreen}
onPress={() => {
this.setState({paused: !this.state.paused});
}}>
<Video
ref={this.videoRef}
source={require('./broadchurch.mp4')}
style={styles.fullScreen}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
onProgress={this.onProgress}
onEnd={() => {
Alert.alert('Done!');
}}
onError={e => {
console.log(e);
}}
repeat={true}
filter={this.state.filter}
filterEnabled={this.state.filterEnabled}
/>
</TouchableOpacity>
<View style={styles.controls}>
<View style={styles.generalControls}>
<View style={styles.skinControl}>
{this.renderSkinControl('custom')}
{this.renderSkinControl('native')}
{this.renderSkinControl('embed')}
</View>
{this.state.filterEnabled ? (
<View style={styles.skinControl}>
<TouchableOpacity
onPress={() => {
this.setFilter(-1);
}}>
<Text style={styles.controlOption}>Previous Filter</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
this.setFilter(1);
}}>
<Text style={styles.controlOption}>Next Filter</Text>
</TouchableOpacity>
</View>
) : null}
</View>
<View style={styles.generalControls}>
<View style={styles.rateControl}>
{this.renderRateControl(0.5)}
{this.renderRateControl(1.0)}
{this.renderRateControl(2.0)}
</View>
<View style={styles.volumeControl}>
{this.renderVolumeControl(0.5)}
{this.renderVolumeControl(1)}
{this.renderVolumeControl(1.5)}
</View>
<View style={styles.resizeModeControl}>
{this.renderResizeModeControl('cover')}
{this.renderResizeModeControl('contain')}
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.generalControls}>
{Platform.OS === 'ios' ? (
<>
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</>
) : null}
</View>
<TouchableOpacity ref={this.controlRef} onPress={this.onTouchControl}>
<View style={styles.trackingControls}>
<View style={styles.progress}>
<View
style={[styles.innerProgressCompleted, {flex: flexCompleted}]}
/>
<View
style={[styles.innerProgressRemaining, {flex: flexRemaining}]}
/>
</View>
</View>
</TouchableOpacity>
</View>
</View>
);
}
renderNativeSkin() {
const videoStyle =
this.state.skin == 'embed'
? styles.nativeVideoControls
: styles.fullScreen;
return (
<View style={styles.container}>
<View style={styles.fullScreen}>
<Video
ref={this.videoRef}
source={require('./broadchurch.mp4')}
style={videoStyle}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
ignoreSilentSwitch={this.state.ignoreSilentSwitch}
mixWithOthers={this.state.mixWithOthers}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
onProgress={this.onProgress}
onEnd={() => {
Alert.alert('Done!');
}}
onError={e => {
console.log(e);
}}
repeat={true}
controls={this.state.controls}
filter={this.state.filter}
filterEnabled={this.state.filterEnabled}
/>
</View>
<View style={styles.controls}>
<View style={styles.generalControls}>
<View style={styles.skinControl}>
{this.renderSkinControl('custom')}
{this.renderSkinControl('native')}
{this.renderSkinControl('embed')}
</View>
{this.state.filterEnabled ? (
<View style={styles.skinControl}>
<TouchableOpacity
onPress={() => {
this.setFilter(-1);
}}>
<Text style={styles.controlOption}>Previous Filter</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
this.setFilter(1);
}}>
<Text style={styles.controlOption}>Next Filter</Text>
</TouchableOpacity>
</View>
) : null}
</View>
<View style={styles.generalControls}>
<View style={styles.rateControl}>
{this.renderRateControl(0.5)}
{this.renderRateControl(1.0)}
{this.renderRateControl(2.0)}
</View>
<View style={styles.volumeControl}>
{this.renderVolumeControl(0.5)}
{this.renderVolumeControl(1)}
{this.renderVolumeControl(1.5)}
</View>
<View style={styles.resizeModeControl}>
{this.renderResizeModeControl('cover')}
{this.renderResizeModeControl('contain')}
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.generalControls}>
{Platform.OS === 'ios' ? (
<>
<View style={styles.ignoreSilentSwitchControl}>
{this.renderIgnoreSilentSwitchControl('ignore')}
{this.renderIgnoreSilentSwitchControl('obey')}
</View>
<View style={styles.mixWithOthersControl}>
{this.renderMixWithOthersControl('mix')}
{this.renderMixWithOthersControl('duck')}
</View>
</>
) : null}
</View>
</View>
</View>
);
}
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;

Binary file not shown.