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/MatchPage/components/FinishedMatch/helpers.tsx

137 lines
3.4 KiB

import map from 'lodash/map'
import last from 'lodash/last'
import uniq from 'lodash/uniq'
import filter from 'lodash/filter'
import reduce from 'lodash/reduce'
import concat from 'lodash/concat'
import orderBy from 'lodash/orderBy'
import isEmpty from 'lodash/isEmpty'
import groupBy from 'lodash/groupBy'
import type {
Videos,
Episodes,
Episode,
} from 'requests'
import type { Chapters, Urls } from 'features/MultiSourcePlayer/types'
import type { PlaylistOption } from '../../types'
import { FULL_GAME_KEY } from '../../helpers/buildPlaylists'
const getUniquePeriods = (videos: Videos) => uniq(map(videos, ({ period }) => period))
type Video = {
duration: number,
period: number,
urls: Urls,
}
const getVideoByPeriod = (videos: Videos, period: number) => {
const videosWithSamePeriod = filter(videos, { period })
if (isEmpty(videosWithSamePeriod)) return null
const urls = reduce(
videosWithSamePeriod,
(acc: Urls, video) => ({
...acc,
[video.quality]: video.url,
}),
{},
)
const [video] = videosWithSamePeriod
return {
duration: video.duration,
period: video.period,
urls,
}
}
const getVideoByPeriods = (videos: Videos, periods: Array<number>) => (
reduce(
periods,
(acc: Array<Video>, period) => {
const video = getVideoByPeriod(videos, period)
return video ? concat(acc, video) : acc
},
[],
)
)
const getFullMatchChapters = (videos: Array<Video>) => {
const sortedVideos = orderBy(videos, ({ period }) => period)
return reduce(
sortedVideos,
(acc: Chapters, video) => {
const prevVideoEndMs = last(acc)?.endMs || 0
const endMs = prevVideoEndMs + video.duration
const nextChapter = {
duration: video.duration,
endMs,
endOffsetMs: endMs,
period: video.period,
startMs: prevVideoEndMs,
startOffsetMs: 0,
urls: video.urls,
}
return concat(acc, nextChapter)
},
[],
)
}
const getEpisodeUrls = (urls: Urls, episode: Episode) => reduce(
urls,
(
acc: Urls,
url,
qulaity,
) => {
acc[qulaity] = `${url}#t=${episode.s},${episode.e}`
return acc
},
{},
)
const getPlaylistChapters = (videos: Array<Video>, episodes: Episodes) => {
const groupedByPeriods = groupBy(videos, ({ period }) => period)
return reduce(
episodes,
(acc: Chapters, episode) => {
const video = groupedByPeriods[episode.h]?.[0]
if (!video || episode.s >= episode.e) return acc
const episodeDuration = (episode.e - episode.s) * 1000
const prevVideoEndMs = last(acc)?.endMs || 0
const nextChapter = {
duration: episodeDuration,
endMs: prevVideoEndMs + episodeDuration,
endOffsetMs: episode.e * 1000,
period: video.period,
startMs: prevVideoEndMs,
startOffsetMs: episode.s * 1000,
urls: getEpisodeUrls(video.urls, episode),
}
return concat(acc, nextChapter)
},
[],
)
}
type Args = {
episodes: Episodes,
selectedPlaylist?: PlaylistOption,
videos: Videos,
}
export const buildChapters = ({
episodes,
selectedPlaylist,
videos,
}: Args) => {
const periods = getUniquePeriods(videos)
const highQualityVideos = getVideoByPeriods(videos, periods)
return selectedPlaylist?.id === FULL_GAME_KEY
? getFullMatchChapters(highQualityVideos)
: getPlaylistChapters(highQualityVideos, episodes)
}