Add ability to manually run transcoding job
authorChocobozzz <me@florianbigard.com>
Wed, 30 May 2018 08:49:40 +0000 (10:49 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 30 May 2018 08:49:56 +0000 (10:49 +0200)
package.json
scripts/create-transcoding-job.ts [new file with mode: 0755]
server/controllers/api/videos/index.ts
server/lib/job-queue/handlers/video-file.ts
server/tests/cli/create-transcoding-job.ts [new file with mode: 0644]
server/tests/cli/index.ts

index c4ee202e19d729c0c7c892bb221c84e617524429..4e890d771a325ee68d344c1ae6ee173afb41816b 100644 (file)
@@ -36,6 +36,7 @@
     "dev:client": "scripty",
     "start": "node dist/server",
     "update-host": "node ./dist/scripts/update-host.js",
+    "create-transcoding-job": "node ./dist/scripts/create-transcoding-job.js",
     "test": "scripty",
     "help": "scripty",
     "generate-api-doc": "scripty",
diff --git a/scripts/create-transcoding-job.ts b/scripts/create-transcoding-job.ts
new file mode 100755 (executable)
index 0000000..463cdfa
--- /dev/null
@@ -0,0 +1,39 @@
+import * as program from 'commander'
+import { createReadStream } from 'fs'
+import { join } from 'path'
+import { createInterface } from 'readline'
+import { VideoModel } from '../server/models/video/video'
+import { initDatabaseModels } from '../server/initializers'
+import { JobQueue } from '../server/lib/job-queue'
+
+program
+  .option('-v, --video [videoUUID]', 'Video UUID')
+  .parse(process.argv)
+
+if (program['video'] === undefined) {
+  console.error('All parameters are mandatory.')
+  process.exit(-1)
+}
+
+run()
+  .then(() => process.exit(0))
+  .catch(err => {
+    console.error(err)
+    process.exit(-1)
+  })
+
+async function run () {
+  await initDatabaseModels(true)
+
+  const video = await VideoModel.loadByUUID(program['video'])
+  if (!video) throw new Error('Video not found.')
+
+  const dataInput = {
+    videoUUID: video.uuid,
+    isNewVideo: false
+  }
+
+  await JobQueue.Instance.init()
+  await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
+  console.log('Transcoding job for video %s created.', video.uuid)
+}
index 05fd79e672156ff6cff4db21280bccf975bcd62c..7f5e74626e401714667d6be9c53d702e04116250 100644 (file)
@@ -267,7 +267,8 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
   if (CONFIG.TRANSCODING.ENABLED === true) {
     // Put uuid because we don't have id auto incremented for now
     const dataInput = {
-      videoUUID: videoCreated.uuid
+      videoUUID: videoCreated.uuid,
+      isNewVideo: true
     }
 
     await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
index 1b41d29e862baa413ce17c6f8cc8415d129ce7ba..93f9e9fe7784260afd459d5d567cf0de74b928cb 100644 (file)
@@ -11,7 +11,8 @@ import { JobQueue } from '../job-queue'
 
 export type VideoFilePayload = {
   videoUUID: string
-  resolution?: VideoResolution,
+  isNewVideo: boolean
+  resolution?: VideoResolution
   isPortraitMode?: boolean
 }
 
@@ -32,7 +33,7 @@ async function processVideoFile (job: kue.Job) {
     await onVideoFileTranscoderSuccess(video)
   } else {
     await video.optimizeOriginalVideofile()
-    await onVideoFileOptimizerSuccess(video)
+    await onVideoFileOptimizerSuccess(video, payload.isNewVideo)
   }
 
   return video
@@ -53,7 +54,7 @@ async function onVideoFileTranscoderSuccess (video: VideoModel) {
   return undefined
 }
 
-async function onVideoFileOptimizerSuccess (video: VideoModel) {
+async function onVideoFileOptimizerSuccess (video: VideoModel, isNewVideo: boolean) {
   if (video === undefined) return undefined
 
   // Maybe the video changed in database, refresh it
@@ -62,11 +63,15 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
   if (!videoDatabase) return undefined
 
   if (video.privacy !== VideoPrivacy.PRIVATE) {
-    // Now we'll add the video's meta data to our followers
-    await sequelizeTypescript.transaction(async t => {
-      await sendCreateVideo(video, t)
-      await shareVideoByServerAndChannel(video, t)
-    })
+    if (isNewVideo === true) {
+      // Now we'll add the video's meta data to our followers
+      await sequelizeTypescript.transaction(async t => {
+        await sendCreateVideo(video, t)
+        await shareVideoByServerAndChannel(video, t)
+      })
+    } else {
+      await sendUpdateVideo(video, undefined)
+    }
   }
 
   const { videoFileResolution } = await videoDatabase.getOriginalFileResolution()
@@ -84,7 +89,8 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
     for (const resolution of resolutionsEnabled) {
       const dataInput = {
         videoUUID: videoDatabase.uuid,
-        resolution
+        resolution,
+        isNewVideo
       }
 
       const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
diff --git a/server/tests/cli/create-transcoding-job.ts b/server/tests/cli/create-transcoding-job.ts
new file mode 100644 (file)
index 0000000..c2214d2
--- /dev/null
@@ -0,0 +1,96 @@
+/* tslint:disable:no-unused-expression */
+
+import 'mocha'
+import * as chai from 'chai'
+import { VideoDetails } from '../../../shared/models/videos'
+const expect = chai.expect
+
+import {
+  execCLI,
+  flushTests,
+  getEnvCli,
+  getVideosList,
+  killallServers,
+  parseTorrentVideo,
+  runServer,
+  ServerInfo,
+  setAccessTokensToServers,
+  uploadVideo,
+  wait,
+  getVideo, flushAndRunMultipleServers, doubleFollow
+} from '../utils'
+
+describe('Test create transcoding jobs', function () {
+  let servers: ServerInfo[] = []
+  let video2UUID: string
+
+  before(async function () {
+    this.timeout(60000)
+
+    await flushTests()
+
+    // Run server 2 to have transcoding enabled
+    servers = await flushAndRunMultipleServers(2)
+    await setAccessTokensToServers(servers)
+
+    await doubleFollow(servers[0], servers[1])
+
+    // Upload two videos for our needs
+    await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video1' })
+    const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video2' })
+    video2UUID = res.body.video.uuid
+
+    await wait(3000)
+  })
+
+  it('Should have two video files on each server', async function () {
+    this.timeout(30000)
+
+    for (const server of servers) {
+      const res = await getVideosList(server.url)
+      const videos = res.body.data
+      expect(videos).to.have.lengthOf(2)
+
+      for (const video of videos) {
+        const res2 = await getVideo(server.url, video.uuid)
+        const videoDetail: VideoDetails = res2.body
+        expect(videoDetail.files).to.have.lengthOf(1)
+      }
+    }
+  })
+
+  it('Should run a transcoding job on video 2', async function () {
+    this.timeout(60000)
+
+    const env = getEnvCli(servers[0])
+    await execCLI(`${env} npm run create-transcoding-job -- -v ${video2UUID}`)
+
+    await wait(30000)
+
+    for (const server of servers) {
+      const res = await getVideosList(server.url)
+      const videos = res.body.data
+      expect(videos).to.have.lengthOf(2)
+
+      for (const video of videos) {
+        const res2 = await getVideo(server.url, video.uuid)
+        const videoDetail: VideoDetails = res2.body
+
+        if (video.uuid === video2UUID) {
+          expect(videoDetail.files).to.have.lengthOf(4)
+        } else {
+          expect(videoDetail.files).to.have.lengthOf(1)
+        }
+      }
+    }
+  })
+
+  after(async function () {
+    killallServers(servers)
+
+    // Keep the logs if the test failed
+    if (this['ok']) {
+      await flushTests()
+    }
+  })
+})
index ecef9bd24f653997c8affd7d3162a256ee632292..f0317aac07c54c094112a6e90444c490b3701105 100644 (file)
@@ -1,3 +1,4 @@
 // Order of the tests we want to execute
+import './create-transcoding-job'
 import './reset-password'
 import './update-host'