You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VideoManager.tsx 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // @ts-expect-error
  2. import Logger from '@jitsi/logger';
  3. import React, { RefObject } from 'react';
  4. import Video from 'react-native-video';
  5. import { connect } from 'react-redux';
  6. import { PLAYBACK_STATUSES } from '../../constants';
  7. import AbstractVideoManager, {
  8. IProps,
  9. _mapStateToProps
  10. } from './AbstractVideoManager';
  11. // @ts-ignore
  12. const logger = Logger.getLogger(__filename);
  13. interface IState {
  14. currentTime: number;
  15. paused: boolean;
  16. }
  17. /**
  18. * Manager of shared video.
  19. */
  20. class VideoManager extends AbstractVideoManager<IState> {
  21. playerRef: RefObject<Video>;
  22. /**
  23. * Initializes a new VideoManager instance.
  24. *
  25. * @param {Object} props - This component's props.
  26. *
  27. * @returns {void}
  28. */
  29. constructor(props: IProps) {
  30. super(props);
  31. this.state = {
  32. currentTime: 0,
  33. paused: false
  34. };
  35. this.playerRef = React.createRef();
  36. this.onPlaybackRateChange = this.onPlaybackRateChange.bind(this);
  37. this.onProgress = this.onProgress.bind(this);
  38. }
  39. /**
  40. * Retrieves the current player ref.
  41. */
  42. get player() {
  43. return this.playerRef.current;
  44. }
  45. /**
  46. * Indicates the playback state of the video.
  47. *
  48. * @returns {string}
  49. */
  50. getPlaybackStatus() {
  51. let status;
  52. if (this.state.paused) {
  53. status = PLAYBACK_STATUSES.PAUSED;
  54. } else {
  55. status = PLAYBACK_STATUSES.PLAYING;
  56. }
  57. return status;
  58. }
  59. /**
  60. * Retrieves current time.
  61. *
  62. * @returns {number}
  63. */
  64. getTime() {
  65. return this.state.currentTime;
  66. }
  67. /**
  68. * Seeks video to provided time.
  69. *
  70. * @param {number} time - The time to seek to.
  71. *
  72. * @returns {void}
  73. */
  74. seek(time: number) {
  75. if (this.player) {
  76. this.player.seek(time);
  77. }
  78. }
  79. /**
  80. * Plays video.
  81. *
  82. * @returns {void}
  83. */
  84. play() {
  85. this.setState({
  86. paused: false
  87. });
  88. }
  89. /**
  90. * Pauses video.
  91. *
  92. * @returns {void}
  93. */
  94. pause() {
  95. this.setState({
  96. paused: true
  97. });
  98. }
  99. /**
  100. * Handles playback rate changed event.
  101. *
  102. * @param {Object} options.playbackRate - Playback rate: 1 - playing, 0 - paused, other - slowed down / sped up.
  103. * @returns {void}
  104. */
  105. onPlaybackRateChange({ playbackRate }: { playbackRate: number; }) {
  106. if (playbackRate === 0) {
  107. this.setState({
  108. paused: true
  109. }, () => {
  110. this.onPause();
  111. });
  112. }
  113. if (playbackRate === 1) {
  114. this.setState({
  115. paused: false
  116. }, () => {
  117. this.onPlay();
  118. });
  119. }
  120. }
  121. /**
  122. * Handles progress update event.
  123. *
  124. * @param {Object} options - Progress event options.
  125. * @returns {void}
  126. */
  127. onProgress(options: { currentTime: number; }) {
  128. this.setState({ currentTime: options.currentTime });
  129. this.throttledFireUpdateSharedVideoEvent();
  130. }
  131. /**
  132. * Retrieves video tag params.
  133. *
  134. * @returns {void}
  135. */
  136. getPlayerOptions() {
  137. const { _isOwner, videoId, width, height } = this.props;
  138. const { paused } = this.state;
  139. const options: any = {
  140. paused,
  141. progressUpdateInterval: 5000,
  142. resizeMode: 'cover' as const,
  143. style: {
  144. height,
  145. width
  146. },
  147. source: { uri: videoId },
  148. controls: _isOwner,
  149. pictureInPicture: false,
  150. onProgress: this.onProgress,
  151. onError: (event: Error) => {
  152. logger.error('Error in the player:', event);
  153. }
  154. };
  155. if (_isOwner) {
  156. options.onPlaybackRateChange = this.onPlaybackRateChange;
  157. }
  158. return options;
  159. }
  160. /**
  161. * Implements React Component's render.
  162. *
  163. * @inheritdoc
  164. */
  165. render() {
  166. return (
  167. <Video
  168. ref = { this.playerRef }
  169. { ...this.getPlayerOptions() } />
  170. );
  171. }
  172. }
  173. export default connect(_mapStateToProps)(VideoManager);