video.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { Response } from 'express'
  2. import { CONFIG } from '@server/initializers/config'
  3. import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants'
  4. import { JobQueue } from '@server/lib/job-queue'
  5. import {
  6. isStreamingPlaylist,
  7. MStreamingPlaylistVideo,
  8. MVideo,
  9. MVideoAccountLightBlacklistAllFiles,
  10. MVideoFile,
  11. MVideoFullLight,
  12. MVideoIdThumbnail,
  13. MVideoImmutable,
  14. MVideoThumbnail,
  15. MVideoWithRights
  16. } from '@server/types/models'
  17. import { VideoPrivacy, VideoState, VideoTranscodingPayload } from '@shared/models'
  18. import { VideoModel } from '../models/video/video'
  19. type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes'
  20. function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Promise<MVideoFullLight>
  21. function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
  22. function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Promise<MVideoThumbnail>
  23. function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Promise<MVideoWithRights>
  24. function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Promise<MVideoIdThumbnail>
  25. function fetchVideo (
  26. id: number | string,
  27. fetchType: VideoFetchType,
  28. userId?: number
  29. ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable>
  30. function fetchVideo (
  31. id: number | string,
  32. fetchType: VideoFetchType,
  33. userId?: number
  34. ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> {
  35. if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId)
  36. if (fetchType === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id)
  37. if (fetchType === 'only-video-with-rights') return VideoModel.loadWithRights(id)
  38. if (fetchType === 'only-video') return VideoModel.load(id)
  39. if (fetchType === 'id' || fetchType === 'none') return VideoModel.loadOnlyId(id)
  40. }
  41. type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes'
  42. function fetchVideoByUrl (url: string, fetchType: 'all'): Promise<MVideoAccountLightBlacklistAllFiles>
  43. function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
  44. function fetchVideoByUrl (url: string, fetchType: 'only-video'): Promise<MVideoThumbnail>
  45. function fetchVideoByUrl (
  46. url: string,
  47. fetchType: VideoFetchByUrlType
  48. ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable>
  49. function fetchVideoByUrl (
  50. url: string,
  51. fetchType: VideoFetchByUrlType
  52. ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> {
  53. if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url)
  54. if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url)
  55. if (fetchType === 'only-video') return VideoModel.loadByUrl(url)
  56. }
  57. function getVideoWithAttributes (res: Response) {
  58. return res.locals.videoAll || res.locals.onlyVideo || res.locals.onlyVideoWithRights
  59. }
  60. function addOptimizeOrMergeAudioJob (video: MVideo, videoFile: MVideoFile) {
  61. let dataInput: VideoTranscodingPayload
  62. if (videoFile.isAudio()) {
  63. dataInput = {
  64. type: 'merge-audio' as 'merge-audio',
  65. resolution: DEFAULT_AUDIO_RESOLUTION,
  66. videoUUID: video.uuid,
  67. isNewVideo: true
  68. }
  69. } else {
  70. dataInput = {
  71. type: 'optimize' as 'optimize',
  72. videoUUID: video.uuid,
  73. isNewVideo: true
  74. }
  75. }
  76. return JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: dataInput })
  77. }
  78. function extractVideo (videoOrPlaylist: MVideo | MStreamingPlaylistVideo) {
  79. return isStreamingPlaylist(videoOrPlaylist)
  80. ? videoOrPlaylist.Video
  81. : videoOrPlaylist
  82. }
  83. function isPrivacyForFederation (privacy: VideoPrivacy) {
  84. const castedPrivacy = parseInt(privacy + '', 10)
  85. return castedPrivacy === VideoPrivacy.PUBLIC ||
  86. (CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true && castedPrivacy === VideoPrivacy.UNLISTED)
  87. }
  88. function isStateForFederation (state: VideoState) {
  89. const castedState = parseInt(state + '', 10)
  90. return castedState === VideoState.PUBLISHED || castedState === VideoState.WAITING_FOR_LIVE || castedState === VideoState.LIVE_ENDED
  91. }
  92. function getPrivaciesForFederation () {
  93. return (CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true)
  94. ? [ { privacy: VideoPrivacy.PUBLIC }, { privacy: VideoPrivacy.UNLISTED } ]
  95. : [ { privacy: VideoPrivacy.PUBLIC } ]
  96. }
  97. function getExtFromMimetype (mimeTypes: { [id: string]: string | string[] }, mimeType: string) {
  98. const value = mimeTypes[mimeType]
  99. if (Array.isArray(value)) return value[0]
  100. return value
  101. }
  102. export {
  103. VideoFetchType,
  104. VideoFetchByUrlType,
  105. fetchVideo,
  106. getVideoWithAttributes,
  107. fetchVideoByUrl,
  108. addOptimizeOrMergeAudioJob,
  109. extractVideo,
  110. getExtFromMimetype,
  111. isStateForFederation,
  112. isPrivacyForFederation,
  113. getPrivaciesForFederation
  114. }