common.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { remove } from 'fs-extra/esm'
  2. import { join } from 'path'
  3. import { FFmpegEdition, FFmpegLive, FFmpegVOD, getDefaultAvailableEncoders, getDefaultEncodersToTry } from '@peertube/peertube-ffmpeg'
  4. import { RunnerJob, RunnerJobPayload } from '@peertube/peertube-models'
  5. import { buildUUID } from '@peertube/peertube-node-utils'
  6. import { PeerTubeServer } from '@peertube/peertube-server-commands'
  7. import { ConfigManager, downloadFile, logger } from '../../../shared/index.js'
  8. import { getTranscodingLogger } from './transcoding-logger.js'
  9. export type JobWithToken <T extends RunnerJobPayload = RunnerJobPayload> = RunnerJob<T> & { jobToken: string }
  10. export type ProcessOptions <T extends RunnerJobPayload = RunnerJobPayload> = {
  11. server: PeerTubeServer
  12. job: JobWithToken<T>
  13. runnerToken: string
  14. }
  15. export async function downloadInputFile (options: {
  16. url: string
  17. job: JobWithToken
  18. runnerToken: string
  19. }) {
  20. const { url, job, runnerToken } = options
  21. const destination = join(ConfigManager.Instance.getTranscodingDirectory(), buildUUID())
  22. try {
  23. await downloadFile({ url, jobToken: job.jobToken, runnerToken, destination })
  24. } catch (err) {
  25. remove(destination)
  26. .catch(err => logger.error({ err }, `Cannot remove ${destination}`))
  27. throw err
  28. }
  29. return destination
  30. }
  31. export function scheduleTranscodingProgress (options: {
  32. server: PeerTubeServer
  33. runnerToken: string
  34. job: JobWithToken
  35. progressGetter: () => number
  36. }) {
  37. const { job, server, progressGetter, runnerToken } = options
  38. const updateInterval = ConfigManager.Instance.isTestInstance()
  39. ? 500
  40. : 60000
  41. const update = () => {
  42. server.runnerJobs.update({ jobToken: job.jobToken, jobUUID: job.uuid, runnerToken, progress: progressGetter() })
  43. .catch(err => logger.error({ err }, 'Cannot send job progress'))
  44. }
  45. const interval = setInterval(() => {
  46. update()
  47. }, updateInterval)
  48. update()
  49. return interval
  50. }
  51. // ---------------------------------------------------------------------------
  52. export function buildFFmpegVOD (options: {
  53. onJobProgress: (progress: number) => void
  54. }) {
  55. const { onJobProgress } = options
  56. return new FFmpegVOD({
  57. ...getCommonFFmpegOptions(),
  58. updateJobProgress: arg => {
  59. const progress = arg < 0 || arg > 100
  60. ? undefined
  61. : arg
  62. onJobProgress(progress)
  63. }
  64. })
  65. }
  66. export function buildFFmpegLive () {
  67. return new FFmpegLive(getCommonFFmpegOptions())
  68. }
  69. export function buildFFmpegEdition () {
  70. return new FFmpegEdition(getCommonFFmpegOptions())
  71. }
  72. function getCommonFFmpegOptions () {
  73. const config = ConfigManager.Instance.getConfig()
  74. return {
  75. niceness: config.ffmpeg.nice,
  76. threads: config.ffmpeg.threads,
  77. tmpDirectory: ConfigManager.Instance.getTranscodingDirectory(),
  78. profile: 'default',
  79. availableEncoders: {
  80. available: getDefaultAvailableEncoders(),
  81. encodersToTry: getDefaultEncodersToTry()
  82. },
  83. logger: getTranscodingLogger()
  84. }
  85. }