123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import React from 'react';
- import PropTypes from 'prop-types';
- import videoConnect from './../video/video';
- import copy from './copy';
- import {
- setVolume,
- showTrack,
- showSpeed,
- toggleTracks,
- toggleSpeeds,
- toggleMute,
- togglePause,
- setCurrentTime,
- toggleFullscreen,
- getPercentagePlayed,
- getPercentageBuffered
- } from './../video/api';
- import styles from './DefaultPlayer.css';
- import Time from './Time/Time';
- import Seek from './Seek/Seek';
- import Volume from './Volume/Volume';
- import Captions from './Captions/Captions';
- import Speed from './Speed/Speed';
- import PlayPause from './PlayPause/PlayPause';
- import Fullscreen from './Fullscreen/Fullscreen';
- import Overlay from './Overlay/Overlay';
-
- const DefaultPlayer = ({
- copy,
- video,
- style,
- controls,
- children,
- className,
- onSeekChange,
- onVolumeChange,
- onVolumeClick,
- onCaptionsClick,
- onSpeedClick,
- onPlayPauseClick,
- onFullscreenClick,
- onCaptionsItemClick,
- onSpeedsItemClick,
- ...restProps
- }) => {
- let playbackrates = restProps['data-playbackrates'];
- if (playbackrates) {
- playbackrates = JSON.parse(playbackrates);
- }
- let onScreenClickCallback = restProps['onScreenClickCallback'];
- return (
- <div className={[
- styles.component,
- className
- ].join(' ')}
- style={style}>
- <video
- className={styles.video}
- {...restProps}>
- {children}
- </video>
- <Overlay
- onClick={onPlayPauseClick}
- {...video} />
- {controls && controls.length && !video.error
- ? <div className={styles.controls}>
- {controls.map((control, i) => {
- switch (control) {
- case 'Seek':
- return <Seek
- key={i}
- ariaLabel={copy.seek}
- className={styles.seek}
- onChange={onSeekChange}
- {...video} />;
- case 'PlayPause':
- return <PlayPause
- key={i}
- ariaLabelPlay={copy.play}
- ariaLabelPause={copy.pause}
- onClick={onPlayPauseClick}
- {...video} />;
- case 'Fullscreen':
- return <Fullscreen
- key={i}
- ariaLabel={copy.fullscreen}
- onClick={onFullscreenClick}
- onScreenClickCallback={onScreenClickCallback}
- {...video} />;
- case 'Time':
- return <Time
- key={i}
- {...video} />;
- case 'Volume':
- return <Volume
- key={i}
- onClick={onVolumeClick}
- onChange={onVolumeChange}
- ariaLabelMute={copy.mute}
- ariaLabelUnmute={copy.unmute}
- ariaLabelVolume={copy.volume}
- {...video} />;
- case 'Captions':
- return video.textTracks && video.textTracks.length
- ? <Captions
- key={i}
- onClick={onCaptionsClick}
- ariaLabel={copy.captions}
- onItemClick={onCaptionsItemClick}
- {...video} />
- : null;
- case 'Speed':
- return playbackrates && playbackrates.length > 0
- ? <Speed
- key={i}
- onClick={onSpeedClick}
- ariaLabel={copy.captions}
- onItemClick={onSpeedsItemClick}
- playbackrates={playbackrates}
- {...video} />
- : null;
- default:
- return null;
- }
- })}
- </div>
- : null}
- </div>
- );
- };
-
- const controls = ['PlayPause', 'Seek', 'Fullscreen', 'Speed', 'Volume', 'Time', 'Captions'];
-
- DefaultPlayer.defaultProps = {
- copy,
- controls,
- video: {}
- };
-
- DefaultPlayer.propTypes = {
- copy: PropTypes.object.isRequired,
- controls: PropTypes.arrayOf(PropTypes.oneOf(controls)),
- video: PropTypes.object.isRequired
- };
-
- const connectedPlayer = videoConnect(
- DefaultPlayer,
- ({ networkState, readyState, error, ...restState }) => ({
- video: {
- readyState,
- networkState,
- error: error || (readyState > 0 && networkState === 3),
- // TODO: This is not pretty. Doing device detection to remove
- // spinner on iOS devices for a quick and dirty win. We should see if
- // we can use the same readyState check safely across all browsers.
- loading: readyState < (/iPad|iPhone|iPod/.test(navigator.userAgent) ? 1 : 4),
- percentagePlayed: getPercentagePlayed(restState),
- percentageBuffered: getPercentageBuffered(restState),
- ...restState
- }
- }),
- (videoEl, state) => ({
- onFullscreenClick: () => toggleFullscreen(videoEl.parentElement),
- onVolumeClick: () => toggleMute(videoEl, state),
- onCaptionsClick: () => toggleTracks(state),
- onSpeedClick: () => toggleSpeeds(videoEl, state),
- onPlayPauseClick: () => togglePause(videoEl, state),
- onCaptionsItemClick: (track) => showTrack(state, track),
- onSpeedsItemClick: (speed) => showSpeed(videoEl, state, speed),
- onVolumeChange: (e) => setVolume(videoEl, state, e.target.value),
- onSeekChange: (e) => setCurrentTime(videoEl, state, e.target.value * state.duration / 100)
- })
- );
-
- export {
- connectedPlayer as default,
- DefaultPlayer,
- Time,
- Seek,
- Volume,
- Captions,
- PlayPause,
- Fullscreen,
- Overlay
- };
|