Fix transcoding
authorChocobozzz <me@florianbigard.com>
Wed, 29 Jan 2020 15:54:03 +0000 (16:54 +0100)
committerChocobozzz <me@florianbigard.com>
Wed, 29 Jan 2020 15:54:52 +0000 (16:54 +0100)
.gitignore
server/helpers/ffmpeg-utils.ts
server/tests/api/videos/video-transcoder.ts
shared/extra-utils/miscs/miscs.ts

index 6ef90385c61a654608a219fb58c8adcd4687c5d0..07b2fb7effeb756d1a444391efc16bebdb797356 100644 (file)
@@ -12,6 +12,7 @@ yarn-error.log
 /test5/
 /test6/
 /server/tests/fixtures/video_high_bitrate_1080p.mp4
+/server/tests/fixtures/video_59fps.mp4
 
 # Production
 /storage/
index 63dc5b6a3af39ac92ed9e8893fea1ccc31a1492c..7022d3e037d23e274ab6b025cc1aab3df7d158f8 100644 (file)
@@ -263,8 +263,9 @@ async function canDoQuickTranscode (path: string): Promise<boolean> {
   return true
 }
 
-function getClosestFramerateStandard (fps: number, hd = false): number {
-  return VIDEO_TRANSCODING_FPS[hd ? 'HD_STANDARD' : 'STANDARD'].slice(0).sort((a, b) => fps % a - fps % b)[0]
+function getClosestFramerateStandard (fps: number, type: 'HD_STANDARD' | 'STANDARD'): number {
+  return VIDEO_TRANSCODING_FPS[type].slice(0)
+                                    .sort((a, b) => fps % a - fps % b)[0]
 }
 
 // ---------------------------------------------------------------------------
@@ -294,12 +295,10 @@ async function buildx264Command (command: ffmpeg.FfmpegCommand, options: Transco
     // On small/medium resolutions, limit FPS
     options.resolution !== undefined &&
     options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN &&
-    fps > VIDEO_TRANSCODING_FPS.AVERAGE ||
-    // If the video is doesn't match hd standard
-    !VIDEO_TRANSCODING_FPS.HD_STANDARD.some(value => fps % value === 0)
+    fps > VIDEO_TRANSCODING_FPS.AVERAGE
   ) {
     // Get closest standard framerate by modulo: downsampling has to be done to a divisor of the nominal fps value
-    fps = getClosestFramerateStandard(fps)
+    fps = getClosestFramerateStandard(fps, 'STANDARD')
   }
 
   command = await presetH264(command, options.inputPath, options.resolution, fps)
@@ -312,7 +311,7 @@ async function buildx264Command (command: ffmpeg.FfmpegCommand, options: Transco
 
   if (fps) {
     // Hard FPS limits
-    if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = getClosestFramerateStandard(fps, true)
+    if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = getClosestFramerateStandard(fps, 'HD_STANDARD')
     else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN
 
     command = command.withFPS(fps)
index 0104c94fcb9b228f4cf90bcc1f84d792ec92204d..55eb76b3ba601168378aba9791cc757e5eb207f2 100644 (file)
@@ -423,7 +423,7 @@ describe('Test video transcoding', function () {
     let tempFixturePath: string
 
     {
-      tempFixturePath = await generateVideoWithFramerate()
+      tempFixturePath = await generateVideoWithFramerate(59)
 
       const fps = await getVideoFileFPS(tempFixturePath)
       expect(fps).to.be.equal(59)
@@ -443,10 +443,18 @@ describe('Test video transcoding', function () {
       const res = await getVideosList(server.url)
 
       const video = res.body.data.find(v => v.name === videoAttributes.name)
-      const path = join(root(), 'test' + servers[1].internalServerNumber, 'videos', video.uuid + '-240.mp4')
-      const fps = await getVideoFileFPS(path)
 
-      expect(fps).to.be.equal(25)
+      {
+        const path = join(root(), 'test' + servers[ 1 ].internalServerNumber, 'videos', video.uuid + '-240.mp4')
+        const fps = await getVideoFileFPS(path)
+        expect(fps).to.be.equal(25)
+      }
+
+      {
+        const path = join(root(), 'test' + servers[ 1 ].internalServerNumber, 'videos', video.uuid + '-720.mp4')
+        const fps = await getVideoFileFPS(path)
+        expect(fps).to.be.equal(59)
+      }
     }
   })
 
index c957a6abea2d78d83f1b20a7ff4ebc09a22aa50d..d04003988b74577412b4d20c18b2438776cc6b76 100644 (file)
@@ -113,7 +113,7 @@ async function generateVideoWithFramerate (fps = 60) {
   if (!exists) {
     return new Promise<string>(async (res, rej) => {
       ffmpeg()
-        .outputOptions([ '-f rawvideo', '-video_size 320x240', '-i /dev/urandom' ])
+        .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ])
         .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
         .outputOptions([ `-r ${fps}` ])
         .output(tempFixturePath)