Ott 1701 part 4 (#573)

* refactor(1701): removed MultiSourcePlayer

* refactor(1701): duration fix on live stream
keep-around/fdb88b04b32b9392e76795099e2ec47c9856b38b
Mirlan 4 years ago committed by Andrei Dekterev
parent d3b25de38d
commit 7e0f83ad2a
  1. 4
      src/features/MatchPage/store/index.tsx
  2. 25
      src/features/MatchPopup/store/hooks/usePlayerClickHandler.tsx
  3. 126
      src/features/MultiSourcePlayer/components/ProgressBar/stories.tsx
  4. 3
      src/features/MultiSourcePlayer/config.tsx
  5. 38
      src/features/MultiSourcePlayer/hooks/useVideoQuality.tsx
  6. 4
      src/features/StreamPlayer/components/ProgressBar/helpers/calculateChapterStyles/index.tsx
  7. 14
      src/features/StreamPlayer/hooks/index.tsx
  8. 6
      src/features/StreamPlayer/hooks/usePlayingHandlers.tsx
  9. 24
      src/requests/getFullMatchDuration.tsx
  10. 40
      src/requests/getVideos.tsx

@ -12,8 +12,8 @@ type Props = { children: ReactNode }
const MatchPageContext = createContext({} as Context)
export const MatchPageStore = ({ children }: Props) => {
const lexics = useMatchPage()
return <MatchPageContext.Provider value={lexics}>{children}</MatchPageContext.Provider>
const values = useMatchPage()
return <MatchPageContext.Provider value={values}>{children}</MatchPageContext.Provider>
}
export const useMatchPageStore = () => useContext(MatchPageContext)

@ -1,25 +0,0 @@
import type { MouseEvent } from 'react'
import { useState, useEffect } from 'react'
import { useLocation } from 'react-router'
import type { PlaylistOption } from 'features/MatchPage/types'
export const usePlayerClickHandler = () => {
const { pathname } = useLocation()
const [selectedPlaylist, setSelectedPlaylist] = useState<PlaylistOption>()
const handlePlaylistClick = (playlist: PlaylistOption, e?: MouseEvent) => {
e?.stopPropagation()
if (playlist !== selectedPlaylist) {
setSelectedPlaylist(playlist)
}
}
useEffect(() => {
setSelectedPlaylist(undefined)
}, [pathname])
return {
handlePlaylistClick,
selectedPlaylist,
}
}

@ -1,126 +0,0 @@
import type { ReactElement } from 'react'
import styled from 'styled-components/macro'
import { VolumeBar } from 'features/StreamPlayer/components/VolumeBar'
import {
Controls,
Fullscreen,
PlayStop,
} from 'features/StreamPlayer/styled'
import { ProgressBar } from '.'
const Story = {
component: ProgressBar,
title: 'ProgressBarWithChapters',
}
export default Story
const Wrapper = styled.div`
position: relative;
width: 95vw;
height: 50vh;
left: 50%;
transform: translateX(-50%);
background-color: #000;
`
const callback = () => {}
const renderInControls = (progressBarElement: ReactElement) => (
<Wrapper>
<Controls visible>
<PlayStop onClick={callback} playing={false} />
<VolumeBar
value={50}
muted={false}
onChange={callback}
onClick={callback}
/>
{progressBarElement}
<Fullscreen onClick={callback} isFullscreen={false} />
</Controls>
</Wrapper>
)
const duration = 70000
const chapters = [
{
duration: 30000,
endMs: 30000,
endOffsetMs: 0,
period: 0,
startMs: 0,
startOffsetMs: 0,
urls: {},
},
{
duration: 30000,
endMs: 60000,
endOffsetMs: 0,
period: 0,
startMs: 30000,
startOffsetMs: 0,
urls: {},
},
{
duration: 10000,
endMs: 70000,
endOffsetMs: 0,
period: 0,
startMs: 60000,
startOffsetMs: 0,
urls: {},
},
]
export const Empty = () => renderInControls(
<ProgressBar
activeChapterIndex={0}
allPlayedProgress={0}
duration={duration}
chapters={chapters}
onPlayedProgressChange={callback}
playedProgress={0}
loadedProgress={0}
/>,
)
export const HalfLoaded = () => renderInControls(
<ProgressBar
activeChapterIndex={0}
allPlayedProgress={0}
duration={duration}
chapters={chapters}
onPlayedProgressChange={callback}
playedProgress={0}
loadedProgress={30000}
/>,
)
export const HalfPlayed = () => renderInControls(
<ProgressBar
activeChapterIndex={1}
allPlayedProgress={1}
duration={duration}
chapters={chapters}
onPlayedProgressChange={callback}
playedProgress={30000}
loadedProgress={0}
/>,
)
export const Loaded40AndPlayed20 = () => renderInControls(
<ProgressBar
activeChapterIndex={0}
allPlayedProgress={0}
duration={duration}
chapters={chapters}
onPlayedProgressChange={callback}
playedProgress={20000}
loadedProgress={40000}
/>,
)

@ -1,3 +0,0 @@
export const REWIND_SECONDS = 5
export const HOUR_IN_MILLISECONDS = 60 * 60 * 1000

@ -1,38 +0,0 @@
import keys from 'lodash/keys'
import uniq from 'lodash/uniq'
import orderBy from 'lodash/orderBy'
import includes from 'lodash/includes'
import { useLocalStore } from 'hooks'
import type { Chapters } from '../types'
const getVideoQualities = (chapters: Chapters) => {
const qualities = uniq(keys(chapters[0]?.urls))
return orderBy(
qualities,
Number,
'desc',
)
}
export const useVideoQuality = (chapters: Chapters) => {
const videoQualities = getVideoQualities(chapters)
const qualityValidator = (localStorageQuality: string) => (
includes(videoQualities, localStorageQuality)
)
const [selectedQuality, setSelectedQuality] = useLocalStore({
// по умолчанию наилучшее качество
defaultValue: videoQualities[0],
key: 'player_quality',
validator: qualityValidator,
})
return {
selectedQuality,
setSelectedQuality,
videoQualities,
}
}

@ -49,7 +49,9 @@ export const calculateChapterStyles = ({
...chapter,
loaded: calculateChapterProgress(loadedProgress, chapter),
played: calculateChapterProgress(playedProgress, chapter),
width: chapter.duration * 100 / videoDuration,
width: chapter.duration
? chapter.duration * 100 / videoDuration
: 100,
}
return [
...playedChapters,

@ -7,10 +7,12 @@ import {
import size from 'lodash/size'
import isNumber from 'lodash/isNumber'
import isEmpty from 'lodash/isEmpty'
import { isIOS } from 'config/userAgent'
import { useObjectState } from 'hooks/useObjectState'
import { useEventListener } from 'hooks/useEventListener'
import { useVolume } from 'features/VideoPlayer/hooks/useVolume'
import { useNoNetworkPopupStore } from 'features/NoNetworkPopup'
@ -197,6 +199,14 @@ export const useVideoPlayer = ({
setPlayerState({ playedProgress: liveProgressMs, seek: liveProgressMs / 1000 })
}, [duration, setPlayerState])
useEventListener({
callback: (e: KeyboardEvent) => {
if (e.code === 'ArrowLeft') rewindBackward()
else if (e.code === 'ArrowRight') rewindForward()
},
event: 'keydown',
})
useEffect(() => {
if (isNumber(seek)) {
setPlayerState({ seek: undefined })
@ -216,11 +226,15 @@ export const useVideoPlayer = ({
}, [chapters, setPlayerState])
useEffect(() => {
if (isLive || isEmpty(chapters)) return
const { duration: chapterDuration } = getActiveChapter()
if (playedProgress >= chapterDuration && !seeking) {
playNextChapter()
}
}, [
isLive,
chapters,
getActiveChapter,
playedProgress,
seeking,

@ -15,7 +15,11 @@ export const usePlayingHandlers = (
setPlayerState((state) => (
state.ready
? state
: { playing: true, ready: true }
: {
buffering: false,
playing: true,
ready: true,
}
))
}, [setPlayerState])

@ -1,24 +0,0 @@
import pipe from 'lodash/fp/pipe'
import orderBy from 'lodash/fp/orderBy'
import sumBy from 'lodash/fp/sumBy'
import uniqBy from 'lodash/fp/uniqBy'
import type { Videos, Video } from './getVideos'
import { getVideos } from './getVideos'
const calculateDuration = (videos: Videos) => {
const durationMs = pipe(
orderBy(({ quality }: Video) => Number(quality), 'desc'),
uniqBy(({ period }: Video) => period),
sumBy(({ duration }: Video) => duration),
)(videos)
return durationMs / 1000
}
/**
* Временный способ получения длительности матча
*/
export const getFullMatchDuration = async (...args: Parameters<typeof getVideos>) => {
const videos = await getVideos(...args)
return calculateDuration(videos)
}

@ -1,40 +0,0 @@
import isEmpty from 'lodash/isEmpty'
import filter from 'lodash/filter'
import { API_ROOT, SportTypes } from 'config'
import { callApi } from 'helpers'
const filterByIds = (videos: Videos) => {
const zeroIdVideos = filter(videos, { abc: '0' })
return isEmpty(zeroIdVideos) ? videos : zeroIdVideos
}
export type Video = {
/** id дорожки */
abc: string,
duration: number,
period: number,
quality: string,
start_ms: number,
url: string,
}
export type Videos = Array<Video>
export const getVideos = (
sportType: SportTypes,
matchId: number,
): Promise<Videos> => {
const config = {
body: {
match_id: matchId,
sport_id: sportType,
},
}
return callApi({
config,
// эндпоинт удалили со стейджинга, временно ссылаемся на прод
url: `${API_ROOT}/videoapi`,
}).then(filterByIds)
}
Loading…
Cancel
Save