aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Player/components/Video.js
blob: 2167ee03562ec771f411cbf9d56f78fa516de238 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { useState, useEffect, useRef } from 'react'
import Image from 'next/image'
import Splash from 'components/Splash'
import usePopup from 'hooks/usePopup'
import useSettings from 'hooks/useSettings'
import fetchJson from 'helpers/fetchJson'

const Video = ({ playlist, current, setCurrent, audioOnly = false, setDetails }) => {
  const { t } = useSettings()
  const { setPopup } = usePopup()
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(null)
  const videoEl = useRef()

  const handleEnd = () => {
    setCurrent(current === playlist.length - 1 ? null : current + 1)
  }

  useEffect(() => {
    setLoading(true)
    if (current === null) {
      setData(null)
      setDetails(d => ({ ...d, show: false }))
    }

    switch (playlist[current].type.split('_')[0]) {
      case 'yt':
        fetchJson('/api/youtube/video', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id: playlist[current].id })
        })
          .then(v => {
            setData({
              id: v.videoDetails.videoId,
              thumbnail: v.videoDetails.thumbnails[0].url,
              formats: v.formats
                .filter(v => !v.isHLS && v.hasAudio && (audioOnly ? !v.hasVideo : v.hasVideo))
                .sort((a, b) => audioOnly ? a.audioBitrate < b.audioBitrate : a.bitrate < b.bitrate)
            })
            setDetails(d => ({
              ...d,
              title: v.videoDetails.title,
              description: v.videoDetails.description
            }))
          })
          .catch(() => {
            setData({
              // thumbnail: v.videoDetails.thumbnails[0].url,
              formats: []
            })
            setDetails(d => ({
              ...d,
              title: 'Error',
              description: 'Item did not load correctly'
            }))
            setPopup({
              content: t('player_youtube_fetching_error'),
              time: 2000,
              error: true
            })
          })
          .finally(() => setLoading(false))
      break
      case 'radio':
        const { url, mimeType, thumbnail, title } = playlist[current];
        setData({
          thumbnail,
          formats: [{ url, mimeType }]
        })
        setDetails(d => ({
          ...d,
          title: 'Gra radio ' + title,
          description: ''
        }))
        setLoading(false)
      break
      default:
    }
  }, [playlist && playlist[current].id, audioOnly])

  return (
    data && !loading
      ? (
        <>
          <video
            onEnded={handleEnd}
            ref={videoEl}
            key={data.id}
            controls
            playsInline
            webkit-playsInline
            autoPlay
          >
            {
              data.formats.map(s => (
                <source src={s.url} type={s.mimeType} key={s.url} />
              ))
            }
            Your browser does not support the video tag.
          </video>
          {(audioOnly || playlist[current].type === 'radio') && (
            <>
              <div />
              <span style={{ backgroundImage: `url(${data.thumbnail})` }} />
              <Image src='/phono.png' height='160' width='90' />
            </>
          )}
        </>
        )
      : (
        <Splash />
        )
  )
}

export default Video