index.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React, { Component } from 'react';
  2. import './index.less';
  3. import videojs from 'video.js';
  4. import Assets from '@src/components/Assets';
  5. import { generateUUID } from '@src/services/Tools';
  6. function fullScreen(id) {
  7. const element = document.getElementById(id);
  8. if (element.requestFullscreen) {
  9. element.requestFullscreen();
  10. } else if (element.msRequestFullscreen) {
  11. element.msRequestFullscreen();
  12. } else if (element.mozRequestFullScreen) {
  13. element.mozRequestFullScreen();
  14. } else if (element.webkitRequestFullscreen) {
  15. element.webkitRequestFullscreen();
  16. }
  17. }
  18. function exitFullscreen() {
  19. if (document.exitFullscreen) {
  20. document.exitFullscreen();
  21. } else if (document.msExitFullscreen) {
  22. document.msExitFullscreen();
  23. } else if (document.mozCancelFullScreen) {
  24. document.mozCancelFullScreen();
  25. } else if (document.webkitExitFullscreen) {
  26. document.webkitExitFullscreen();
  27. }
  28. }
  29. let fullAgent = null;
  30. document.addEventListener('fullscreenchange', () => {
  31. if (fullAgent) fullAgent();
  32. });
  33. /* Firefox */
  34. document.addEventListener('mozfullscreenchange', () => {
  35. if (fullAgent) fullAgent();
  36. });
  37. /* Chrome, Safari and Opera */
  38. document.addEventListener('webkitfullscreenchange', () => {
  39. if (fullAgent) fullAgent();
  40. });
  41. /* IE / Edge */
  42. document.addEventListener('msfullscreenchange', () => {
  43. if (fullAgent) fullAgent();
  44. });
  45. export default class Video extends Component {
  46. constructor(props) {
  47. super(props);
  48. this.ready = false;
  49. this.state = { id: generateUUID(8), playing: false, fulling: false };
  50. }
  51. componentDidMount() {
  52. this.player = videojs(
  53. this.videoNode,
  54. {
  55. controls: false,
  56. sources: [
  57. {
  58. src: this.props.src,
  59. type: 'video/mp4',
  60. },
  61. ],
  62. },
  63. () => {
  64. this.ready = true;
  65. },
  66. );
  67. }
  68. componentWillUnmount() {
  69. if (this.player) {
  70. this.player.dispose();
  71. }
  72. }
  73. onPlay() {
  74. if (!this.ready) return;
  75. this.player.play();
  76. this.setState({ playing: true });
  77. }
  78. onPuase() {
  79. if (!this.ready) return;
  80. this.player.pause();
  81. this.setState({ playing: false });
  82. }
  83. onSpeed(speed) {
  84. this.player.playbackRate(speed);
  85. }
  86. onFullChange() {
  87. this.setState({ fulling: !this.state.fulling });
  88. if (this.props.onFullChange) this.props.onFullChange();
  89. }
  90. onFull() {
  91. fullAgent = () => this.onFullChange();
  92. fullScreen(this.state.id);
  93. }
  94. onExitFull() {
  95. exitFullscreen();
  96. }
  97. render() {
  98. const { action = true, btnList = [], children, onAction } = this.props;
  99. const { playing, fulling, id } = this.state;
  100. return (
  101. <div id={id} className={`video-item ${action ? 'action' : ''} ${fulling ? 'full' : ''}`}>
  102. <div className="video-wrapper">
  103. <video
  104. ref={node => {
  105. this.videoNode = node;
  106. }}
  107. />
  108. {!playing && <Assets className="play" name="play" onClick={() => this.onPlay()} />}
  109. {playing && <Assets className="stop" name="stop" onClick={() => this.onPuase()} />}
  110. </div>
  111. <div className="video-bottom">
  112. <div className="progress" />
  113. {action && (
  114. <div className="action-bar">
  115. <div className="d-i-b m-r-1">
  116. {!playing && <Assets name="play2" onClick={() => this.onPlay()} />}
  117. {playing && <Assets name="stop2" onClick={() => this.onPuase()} />}
  118. </div>
  119. <div className="d-i-b m-r-1">
  120. <Assets name="next2" />
  121. </div>
  122. <div className="flex-block" />
  123. {btnList.map(btn => {
  124. if (btn.full && !fulling) return '';
  125. return (
  126. <div className="d-i-b m-r-1">
  127. {btn.render ? (
  128. <div className="fix-btn d-i-b" onClick={() => onAction && onAction(btn.key)}>
  129. {btn.render(btn.active)}
  130. </div>
  131. ) : (
  132. <div
  133. className={`btn ${btn.active ? 'active' : ''}`}
  134. onClick={() => onAction && onAction(btn.key)}
  135. >
  136. {btn.title}
  137. </div>
  138. )}
  139. </div>
  140. );
  141. })}
  142. <div className="d-i-b m-r-1">
  143. <div className="btn">倍速</div>
  144. </div>
  145. <div className="d-i-b">
  146. {!fulling && <Assets name="full2" onClick={() => this.onFull()} />}
  147. {fulling && <Assets name="reduction2" onClick={() => this.onExitFull()} />}
  148. </div>
  149. </div>
  150. )}
  151. </div>
  152. {children}
  153. </div>
  154. );
  155. }
  156. }