From 8569d3fa806ba643a94b3d5e42bcb028ee6391f1 Mon Sep 17 00:00:00 2001 From: tangyazhong Date: Tue, 13 Mar 2018 10:05:34 +0800 Subject: [PATCH 1/4] add video vol control --- index.js | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 7a07891..0373d26 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Image, ImageBackground, Platform, StyleSheet, TouchableOpacity, View, ViewPropTypes } from 'react-native'; +import { Image, ImageBackground, Platform, StyleSheet, TouchableOpacity, View, ViewPropTypes, Text} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import Video from 'react-native-video'; // eslint-disable-line @@ -37,6 +37,7 @@ const styles = StyleSheet.create({ marginTop: -48, flexDirection: 'row', alignItems: 'center', + zIndex: 1, }, playControl: { color: 'white', @@ -53,7 +54,7 @@ const styles = StyleSheet.create({ flexDirection: 'row', paddingHorizontal: 10, marginLeft: -10, - marginRight: -5, + marginRight: 0, }, seekBarFullWidth: { marginLeft: 0, @@ -74,7 +75,7 @@ const styles = StyleSheet.create({ borderRadius: 10, backgroundColor: '#F00', transform: [{ scale: 0.8 }], - zIndex: 1, + zIndex: 2, }, seekBarBackground: { backgroundColor: 'rgba(255, 255, 255, 0.5)', @@ -83,6 +84,10 @@ const styles = StyleSheet.create({ overlayButton: { flex: 1, }, + timeSyle: { + fontSize: 15, + color: 'rgba(255, 255, 255, 0.6)', + }, }); export default class VideoPlayer extends Component { @@ -94,12 +99,15 @@ export default class VideoPlayer extends Component { isPlaying: props.autoplay, width: 200, progress: 0, - isMuted: props.defaultMuted, + isMuted: true, isControlsVisible: !props.hideControlsOnStart, duration: 0, isSeeking: false, + volume: 0, }; + this.volControlBarWith = 200; + this.volControlTouchStart = 0; this.seekBarWidth = 200; this.wasPlayingBeforeSeek = props.autoplay; this.seekTouchStart = 0; @@ -118,6 +126,9 @@ export default class VideoPlayer extends Component { this.onSeekGrant = this.onSeekGrant.bind(this); this.onSeekRelease = this.onSeekRelease.bind(this); this.onSeek = this.onSeek.bind(this); + this.onVolCtrlGrant = this.onVolCtrlGrant.bind(this); + this.onVolCtrlRelease = this.onVolCtrlRelease.bind(this); + this.onVolControl = this.onVolControl.bind(this); } componentDidMount() { @@ -134,7 +145,7 @@ export default class VideoPlayer extends Component { } onLayout(event) { - const { width } = event.nativeEvent.layout; + const { width, height } = event.nativeEvent.layout; this.setState({ width, }); @@ -242,6 +253,14 @@ export default class VideoPlayer extends Component { return true; } + onVolCtrlStartResponder() { + return true; + } + + onMoveShouldSetPanResponder() { + return true; + } + onSeekGrant(e) { this.seekTouchStart = e.nativeEvent.pageX; this.seekProgressStart = this.state.progress; @@ -260,6 +279,40 @@ export default class VideoPlayer extends Component { this.showControls(); } + onVolCtrlGrant(e) { + console.log("Test vol ctrl grant start, pos=", e.nativeEvent.pageY); + this.volControlTouchStart = e.nativeEvent.pageY; + this.showControls(); + } + + onVolCtrlRelease() { + console.log("Test vol ctrl touch release"); + } + + onVolControl(e) { + console.log("Test onVolControl,pos=", e.nativeEvent.pageY); + let volume = this.state.volume; + const diff = this.volControlTouchStart - e.nativeEvent.pageY; + const volChange = diff / (this.getSizeStyles().height * 3); + if(volume <= 1 && volume >= 0) { + volume = volume + volChange; + } + if(volume > 1) { + volume = 1; + } + if(volume < 0) { + volume = 0; + } + let mutedChg = ((volume == 0 && this.state.volume > 0 && !this.state.isMuted) || (volume > 0 && this.state.volume == 0) + || (this.state.isMuted && volChange > 0)); + const isMuted = (mutedChg ? (!this.state.isMuted) : (this.state.isMuted)); + console.log("Test mutedChg=", mutedChg, "new mute status=", isMuted); + this.setState({ + volume, + isMuted, + }); + } + onSeek(e) { const diff = e.nativeEvent.pageX - this.seekTouchStart; const ratio = 100 / this.seekBarWidth; @@ -338,6 +391,43 @@ export default class VideoPlayer extends Component { this.showControls(); } + formatTime(seconds) { + let hour = parseInt(seconds/3600); + let minute = parseInt(seconds/60); + let sec = parseInt(seconds%60); + console.log("Test input sec=", seconds, "hour=", hour, "minute=", minute, "sec=", sec); + let formatTime = 0; + if(hour > 99) { + console.log("Test input time out of bound, seconds=", seconds); + return formatTime; + } + if(seconds === 0) { + return '00:00'; + } + if(hour < 10 && hour > 0) { + hour = '0' + hour.toString(); + } + if(minute < 10) { + minute = '0' + minute.toString(); + } + if(sec < 10) { + minute = '0' + sec.toString(); + } + if(hour > 0) { + formatTime = hour + ':' + minute + ':' + sec; + } + else { + formatTime = minute + ':' + sec; + } + return formatTime; + } + + getMuteStatus() { + this.state.isMuted = (this.state.volume === 0 ? true : false); + console.log("Test isMuted=", this.state.isMuted, "vol=", this.state.volume); + return this.props.muted || this.state.isMuted; + } + renderStartButton() { const { customStyles } = this.props; return ( @@ -368,6 +458,26 @@ export default class VideoPlayer extends Component { ); } + renderVolControlBar() { + return ( + + ); + } + renderSeekBar(fullWidth) { const { customStyles, disableSeek } = this.props; return ( @@ -428,6 +538,11 @@ export default class VideoPlayer extends Component { /> {this.renderSeekBar()} + { + + {this.formatTime(this.state.duration)} + + } {this.props.muted ? null : ( { this.player = p; }} + volume={this.state.volume} muted={this.props.muted || this.state.isMuted} paused={!this.state.isPlaying} onProgress={this.onProgress} @@ -500,6 +616,7 @@ export default class VideoPlayer extends Component { {((!this.state.isPlaying) || this.state.isControlsVisible) ? this.renderControls() : this.renderSeekBar(true)} + {this.renderVolControlBar()} ); } From c5c3a3b8f6dde857acf04726effb30540aae98c2 Mon Sep 17 00:00:00 2001 From: tangyazhong Date: Mon, 19 Mar 2018 18:59:57 +0800 Subject: [PATCH 2/4] add vol bar --- index.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 0373d26..7f88a09 100644 --- a/index.js +++ b/index.js @@ -88,6 +88,25 @@ const styles = StyleSheet.create({ fontSize: 15, color: 'rgba(255, 255, 255, 0.6)', }, + + volReflect: { + backgroundColor: 'rgba(255, 0, 0, 0.5)', + width: 100, + height: 30, + flexGrow: 1, + flexDirection: 'row', + alignSelf: 'center', + }, + volProgress: { + height: 3, + backgroundColor: '#FFF', + alignSelf:'flex-end', + }, + volLeft: { + backgroundColor: 'rgba(255, 255, 255, 0.5)', + height: 3, + alignSelf:'flex-end', + }, }); export default class VideoPlayer extends Component { @@ -104,6 +123,7 @@ export default class VideoPlayer extends Component { duration: 0, isSeeking: false, volume: 0, + volBarNeedShow: false, }; this.volControlBarWith = 200; @@ -281,28 +301,32 @@ export default class VideoPlayer extends Component { onVolCtrlGrant(e) { console.log("Test vol ctrl grant start, pos=", e.nativeEvent.pageY); + const volBarNeedShow = true; this.volControlTouchStart = e.nativeEvent.pageY; this.showControls(); + this.setState({volBarNeedShow}); } onVolCtrlRelease() { console.log("Test vol ctrl touch release"); + const volBarNeedShow = false; + this.setState({volBarNeedShow}); } onVolControl(e) { - console.log("Test onVolControl,pos=", e.nativeEvent.pageY); let volume = this.state.volume; + const senseFactor = 5/4; const diff = this.volControlTouchStart - e.nativeEvent.pageY; - const volChange = diff / (this.getSizeStyles().height * 3); - if(volume <= 1 && volume >= 0) { - volume = volume + volChange; - } + const volChange = diff / (this.getSizeStyles().height) * senseFactor; + volume = volume + volChange; if(volume > 1) { volume = 1; } if(volume < 0) { volume = 0; } + console.log("Test onVolControl,pos=", e.nativeEvent.pageY,"new vol=", volume, "vol control touch start=", this.volControlTouchStart); + this.volControlTouchStart = e.nativeEvent.pageY; let mutedChg = ((volume == 0 && this.state.volume > 0 && !this.state.isMuted) || (volume > 0 && this.state.volume == 0) || (this.state.isMuted && volChange > 0)); const isMuted = (mutedChg ? (!this.state.isMuted) : (this.state.isMuted)); @@ -523,6 +547,57 @@ export default class VideoPlayer extends Component { ); } + renderVolReflect() { + return ( + + + + + + + + ); + } + renderControls() { const { customStyles } = this.props; return ( @@ -612,8 +687,10 @@ export default class VideoPlayer extends Component { if (fullScreenOnLongPress && Platform.OS !== 'android') this.onToggleFullScreen(); }} - /> - + /> + {this.state.volBarNeedShow + ? this.renderVolReflect() : null} + {((!this.state.isPlaying) || this.state.isControlsVisible) ? this.renderControls() : this.renderSeekBar(true)} {this.renderVolControlBar()} @@ -703,6 +780,6 @@ VideoPlayer.defaultProps = { resizeMode: 'contain', disableSeek: false, pauseOnPress: false, - fullScreenOnLongPress: false, + fullScreenOnLongPress: true, customStyles: {}, }; From ce9a0dc3bd10ce44577581e5fe815fdd92c4b12d Mon Sep 17 00:00:00 2001 From: AaronTYZ <35682183+AaronTYZ@users.noreply.github.com> Date: Tue, 20 Mar 2018 09:50:43 +0800 Subject: [PATCH 3/4] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13b7837..42ed28f 100644 --- a/README.md +++ b/README.md @@ -76,8 +76,8 @@ All other props are passed to the react-native-video component. - [X] Make seek bar seekable. - [x] Make player customizable. -- [ ] Add volume control +- [X] Add volume control - [X] Add fullscreen button - [ ] Add fullscreen button for Android (See PR #38 if you need fullscreen in Android) - [ ] Add loader -- [ ] Add video duration/play time +- [X] Add video duration/play time From 1a6bf0a3b6cc4387f03a41ffb4bcca88d89b2a39 Mon Sep 17 00:00:00 2001 From: zhangtao Date: Wed, 21 Mar 2018 15:03:38 +0800 Subject: [PATCH 4/4] add header tar --- index.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/index.js b/index.js index 7f88a09..a7f0d71 100644 --- a/index.js +++ b/index.js @@ -149,6 +149,7 @@ export default class VideoPlayer extends Component { this.onVolCtrlGrant = this.onVolCtrlGrant.bind(this); this.onVolCtrlRelease = this.onVolCtrlRelease.bind(this); this.onVolControl = this.onVolControl.bind(this); + this.onBack = this.props.onBack; } componentDidMount() { @@ -714,10 +715,37 @@ export default class VideoPlayer extends Component { return this.renderVideo(); } + renderHeader() { + const {height} = this.getSizeStyles(); + const {videoTitle} = this.props; + return ( + + + + + + + {videoTitle} + + + + ); + } + render() { return ( {this.renderContent()} + {(!this.state.isPlaying || this.state.isControlsVisible) ? this.renderHeader(): null} ); } @@ -743,6 +771,7 @@ VideoPlayer.propTypes = { disableSeek: PropTypes.bool, pauseOnPress: PropTypes.bool, fullScreenOnLongPress: PropTypes.bool, + videoTitle: PropTypes.string, customStyles: PropTypes.shape({ wrapper: ViewPropTypes.style, video: Video.propTypes.style, @@ -769,6 +798,7 @@ VideoPlayer.propTypes = { onPlayPress: PropTypes.func, onHideControls: PropTypes.func, onShowControls: PropTypes.func, + onBack: PropTypes.func, }; VideoPlayer.defaultProps = {