]>
Commit | Line | Data |
---|---|---|
583eb04b | 1 | import { VideoFile } from '@shared/models' |
4097c6d6 | 2 | import { escapeHTML } from '@shared/core-utils/renderer' |
e945b184 | 3 | |
c6352f2c C |
4 | function toTitleCase (str: string) { |
5 | return str.charAt(0).toUpperCase() + str.slice(1) | |
6 | } | |
7 | ||
31b6ddf8 C |
8 | function isWebRTCDisabled () { |
9 | return !!((window as any).RTCPeerConnection || (window as any).mozRTCPeerConnection || (window as any).webkitRTCPeerConnection) === false | |
10 | } | |
11 | ||
3e2bc4ea | 12 | function isIOS () { |
b6a8cfc5 C |
13 | if (/iPad|iPhone|iPod/.test(navigator.platform)) { |
14 | return true | |
15 | } | |
16 | ||
17 | // Detect iPad Desktop mode | |
b12ce2b8 | 18 | return !!(navigator.maxTouchPoints && |
b6a8cfc5 | 19 | navigator.maxTouchPoints > 2 && |
b12ce2b8 | 20 | /MacIntel/.test(navigator.platform)) |
3e2bc4ea C |
21 | } |
22 | ||
23 | function isSafari () { | |
24 | return /^((?!chrome|android).)*safari/i.test(navigator.userAgent) | |
25 | } | |
26 | ||
c6352f2c C |
27 | // https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts |
28 | // Don't import all Angular stuff, just copy the code with shame | |
29 | const dictionaryBytes: Array<{max: number, type: string}> = [ | |
30 | { max: 1024, type: 'B' }, | |
31 | { max: 1048576, type: 'KB' }, | |
32 | { max: 1073741824, type: 'MB' }, | |
33 | { max: 1.0995116e12, type: 'GB' } | |
34 | ] | |
c199c427 | 35 | function bytes (value: number) { |
c6352f2c C |
36 | const format = dictionaryBytes.find(d => value < d.max) || dictionaryBytes[dictionaryBytes.length - 1] |
37 | const calc = Math.floor(value / (format.max / 1024)).toString() | |
38 | ||
39 | return [ calc, format.type ] | |
40 | } | |
41 | ||
d1bd87e0 C |
42 | function isMobile () { |
43 | return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) | |
44 | } | |
45 | ||
2f4c784a | 46 | function buildVideoLink (options: { |
951b582f | 47 | baseUrl?: string |
1f6824c9 | 48 | |
951b582f C |
49 | startTime?: number |
50 | stopTime?: number | |
960a11e8 | 51 | |
951b582f | 52 | subtitle?: string |
1f6824c9 | 53 | |
951b582f C |
54 | loop?: boolean |
55 | autoplay?: boolean | |
56 | muted?: boolean | |
2f4c784a C |
57 | |
58 | // Embed options | |
951b582f C |
59 | title?: boolean |
60 | warningTitle?: boolean | |
2f4c784a | 61 | controls?: boolean |
189ab8de | 62 | peertubeLink?: boolean |
2f4c784a C |
63 | } = {}) { |
64 | const { baseUrl } = options | |
65 | ||
66 | const url = baseUrl | |
67 | ? baseUrl | |
a1eda903 | 68 | : window.location.origin + window.location.pathname.replace('/embed/', '/w/') |
2f4c784a | 69 | |
951b582f | 70 | const params = generateParams(window.location.search) |
2f4c784a | 71 | |
fc418874 | 72 | if (options.startTime !== undefined && options.startTime !== null) { |
2f4c784a C |
73 | const startTimeInt = Math.floor(options.startTime) |
74 | params.set('start', secondsToTime(startTimeInt)) | |
75 | } | |
76 | ||
77 | if (options.stopTime) { | |
78 | const stopTimeInt = Math.floor(options.stopTime) | |
79 | params.set('stop', secondsToTime(stopTimeInt)) | |
960a11e8 C |
80 | } |
81 | ||
2f4c784a C |
82 | if (options.subtitle) params.set('subtitle', options.subtitle) |
83 | ||
84 | if (options.loop === true) params.set('loop', '1') | |
85 | if (options.autoplay === true) params.set('autoplay', '1') | |
86 | if (options.muted === true) params.set('muted', '1') | |
87 | if (options.title === false) params.set('title', '0') | |
88 | if (options.warningTitle === false) params.set('warningTitle', '0') | |
89 | if (options.controls === false) params.set('controls', '0') | |
189ab8de | 90 | if (options.peertubeLink === false) params.set('peertubeLink', '0') |
2f4c784a | 91 | |
951b582f C |
92 | return buildUrl(url, params) |
93 | } | |
94 | ||
95 | function buildPlaylistLink (options: { | |
96 | baseUrl?: string | |
3e0e8d4a | 97 | |
2539932e | 98 | playlistPosition?: number |
3e0e8d4a | 99 | }) { |
951b582f C |
100 | const { baseUrl } = options |
101 | ||
102 | const url = baseUrl | |
103 | ? baseUrl | |
a1eda903 | 104 | : window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/w/p/') |
951b582f C |
105 | |
106 | const params = generateParams(window.location.search) | |
107 | ||
108 | if (options.playlistPosition) params.set('playlistPosition', '' + options.playlistPosition) | |
109 | ||
110 | return buildUrl(url, params) | |
111 | } | |
112 | ||
113 | function buildUrl (url: string, params: URLSearchParams) { | |
2f4c784a C |
114 | let hasParams = false |
115 | params.forEach(() => hasParams = true) | |
116 | ||
117 | if (hasParams) return url + '?' + params.toString() | |
118 | ||
11b8762f | 119 | return url |
1f6824c9 C |
120 | } |
121 | ||
951b582f C |
122 | function generateParams (url: string) { |
123 | const params = new URLSearchParams(window.location.search) | |
124 | // Unused parameters in embed | |
125 | params.delete('videoId') | |
126 | params.delete('resume') | |
127 | ||
128 | return params | |
129 | } | |
130 | ||
1f6824c9 | 131 | function timeToInt (time: number | string) { |
3b019808 | 132 | if (!time) return 0 |
1f6824c9 C |
133 | if (typeof time === 'number') return time |
134 | ||
f0a39880 | 135 | const reg = /^((\d+)[h:])?((\d+)[m:])?((\d+)s?)?$/ |
1f6824c9 C |
136 | const matches = time.match(reg) |
137 | ||
138 | if (!matches) return 0 | |
139 | ||
140 | const hours = parseInt(matches[2] || '0', 10) | |
141 | const minutes = parseInt(matches[4] || '0', 10) | |
142 | const seconds = parseInt(matches[6] || '0', 10) | |
143 | ||
144 | return hours * 3600 + minutes * 60 + seconds | |
145 | } | |
146 | ||
f0a39880 | 147 | function secondsToTime (seconds: number, full = false, symbol?: string) { |
1f6824c9 C |
148 | let time = '' |
149 | ||
fc418874 C |
150 | if (seconds === 0 && !full) return '0s' |
151 | ||
f0a39880 C |
152 | const hourSymbol = (symbol || 'h') |
153 | const minuteSymbol = (symbol || 'm') | |
154 | const secondsSymbol = full ? '' : 's' | |
155 | ||
c4710631 | 156 | const hours = Math.floor(seconds / 3600) |
f0a39880 C |
157 | if (hours >= 1) time = hours + hourSymbol |
158 | else if (full) time = '0' + hourSymbol | |
1f6824c9 C |
159 | |
160 | seconds %= 3600 | |
c4710631 | 161 | const minutes = Math.floor(seconds / 60) |
f0a39880 C |
162 | if (minutes >= 1 && minutes < 10 && full) time += '0' + minutes + minuteSymbol |
163 | else if (minutes >= 1) time += minutes + minuteSymbol | |
164 | else if (full) time += '00' + minuteSymbol | |
1f6824c9 C |
165 | |
166 | seconds %= 60 | |
f0a39880 C |
167 | if (seconds >= 1 && seconds < 10 && full) time += '0' + seconds + secondsSymbol |
168 | else if (seconds >= 1) time += seconds + secondsSymbol | |
169 | else if (full) time += '00' | |
1f6824c9 C |
170 | |
171 | return time | |
960a11e8 C |
172 | } |
173 | ||
4097c6d6 TP |
174 | function buildVideoOrPlaylistEmbed (embedUrl: string, embedTitle: string) { |
175 | const title = escapeHTML(embedTitle) | |
960a11e8 | 176 | return '<iframe width="560" height="315" ' + |
f2aa2c3c | 177 | 'sandbox="allow-same-origin allow-scripts allow-popups" ' + |
4097c6d6 | 178 | 'title="' + title + '" ' + |
960a11e8 C |
179 | 'src="' + embedUrl + '" ' + |
180 | 'frameborder="0" allowfullscreen>' + | |
181 | '</iframe>' | |
182 | } | |
183 | ||
6cca7360 C |
184 | function videoFileMaxByResolution (files: VideoFile[]) { |
185 | let max = files[0] | |
186 | ||
187 | for (let i = 1; i < files.length; i++) { | |
188 | const file = files[i] | |
189 | if (max.resolution.id < file.resolution.id) max = file | |
190 | } | |
191 | ||
192 | return max | |
193 | } | |
194 | ||
195 | function videoFileMinByResolution (files: VideoFile[]) { | |
196 | let min = files[0] | |
197 | ||
198 | for (let i = 1; i < files.length; i++) { | |
199 | const file = files[i] | |
200 | if (min.resolution.id > file.resolution.id) min = file | |
201 | } | |
202 | ||
203 | return min | |
204 | } | |
205 | ||
09209296 C |
206 | function getRtcConfig () { |
207 | return { | |
208 | iceServers: [ | |
209 | { | |
210 | urls: 'stun:stun.stunprotocol.org' | |
211 | }, | |
212 | { | |
213 | urls: 'stun:stun.framasoft.org' | |
214 | } | |
215 | ] | |
216 | } | |
217 | } | |
218 | ||
7b3a99d5 C |
219 | // --------------------------------------------------------------------------- |
220 | ||
c6352f2c | 221 | export { |
09209296 | 222 | getRtcConfig, |
c6352f2c | 223 | toTitleCase, |
1f6824c9 | 224 | timeToInt, |
f0a39880 | 225 | secondsToTime, |
31b6ddf8 | 226 | isWebRTCDisabled, |
951b582f | 227 | buildPlaylistLink, |
960a11e8 | 228 | buildVideoLink, |
951b582f | 229 | buildVideoOrPlaylistEmbed, |
6cca7360 C |
230 | videoFileMaxByResolution, |
231 | videoFileMinByResolution, | |
d1bd87e0 | 232 | isMobile, |
3e2bc4ea C |
233 | bytes, |
234 | isIOS, | |
235 | isSafari | |
c6352f2c | 236 | } |