CusVideo.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import React, { Component } from "react";
  2. import {
  3. Platform,
  4. Text,
  5. View,
  6. ImageBackground,
  7. Button,
  8. Image,
  9. TouchableOpacity,
  10. StyleSheet
  11. } from "react-native";
  12. import { createStackNavigator, createAppContainer } from "react-navigation";
  13. import Video from "react-native-video";
  14. import SeekBar from "../components/SeekBar";
  15. const instructions = Platform.select({
  16. ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
  17. android:
  18. "Double tap R on your keyboard to reload,\n" +
  19. "Shake or press menu button for dev menu"
  20. });
  21. type Props = {};
  22. export default class CusVideo extends React.Component {
  23. state = {
  24. rate: 1,
  25. volume: 1,
  26. muted: false,
  27. resizeMode: "stretch",
  28. duration: 0.0,
  29. currentTime: 0.0,
  30. paused: false,
  31. wheel: false
  32. };
  33. render() {
  34. return (
  35. <View style={this.props.style}>
  36. <Video
  37. style={{ flex: 1 }}
  38. source={{
  39. uri: this.props.uri
  40. }}
  41. ref={ref => {
  42. this.player = ref;
  43. }}
  44. // poster={this.props.poster}
  45. resizeMode={this.state.resizeMode}
  46. // posterResizeMode={this.state.resizeMode}
  47. onBuffer={this.onBuffer}
  48. rate={this.state.rate} //播放速率
  49. paused={this.state.paused} //暂停
  50. volume={this.state.volume} //调节音量
  51. muted={this.state.muted} //控制音频是否静音
  52. resizeMode={this.state.resizeMode} //缩放模式
  53. onLoadStart={this.loadStart} // 当视频开始加载时的回调函数
  54. onLoad={this.onLoad} //加载媒体并准备播放时调用的回调函数。
  55. onProgress={this.onProgress} //视频播放过程中每个间隔进度单位调用的回调函数
  56. onEnd={this.onEnd} //视频播放结束时的回调函数
  57. onAudioBecomingNoisy={this.onAudioBecomingNoisy} //音频变得嘈杂时的回调 - 应暂停视频
  58. onAudioFocusChanged={this.onAudioFocusChanged} //音频焦点丢失时的回调 - 如果焦点丢失则暂停
  59. repeat={this.state.wheel} //确定在到达结尾时是否重复播放视频。
  60. onError={this.onError} // 当视频不能加载,或出错后的回调函数
  61. playInBackground={false} // 当app转到后台运行的时候,播放是否暂停
  62. playWhenInactive={true} // [iOS] Video continues to play when control or notification center are shown. 仅适用于IOS
  63. />
  64. <View style={[styles.player_controller]}>
  65. <View
  66. style={{
  67. flex: 1,
  68. alignItems: "center"
  69. }}
  70. >
  71. {/* 暂停播放按钮 */}
  72. <TouchableOpacity
  73. //点击事件放在这个组件里才管用
  74. style={{
  75. justifyContent: "center",
  76. width: "100%",
  77. height: "100%"
  78. }}
  79. onPress={() => this.play()}
  80. >
  81. <Image
  82. style={[styles.player_pause_icon]}
  83. //source={require("../imgs/player_image_state_pause.png")}
  84. />
  85. </TouchableOpacity>
  86. </View>
  87. <View style={{ flex: 3 }}>
  88. {/* //左侧当前播放时长 */}
  89. <Text style={[styles.player_time]}>
  90. {formatTime(this.state.currentTime)}
  91. </Text>
  92. </View>
  93. <View
  94. style={{
  95. flex: 7,
  96. overflow: "hidden"
  97. }}
  98. >
  99. {/* //中间进度条 */}
  100. <SeekBar
  101. style={{ flex: 1 }}
  102. ref={view => (this.seekbar = view)}
  103. //必须带此方法,作为滑动之后抬起的回调
  104. touchUpCallBack={this.touch_up_callback.bind(this)}
  105. />
  106. </View>
  107. <View style={{ flex: 3 }}>
  108. {/* //右侧总时长 */}
  109. <Text style={[styles.player_time]}>
  110. {formatTime(this.state.duration)}
  111. </Text>
  112. </View>
  113. <TouchableOpacity
  114. style={{ flex: 1 }}
  115. onPress={() => this.presentFullscreenPlayer()}
  116. >
  117. <View style={{ flex: 1 }}>
  118. {/* //放大按钮 */}
  119. <Image style={[styles.player_pause_icon]} />
  120. </View>
  121. </TouchableOpacity>
  122. </View>
  123. </View>
  124. );
  125. }
  126. loadStart() {
  127. // alert("loadStart");
  128. }
  129. onBuffer({ isBuffering }: { isBuffering: boolean }) {
  130. //true为正在加载,false为没有加载,此处给loading提示
  131. console.log("isBuffering:" + isBuffering);
  132. }
  133. onLoad = data => {
  134. //获取的是秒数
  135. this.setState({ duration: data.duration });
  136. this.seekbar.setMax(data.duration);
  137. };
  138. onProgress = data => {
  139. this.setState({
  140. currentTime: data.currentTime
  141. });
  142. this.seekbar.setProgress(this.state.currentTime);
  143. };
  144. onError() {
  145. alert("播放器异常");
  146. }
  147. onEnd() {
  148. alert("播放结束");
  149. }
  150. play() {
  151. if (this.state.paused) {
  152. this.start();
  153. } else {
  154. this.pause();
  155. }
  156. }
  157. pause() {
  158. this.setState({ paused: true });
  159. this.player_icon_index = 1;
  160. }
  161. start() {
  162. this.setState({ paused: false });
  163. this.player_icon_index = 0;
  164. }
  165. showToast(params) {
  166. // ToastExample.message(params);
  167. ToastExample.show(params, ToastExample.SHORT);
  168. }
  169. seekTo(progress) {
  170. this.player.seek(progress);
  171. }
  172. presentFullscreenPlayer() {
  173. // alert("点击调用全屏");
  174. this.props.videofullScreenPlayer();
  175. console.log("currentTime:" + this.state.currentTime);
  176. setTimeout(() => {
  177. this.seekbar.setProgress(this.state.currentTime);
  178. }, 10);
  179. }
  180. touch_up_callback(progress) {
  181. //抬起之后,获取算出来的progress
  182. this.setState({
  183. currentTime: progress
  184. });
  185. this.seekTo(progress);
  186. }
  187. refreshVideo() {
  188. this.setState({
  189. duration: 0,
  190. currentTime: 0
  191. });
  192. }
  193. }
  194. const styles = StyleSheet.create({
  195. player_controller: {
  196. flexDirection: "row",
  197. position: "absolute",
  198. width: "100%",
  199. height: 50,
  200. alignItems: "center",
  201. bottom: 0
  202. },
  203. player_pause_icon: {
  204. width: "100%",
  205. resizeMode: "center",
  206. height: "80%",
  207. justifyContent: "center",
  208. alignItems: "center",
  209. backgroundColor: "blue"
  210. },
  211. player_time: {
  212. fontSize: 18,
  213. color: "white",
  214. alignItems: "center",
  215. justifyContent: "center",
  216. textAlignVertical: "center",
  217. textAlign: "center"
  218. }
  219. });
  220. /**
  221. * 将秒转换为 分:秒
  222. * s int 秒数
  223. */
  224. function formatTime(s) {
  225. //计算分钟
  226. //算法:将秒数除以60,然后下舍入,既得到分钟数
  227. var h;
  228. h = Math.floor(s / 60);
  229. //计算秒
  230. //算法:取得秒%60的余数,既得到秒数
  231. s = Math.round(s % 60);
  232. //将变量转换为字符串
  233. h += "";
  234. s += "";
  235. //如果只有一位数,前面增加一个0
  236. h = h.length == 1 ? "0" + h : h;
  237. s = s.length == 1 ? "0" + s : s;
  238. return h + ":" + s;
  239. }