]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-format-utils.ts
client(hotkeys): remove seekstep VLC behavior
[github/Chocobozzz/PeerTube.git] / server / models / video / video-format-utils.ts
index 21f0e0a68b7767f8544a4c0351d5959c149dcd4b..77b8bcfe349d37d0862893f36e377ec3ef12525d 100644 (file)
@@ -1,14 +1,14 @@
 import { Video, VideoDetails } from '../../../shared/models/videos'
 import { VideoModel } from './video'
-import { ActivityTagObject, ActivityUrlObject, VideoTorrentObject } from '../../../shared/models/activitypub/objects'
+import { ActivityTagObject, ActivityUrlObject, VideoObject } from '../../../shared/models/activitypub/objects'
 import { MIMETYPES, WEBSERVER } from '../../initializers/constants'
 import { VideoCaptionModel } from './video-caption'
 import {
-  getVideoCommentsActivityPubUrl,
-  getVideoDislikesActivityPubUrl,
-  getVideoLikesActivityPubUrl,
-  getVideoSharesActivityPubUrl
-} from '../../lib/activitypub'
+  getLocalVideoCommentsActivityPubUrl,
+  getLocalVideoDislikesActivityPubUrl,
+  getLocalVideoLikesActivityPubUrl,
+  getLocalVideoSharesActivityPubUrl
+} from '../../lib/activitypub/url'
 import { isArray } from '../../helpers/custom-validators/misc'
 import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model'
 import {
@@ -19,11 +19,11 @@ import {
   MVideoFile,
   MVideoFormattable,
   MVideoFormattableDetails
-} from '../../typings/models'
-import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
+} from '../../types/models'
+import { MVideoFileRedundanciesOpt } from '../../types/models/video/video-file'
 import { VideoFile } from '@shared/models/videos/video-file.model'
 import { generateMagnetUri } from '@server/helpers/webtorrent'
-import { extractVideo } from '@server/lib/videos'
+import { extractVideo } from '@server/helpers/video'
 
 export type VideoFormattingJSONOptions = {
   completeDescription?: boolean
@@ -59,7 +59,11 @@ function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFor
       label: VideoModel.getPrivacyLabel(video.privacy)
     },
     nsfw: video.nsfw,
-    description: options && options.completeDescription === true ? video.description : video.getTruncatedDescription(),
+
+    description: options && options.completeDescription === true
+      ? video.description
+      : video.getTruncatedDescription(),
+
     isLocal: video.isOwned(),
     duration: video.duration,
     views: video.views,
@@ -73,12 +77,17 @@ function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFor
     publishedAt: video.publishedAt,
     originallyPublishedAt: video.originallyPublishedAt,
 
+    isLive: video.isLive,
+
     account: video.VideoChannel.Account.toFormattedSummaryJSON(),
     channel: video.VideoChannel.toFormattedSummaryJSON(),
 
-    userHistory: userHistory ? {
-      currentTime: userHistory.currentTime
-    } : undefined
+    userHistory: userHistory
+      ? { currentTime: userHistory.currentTime }
+      : undefined,
+
+    // Can be added by external plugins
+    pluginData: (video as any).pluginData
   }
 
   if (options) {
@@ -175,13 +184,23 @@ function streamingPlaylistsModelToFormattedJSON (video: MVideo, playlists: MStre
     })
 }
 
+function sortByResolutionDesc (fileA: MVideoFile, fileB: MVideoFile) {
+  if (fileA.resolution < fileB.resolution) return 1
+  if (fileA.resolution === fileB.resolution) return 0
+  return -1
+}
+
 function videoFilesModelToFormattedJSON (
   model: MVideo | MStreamingPlaylistVideo,
   baseUrlHttp: string,
   baseUrlWs: string,
   videoFiles: MVideoFileRedundanciesOpt[]
 ): VideoFile[] {
-  return videoFiles
+  const video = extractVideo(model)
+
+  return [ ...videoFiles ]
+    .filter(f => !f.isLive())
+    .sort(sortByResolutionDesc)
     .map(videoFile => {
       return {
         resolution: {
@@ -195,14 +214,9 @@ function videoFilesModelToFormattedJSON (
         torrentDownloadUrl: model.getTorrentDownloadUrl(videoFile, baseUrlHttp),
         fileUrl: model.getVideoFileUrl(videoFile, baseUrlHttp),
         fileDownloadUrl: model.getVideoFileDownloadUrl(videoFile, baseUrlHttp),
-        metadataUrl: videoFile.metadataUrl // only send the metadataUrl and not the metadata over the wire
+        metadataUrl: video.getVideoFileMetadataUrl(videoFile, baseUrlHttp)
       } as VideoFile
     })
-    .sort((a, b) => {
-      if (a.resolution.id < b.resolution.id) return 1
-      if (a.resolution.id === b.resolution.id) return 0
-      return -1
-    })
 }
 
 function addVideoFilesInAPAcc (
@@ -212,7 +226,11 @@ function addVideoFilesInAPAcc (
   baseUrlWs: string,
   files: MVideoFile[]
 ) {
-  for (const file of files) {
+  const sortedFiles = [ ...files ]
+    .filter(f => !f.isLive())
+    .sort(sortByResolutionDesc)
+
+  for (const file of sortedFiles) {
     acc.push({
       type: 'Link',
       mediaType: MIMETYPES.VIDEO.EXT_MIMETYPE[file.extname] as any,
@@ -247,7 +265,7 @@ function addVideoFilesInAPAcc (
   }
 }
 
-function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject {
+function videoModelToActivityPubObject (video: MVideoAP): VideoObject {
   const { baseUrlHttp, baseUrlWs } = video.getBaseUrls()
   if (!video.Tags) video.Tags = []
 
@@ -336,14 +354,28 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject {
     views: video.views,
     sensitive: video.nsfw,
     waitTranscoding: video.waitTranscoding,
+    isLiveBroadcast: video.isLive,
+
+    liveSaveReplay: video.isLive
+      ? video.VideoLive.saveReplay
+      : null,
+
+    permanentLive: video.isLive
+      ? video.VideoLive.permanentLive
+      : null,
+
     state: video.state,
     commentsEnabled: video.commentsEnabled,
     downloadEnabled: video.downloadEnabled,
     published: video.publishedAt.toISOString(),
-    originallyPublishedAt: video.originallyPublishedAt ? video.originallyPublishedAt.toISOString() : null,
+
+    originallyPublishedAt: video.originallyPublishedAt
+      ? video.originallyPublishedAt.toISOString()
+      : null,
+
     updated: video.updatedAt.toISOString(),
     mediaType: 'text/markdown',
-    content: video.getTruncatedDescription(),
+    content: video.description,
     support: video.support,
     subtitleLanguage,
     icon: icons.map(i => ({
@@ -354,10 +386,10 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject {
       height: i.height
     })),
     url,
-    likes: getVideoLikesActivityPubUrl(video),
-    dislikes: getVideoDislikesActivityPubUrl(video),
-    shares: getVideoSharesActivityPubUrl(video),
-    comments: getVideoCommentsActivityPubUrl(video),
+    likes: getLocalVideoLikesActivityPubUrl(video),
+    dislikes: getLocalVideoDislikesActivityPubUrl(video),
+    shares: getLocalVideoSharesActivityPubUrl(video),
+    comments: getLocalVideoCommentsActivityPubUrl(video),
     attributedTo: [
       {
         type: 'Person',