aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video-format-utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video-format-utils.ts')
-rw-r--r--server/models/video/video-format-utils.ts69
1 files changed, 65 insertions, 4 deletions
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index e7bff2ed7..76d0445d4 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -1,8 +1,13 @@
1import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' 1import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos'
2import { VideoModel } from './video' 2import { VideoModel } from './video'
3import { VideoFileModel } from './video-file' 3import { VideoFileModel } from './video-file'
4import { ActivityUrlObject, VideoTorrentObject } from '../../../shared/models/activitypub/objects' 4import {
5import { CONFIG, THUMBNAILS_SIZE, VIDEO_EXT_MIMETYPE } from '../../initializers' 5 ActivityPlaylistInfohashesObject,
6 ActivityPlaylistSegmentHashesObject,
7 ActivityUrlObject,
8 VideoTorrentObject
9} from '../../../shared/models/activitypub/objects'
10import { CONFIG, MIMETYPES, THUMBNAILS_SIZE } from '../../initializers'
6import { VideoCaptionModel } from './video-caption' 11import { VideoCaptionModel } from './video-caption'
7import { 12import {
8 getVideoCommentsActivityPubUrl, 13 getVideoCommentsActivityPubUrl,
@@ -11,6 +16,8 @@ import {
11 getVideoSharesActivityPubUrl 16 getVideoSharesActivityPubUrl
12} from '../../lib/activitypub' 17} from '../../lib/activitypub'
13import { isArray } from '../../helpers/custom-validators/misc' 18import { isArray } from '../../helpers/custom-validators/misc'
19import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model'
20import { VideoStreamingPlaylistModel } from './video-streaming-playlist'
14 21
15export type VideoFormattingJSONOptions = { 22export type VideoFormattingJSONOptions = {
16 completeDescription?: boolean 23 completeDescription?: boolean
@@ -120,7 +127,12 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
120 } 127 }
121 }) 128 })
122 129
130 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls()
131
123 const tags = video.Tags ? video.Tags.map(t => t.name) : [] 132 const tags = video.Tags ? video.Tags.map(t => t.name) : []
133
134 const streamingPlaylists = streamingPlaylistsModelToFormattedJSON(video, video.VideoStreamingPlaylists)
135
124 const detailsJson = { 136 const detailsJson = {
125 support: video.support, 137 support: video.support,
126 descriptionPath: video.getDescriptionAPIPath(), 138 descriptionPath: video.getDescriptionAPIPath(),
@@ -134,7 +146,11 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
134 id: video.state, 146 id: video.state,
135 label: VideoModel.getStateLabel(video.state) 147 label: VideoModel.getStateLabel(video.state)
136 }, 148 },
137 files: [] 149
150 trackerUrls: video.getTrackerUrls(baseUrlHttp, baseUrlWs),
151
152 files: [],
153 streamingPlaylists
138 } 154 }
139 155
140 // Format and sort video files 156 // Format and sort video files
@@ -143,6 +159,25 @@ function videoModelToFormattedDetailsJSON (video: VideoModel): VideoDetails {
143 return Object.assign(formattedJson, detailsJson) 159 return Object.assign(formattedJson, detailsJson)
144} 160}
145 161
162function streamingPlaylistsModelToFormattedJSON (video: VideoModel, playlists: VideoStreamingPlaylistModel[]): VideoStreamingPlaylist[] {
163 if (isArray(playlists) === false) return []
164
165 return playlists
166 .map(playlist => {
167 const redundancies = isArray(playlist.RedundancyVideos)
168 ? playlist.RedundancyVideos.map(r => ({ baseUrl: r.fileUrl }))
169 : []
170
171 return {
172 id: playlist.id,
173 type: playlist.type,
174 playlistUrl: playlist.playlistUrl,
175 segmentsSha256Url: playlist.segmentsSha256Url,
176 redundancies
177 } as VideoStreamingPlaylist
178 })
179}
180
146function videoFilesModelToFormattedJSON (video: VideoModel, videoFiles: VideoFileModel[]): VideoFile[] { 181function videoFilesModelToFormattedJSON (video: VideoModel, videoFiles: VideoFileModel[]): VideoFile[] {
147 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls() 182 const { baseUrlHttp, baseUrlWs } = video.getBaseUrls()
148 183
@@ -208,7 +243,8 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
208 for (const file of video.VideoFiles) { 243 for (const file of video.VideoFiles) {
209 url.push({ 244 url.push({
210 type: 'Link', 245 type: 'Link',
211 mimeType: VIDEO_EXT_MIMETYPE[ file.extname ] as any, 246 mimeType: MIMETYPES.VIDEO.EXT_MIMETYPE[ file.extname ] as any,
247 mediaType: MIMETYPES.VIDEO.EXT_MIMETYPE[ file.extname ] as any,
212 href: video.getVideoFileUrl(file, baseUrlHttp), 248 href: video.getVideoFileUrl(file, baseUrlHttp),
213 height: file.resolution, 249 height: file.resolution,
214 size: file.size, 250 size: file.size,
@@ -218,6 +254,7 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
218 url.push({ 254 url.push({
219 type: 'Link', 255 type: 'Link',
220 mimeType: 'application/x-bittorrent' as 'application/x-bittorrent', 256 mimeType: 'application/x-bittorrent' as 'application/x-bittorrent',
257 mediaType: 'application/x-bittorrent' as 'application/x-bittorrent',
221 href: video.getTorrentUrl(file, baseUrlHttp), 258 href: video.getTorrentUrl(file, baseUrlHttp),
222 height: file.resolution 259 height: file.resolution
223 }) 260 })
@@ -225,15 +262,39 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
225 url.push({ 262 url.push({
226 type: 'Link', 263 type: 'Link',
227 mimeType: 'application/x-bittorrent;x-scheme-handler/magnet' as 'application/x-bittorrent;x-scheme-handler/magnet', 264 mimeType: 'application/x-bittorrent;x-scheme-handler/magnet' as 'application/x-bittorrent;x-scheme-handler/magnet',
265 mediaType: 'application/x-bittorrent;x-scheme-handler/magnet' as 'application/x-bittorrent;x-scheme-handler/magnet',
228 href: video.generateMagnetUri(file, baseUrlHttp, baseUrlWs), 266 href: video.generateMagnetUri(file, baseUrlHttp, baseUrlWs),
229 height: file.resolution 267 height: file.resolution
230 }) 268 })
231 } 269 }
232 270
271 for (const playlist of (video.VideoStreamingPlaylists || [])) {
272 let tag: (ActivityPlaylistSegmentHashesObject | ActivityPlaylistInfohashesObject)[]
273
274 tag = playlist.p2pMediaLoaderInfohashes
275 .map(i => ({ type: 'Infohash' as 'Infohash', name: i }))
276 tag.push({
277 type: 'Link',
278 name: 'sha256',
279 mimeType: 'application/json' as 'application/json',
280 mediaType: 'application/json' as 'application/json',
281 href: playlist.segmentsSha256Url
282 })
283
284 url.push({
285 type: 'Link',
286 mimeType: 'application/x-mpegURL' as 'application/x-mpegURL',
287 mediaType: 'application/x-mpegURL' as 'application/x-mpegURL',
288 href: playlist.playlistUrl,
289 tag
290 })
291 }
292
233 // Add video url too 293 // Add video url too
234 url.push({ 294 url.push({
235 type: 'Link', 295 type: 'Link',
236 mimeType: 'text/html', 296 mimeType: 'text/html',
297 mediaType: 'text/html',
237 href: CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid 298 href: CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid
238 }) 299 })
239 300