create-transcoding-job.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { program } from 'commander'
  2. import { isUUIDValid, toCompleteUUID } from '@server/helpers/custom-validators/misc'
  3. import { computeResolutionsToTranscode } from '@server/helpers/ffmpeg'
  4. import { CONFIG } from '@server/initializers/config'
  5. import { buildTranscodingJob } from '@server/lib/video'
  6. import { VideoState, VideoTranscodingPayload } from '@shared/models'
  7. import { initDatabaseModels } from '../server/initializers/database'
  8. import { JobQueue } from '../server/lib/job-queue'
  9. import { VideoModel } from '../server/models/video/video'
  10. program
  11. .option('-v, --video [videoUUID]', 'Video UUID')
  12. .option('-r, --resolution [resolution]', 'Video resolution (integer)')
  13. .option('--generate-hls', 'Generate HLS playlist')
  14. .parse(process.argv)
  15. const options = program.opts()
  16. if (options.video === undefined) {
  17. console.error('All parameters are mandatory.')
  18. process.exit(-1)
  19. }
  20. if (options.resolution !== undefined && Number.isNaN(+options.resolution)) {
  21. console.error('The resolution must be an integer (example: 1080).')
  22. process.exit(-1)
  23. }
  24. run()
  25. .then(() => process.exit(0))
  26. .catch(err => {
  27. console.error(err)
  28. process.exit(-1)
  29. })
  30. async function run () {
  31. await initDatabaseModels(true)
  32. const uuid = toCompleteUUID(options.video)
  33. if (isUUIDValid(uuid) === false) {
  34. console.error('%s is not a valid video UUID.', options.video)
  35. return
  36. }
  37. const video = await VideoModel.loadFull(uuid)
  38. if (!video) throw new Error('Video not found.')
  39. const dataInput: VideoTranscodingPayload[] = []
  40. const maxResolution = video.getMaxQualityFile().resolution
  41. // FIXME: check the file has audio
  42. const hasAudio = true
  43. // Generate HLS files
  44. if (options.generateHls || CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false) {
  45. const resolutionsEnabled = options.resolution
  46. ? [ parseInt(options.resolution) ]
  47. : computeResolutionsToTranscode({ input: maxResolution, type: 'vod', includeInput: true, strictLower: false, hasAudio })
  48. for (const resolution of resolutionsEnabled) {
  49. dataInput.push({
  50. type: 'new-resolution-to-hls' as 'new-resolution-to-hls',
  51. videoUUID: video.uuid,
  52. resolution,
  53. hasAudio,
  54. copyCodecs: false,
  55. isNewVideo: false,
  56. isMaxQuality: maxResolution === resolution,
  57. autoDeleteWebTorrentIfNeeded: false
  58. })
  59. }
  60. } else {
  61. if (options.resolution !== undefined) {
  62. dataInput.push({
  63. type: 'new-resolution-to-webtorrent' as 'new-resolution-to-webtorrent',
  64. videoUUID: video.uuid,
  65. createHLSIfNeeded: true,
  66. hasAudio,
  67. isNewVideo: false,
  68. resolution: parseInt(options.resolution)
  69. })
  70. } else {
  71. if (video.VideoFiles.length === 0) {
  72. console.error('Cannot regenerate webtorrent files with a HLS only video.')
  73. return
  74. }
  75. dataInput.push({
  76. type: 'optimize-to-webtorrent' as 'optimize-to-webtorrent',
  77. videoUUID: video.uuid,
  78. isNewVideo: false
  79. })
  80. }
  81. }
  82. JobQueue.Instance.init()
  83. video.state = VideoState.TO_TRANSCODE
  84. await video.save()
  85. for (const d of dataInput) {
  86. await JobQueue.Instance.createJob(await buildTranscodingJob(d))
  87. console.log('Transcoding job for video %s created.', video.uuid)
  88. }
  89. }