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.
 
 
 
 
spa_instat_tv/src/features/StreamPlayer/index.tsx

295 lines
8.3 KiB

import { Fragment, memo } from 'react'
import includes from 'lodash/includes'
import isEmpty from 'lodash/isEmpty'
import { isMobileDevice } from 'config'
import { Loader } from 'features/Loader'
import { VideoPlayer } from 'features/VideoPlayer'
import { useMatchPageStore } from 'features/MatchPage/store'
import { Name } from 'features/Name'
import { FiltersPopup } from 'features/MatchSidePlaylists/components/FiltersPopup'
import { WaterMark } from 'components/WaterMark'
import { AccessTimer } from 'components/AccessTimer'
import { PLAYER_ADS, PLAYER_MOBILE_ADS } from 'components/Ads/types'
import { HeaderAds } from 'components/Ads'
import { REWIND_SECONDS } from './config'
import type { Props } from './hooks'
import { useVideoPlayer } from './hooks'
import { useAuthStore } from '../AuthStore'
import { Controls } from './components/Controls'
import RewindMobile from './components/RewindMobile'
import {
PlayerWrapper,
CenterControls,
PlayStop,
LoaderWrapper,
Backward,
Forward,
ControlsGradient,
TeamsDetailsWrapper,
EpisodeInfo,
EpisodeInfoName,
EpisodeInfoOrder,
EpisodeInfoDivider,
CloseButton,
PlayerAdsWrapper,
Canvas,
} from './styled'
const CanvasComponent = memo(Canvas)
const tournamentsWithWatermark = {
316: 'Tunisia',
1136: 'Brasil',
1448: 'India',
5950: 'India',
}
/**
* HLS плеер, применяется на лайв и завершенных матчах
*/
export const StreamPlayer = (props: Props) => {
const {
access,
ads,
episodeInfo,
isOpenFiltersPopup,
isPlayingEpisode,
profile,
} = useMatchPageStore()
const { user } = useAuthStore()
const {
activeChapterIndex,
allPlayedProgress,
audioTracks,
backToLive,
buffering,
canvasRef,
centerControlsVisible,
changeAudioTrack,
chapters,
currentPlayingOrder,
duration,
hideCenterControls,
isFullscreen,
isLive,
isLiveTime,
likeButtonRef,
loadedProgress,
mainControlsVisible,
muted,
onDuration,
onError,
onFullscreenClick,
onLoadedProgress,
onMouseEnter,
onMouseLeave,
onMouseMove,
onPause,
onPlay,
onPlayedProgress,
onPlayerClick,
onPlaying,
onProgressChange,
onQualitySelect,
onReady,
onTouchEnd,
onTouchStart,
onVolumeChange,
onVolumeClick,
onWaiting,
playedProgress,
playing,
ready,
rewindBackward,
rewindForward,
seek,
selectedAudioTrack,
selectedQuality,
setGenerateParticles,
showCenterControls,
stopPlayingEpisodes,
togglePlaying,
url,
videoQualities,
videoRef,
volume,
volumeInPercent,
wrapperRef,
} = useVideoPlayer(props)
return (
<PlayerWrapper
ref={wrapperRef}
playing={playing}
onClick={isMobileDevice ? showCenterControls : onPlayerClick}
onMouseMove={onMouseMove}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
isPlayingEpisode={isPlayingEpisode}
>
{ads
&& (
<PlayerAdsWrapper isFullscreen={isFullscreen}>
<HeaderAds ads={ads.filter(({ position }) => (isMobileDevice
? position.id === PLAYER_MOBILE_ADS
: includes(PLAYER_ADS, position.id)))}
/>
</PlayerAdsWrapper>
)}
{isPlayingEpisode && (
<EpisodeInfo>
{!isEmpty(episodeInfo) && (
<Fragment>
<EpisodeInfoName>
{isMobileDevice
? (
<Fragment>
{episodeInfo.playerOrTeamName}
{episodeInfo.playerOrTeamName && <br />}
{episodeInfo.paramName}
</Fragment>
)
: `${episodeInfo.playerOrTeamName || ''}${episodeInfo.paramName && episodeInfo.playerOrTeamName ? ' - ' : ''}${episodeInfo.paramName || ''}`}
</EpisodeInfoName>
{currentPlayingOrder > 0 && (
<EpisodeInfoOrder>
{currentPlayingOrder}
<EpisodeInfoDivider />
{episodeInfo.episodesCount}
</EpisodeInfoOrder>
)}
</Fragment>
)}
<CloseButton onClick={stopPlayingEpisodes} />
</EpisodeInfo>
)}
{isOpenFiltersPopup && <FiltersPopup />}
<LoaderWrapper buffering={buffering}>
<Loader color='#515151' />
</LoaderWrapper>
{user
&& (Boolean(
tournamentsWithWatermark[profile?.tournament.id as keyof typeof tournamentsWithWatermark],
) || profile?.watermark)
&& playing
&& isLive
&& (
<WaterMark value={user?.profile?.sub} />
)}
<VideoPlayer
width='100%'
height='100%'
src={url}
ref={videoRef}
playing={playing}
volume={volume}
muted={muted}
seek={seek}
isFullscreen={isFullscreen}
onLoadedProgress={onLoadedProgress}
onPlayedProgress={onPlayedProgress}
onDurationChange={onDuration}
onEnded={togglePlaying}
onReady={onReady}
onPause={onPause}
onPlay={onPlay}
onPlaying={onPlaying}
onWaiting={onWaiting}
onError={onError}
/>
{isMobileDevice && isFullscreen && mainControlsVisible && profile && (
<TeamsDetailsWrapper>
<Name nameObj={profile.team1} />
{` ${profile.team1.score}-${profile.team2.score} `}
<Name nameObj={profile.team2} />
</TeamsDetailsWrapper>
)}
{ready && (
<CenterControls controlsVisible={centerControlsVisible} playing={playing}>
{isMobileDevice
? <RewindMobile isBackward rewindCallback={rewindBackward} />
: <Backward size='lg' onClick={rewindBackward} id='match_video_screen_back'>{REWIND_SECONDS}</Backward>}
<PlayStop
size='lg'
fullWidth
marginRight={0}
playing={playing}
onClickCapture={() => {
togglePlaying()
hideCenterControls()
}}
id='match_video_screen_start_stop'
/>
{isMobileDevice
? <RewindMobile isForward rewindCallback={rewindForward} />
: <Forward size='lg' onClick={rewindForward} id='match_video_screen_forward'>{REWIND_SECONDS}</Forward>}
</CenterControls>
)}
<Controls
allPlayedProgress={allPlayedProgress}
audioTracks={audioTracks}
backToLive={backToLive}
changeAudioTrack={changeAudioTrack}
controlsVisible={mainControlsVisible}
duration={duration}
isFullscreen={isFullscreen}
isLive={profile?.live}
isLiveTime={isLiveTime}
isStorage={profile?.storage}
loadedProgress={loadedProgress}
muted={muted}
onFullscreenClick={onFullscreenClick}
onProgressChange={onProgressChange}
onQualitySelect={onQualitySelect}
onTouchEnd={onTouchEnd}
onTouchStart={onTouchStart}
onVolumeChange={onVolumeChange}
onVolumeClick={onVolumeClick}
playedProgress={playedProgress}
playing={playing}
rewindBackward={rewindBackward}
rewindForward={rewindForward}
selectedQuality={selectedQuality}
togglePlaying={togglePlaying}
videoQualities={videoQualities}
videoRef={videoRef}
volume={volume}
volumeInPercent={volumeInPercent}
activeChapterIndex={activeChapterIndex}
liveChapters={chapters}
selectedAudioTrack={selectedAudioTrack}
setGenerateParticles={setGenerateParticles}
likeButtonRef={likeButtonRef}
isFullMatchChapter={chapters[0].isFullMatchChapter}
/>
<ControlsGradient isVisible={mainControlsVisible} />
{!user && (
<AccessTimer
access={access}
isFullscreen={isFullscreen}
onFullscreenClick={onFullscreenClick}
playing={ready && playing && !!playedProgress}
videoRef={videoRef}
/>
)}
{user && chapters[0].isFullMatchChapter && (
<CanvasComponent
ref={canvasRef}
width={wrapperRef.current?.clientWidth}
height={wrapperRef.current?.clientHeight}
/>
)}
</PlayerWrapper>
)
}