diff options
author | Chocobozzz <me@florianbigard.com> | 2018-10-18 16:53:52 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-10-18 16:54:26 +0200 |
commit | 74cd011b6c089cac88a4b8aa76ad3be2ca4f1c15 (patch) | |
tree | 0fa74ef54f80cf5b2825f0b2d2d123e4c1aaa1dc | |
parent | ccbbe2b8d4b18d48d132058776c22397250a4a87 (diff) | |
download | PeerTube-74cd011b6c089cac88a4b8aa76ad3be2ca4f1c15.tar.gz PeerTube-74cd011b6c089cac88a4b8aa76ad3be2ca4f1c15.tar.zst PeerTube-74cd011b6c089cac88a4b8aa76ad3be2ca4f1c15.zip |
Fix optimize old videos script
-rw-r--r-- | scripts/optimize-old-videos.ts | 8 | ||||
-rw-r--r-- | server/tests/api/videos/video-transcoder.ts | 25 | ||||
-rw-r--r-- | server/tests/cli/index.ts | 1 | ||||
-rw-r--r-- | server/tests/cli/optimize-old-videos.ts | 120 | ||||
-rw-r--r-- | server/tests/utils/miscs/miscs.ts | 31 |
5 files changed, 161 insertions, 24 deletions
diff --git a/scripts/optimize-old-videos.ts b/scripts/optimize-old-videos.ts index 02026b3da..c93f82316 100644 --- a/scripts/optimize-old-videos.ts +++ b/scripts/optimize-old-videos.ts | |||
@@ -1,8 +1,10 @@ | |||
1 | import { VIDEO_TRANSCODING_FPS } from '../server/initializers/constants' | 1 | import { CONFIG, VIDEO_TRANSCODING_FPS } from '../server/initializers/constants' |
2 | import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../server/helpers/ffmpeg-utils' | 2 | import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../server/helpers/ffmpeg-utils' |
3 | import { getMaxBitrate } from '../shared/models/videos' | 3 | import { getMaxBitrate } from '../shared/models/videos' |
4 | import { VideoModel } from '../server/models/video/video' | 4 | import { VideoModel } from '../server/models/video/video' |
5 | import { optimizeVideofile } from '../server/lib/video-transcoding' | 5 | import { optimizeVideofile } from '../server/lib/video-transcoding' |
6 | import { initDatabaseModels } from '../server/initializers' | ||
7 | import { join } from 'path' | ||
6 | 8 | ||
7 | run() | 9 | run() |
8 | .then(() => process.exit(0)) | 10 | .then(() => process.exit(0)) |
@@ -12,11 +14,13 @@ run() | |||
12 | }) | 14 | }) |
13 | 15 | ||
14 | async function run () { | 16 | async function run () { |
17 | await initDatabaseModels(true) | ||
18 | |||
15 | const localVideos = await VideoModel.listLocal() | 19 | const localVideos = await VideoModel.listLocal() |
16 | 20 | ||
17 | for (const video of localVideos) { | 21 | for (const video of localVideos) { |
18 | for (const file of video.VideoFiles) { | 22 | for (const file of video.VideoFiles) { |
19 | const inputPath = video.getVideoFilename(file) | 23 | const inputPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(file)) |
20 | 24 | ||
21 | const [ videoBitrate, fps, resolution ] = await Promise.all([ | 25 | const [ videoBitrate, fps, resolution ] = await Promise.all([ |
22 | getVideoFileBitrate(inputPath), | 26 | getVideoFileBitrate(inputPath), |
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts index 0a567873c..85795d2ed 100644 --- a/server/tests/api/videos/video-transcoder.ts +++ b/server/tests/api/videos/video-transcoder.ts | |||
@@ -18,7 +18,8 @@ import { | |||
18 | ServerInfo, | 18 | ServerInfo, |
19 | setAccessTokensToServers, | 19 | setAccessTokensToServers, |
20 | uploadVideo, | 20 | uploadVideo, |
21 | webtorrentAdd | 21 | webtorrentAdd, |
22 | generateHighBitrateVideo | ||
22 | } from '../../utils' | 23 | } from '../../utils' |
23 | import { join } from 'path' | 24 | import { join } from 'path' |
24 | import { waitJobs } from '../../utils/server/jobs' | 25 | import { waitJobs } from '../../utils/server/jobs' |
@@ -283,29 +284,13 @@ describe('Test video transcoding', function () { | |||
283 | } | 284 | } |
284 | }) | 285 | }) |
285 | 286 | ||
286 | const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true) | ||
287 | it('Should respect maximum bitrate values', async function () { | 287 | it('Should respect maximum bitrate values', async function () { |
288 | this.timeout(160000) | 288 | this.timeout(160000) |
289 | 289 | ||
290 | let tempFixturePath: string | ||
291 | |||
290 | { | 292 | { |
291 | const exists = await pathExists(tempFixturePath) | 293 | tempFixturePath = await generateHighBitrateVideo() |
292 | if (!exists) { | ||
293 | |||
294 | // Generate a random, high bitrate video on the fly, so we don't have to include | ||
295 | // a large file in the repo. The video needs to have a certain minimum length so | ||
296 | // that FFmpeg properly applies bitrate limits. | ||
297 | // https://stackoverflow.com/a/15795112 | ||
298 | await new Promise<void>(async (res, rej) => { | ||
299 | ffmpeg() | ||
300 | .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ]) | ||
301 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
302 | .outputOptions([ '-maxrate 10M', '-bufsize 10M' ]) | ||
303 | .output(tempFixturePath) | ||
304 | .on('error', rej) | ||
305 | .on('end', res) | ||
306 | .run() | ||
307 | }) | ||
308 | } | ||
309 | 294 | ||
310 | const bitrate = await getVideoFileBitrate(tempFixturePath) | 295 | const bitrate = await getVideoFileBitrate(tempFixturePath) |
311 | expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS)) | 296 | expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS)) |
diff --git a/server/tests/cli/index.ts b/server/tests/cli/index.ts index 6201314ce..8f8acf56c 100644 --- a/server/tests/cli/index.ts +++ b/server/tests/cli/index.ts | |||
@@ -4,3 +4,4 @@ import './create-transcoding-job' | |||
4 | import './peertube' | 4 | import './peertube' |
5 | import './reset-password' | 5 | import './reset-password' |
6 | import './update-host' | 6 | import './update-host' |
7 | import './update-host' | ||
diff --git a/server/tests/cli/optimize-old-videos.ts b/server/tests/cli/optimize-old-videos.ts new file mode 100644 index 000000000..66dd39cce --- /dev/null +++ b/server/tests/cli/optimize-old-videos.ts | |||
@@ -0,0 +1,120 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | ||
5 | import { getMaxBitrate, Video, VideoDetails, VideoResolution } from '../../../shared/models/videos' | ||
6 | import { | ||
7 | doubleFollow, | ||
8 | execCLI, | ||
9 | flushAndRunMultipleServers, | ||
10 | flushTests, generateHighBitrateVideo, | ||
11 | getEnvCli, | ||
12 | getVideo, | ||
13 | getVideosList, | ||
14 | killallServers, root, | ||
15 | ServerInfo, | ||
16 | setAccessTokensToServers, | ||
17 | uploadVideo, viewVideo, wait | ||
18 | } from '../utils' | ||
19 | import { waitJobs } from '../utils/server/jobs' | ||
20 | import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils' | ||
21 | import { VIDEO_TRANSCODING_FPS } from '../../initializers' | ||
22 | import { join } from 'path' | ||
23 | |||
24 | const expect = chai.expect | ||
25 | |||
26 | describe('Test optimize old videos', function () { | ||
27 | let servers: ServerInfo[] = [] | ||
28 | let video1UUID: string | ||
29 | let video2UUID: string | ||
30 | |||
31 | before(async function () { | ||
32 | this.timeout(200000) | ||
33 | |||
34 | await flushTests() | ||
35 | |||
36 | // Run server 2 to have transcoding enabled | ||
37 | servers = await flushAndRunMultipleServers(2) | ||
38 | await setAccessTokensToServers(servers) | ||
39 | |||
40 | await doubleFollow(servers[0], servers[1]) | ||
41 | |||
42 | let tempFixturePath: string | ||
43 | |||
44 | { | ||
45 | tempFixturePath = await generateHighBitrateVideo() | ||
46 | |||
47 | const bitrate = await getVideoFileBitrate(tempFixturePath) | ||
48 | expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS)) | ||
49 | } | ||
50 | |||
51 | // Upload two videos for our needs | ||
52 | const res1 = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video1', fixture: tempFixturePath }) | ||
53 | video1UUID = res1.body.video.uuid | ||
54 | const res2 = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video2', fixture: tempFixturePath }) | ||
55 | video2UUID = res2.body.video.uuid | ||
56 | |||
57 | await waitJobs(servers) | ||
58 | }) | ||
59 | |||
60 | it('Should have two video files on each server', async function () { | ||
61 | this.timeout(30000) | ||
62 | |||
63 | for (const server of servers) { | ||
64 | const res = await getVideosList(server.url) | ||
65 | const videos = res.body.data | ||
66 | expect(videos).to.have.lengthOf(2) | ||
67 | |||
68 | for (const video of videos) { | ||
69 | const res2 = await getVideo(server.url, video.uuid) | ||
70 | const videoDetail: VideoDetails = res2.body | ||
71 | expect(videoDetail.files).to.have.lengthOf(1) | ||
72 | } | ||
73 | } | ||
74 | }) | ||
75 | |||
76 | it('Should run optimize script', async function () { | ||
77 | this.timeout(120000) | ||
78 | |||
79 | const env = getEnvCli(servers[0]) | ||
80 | await execCLI(`${env} npm run optimize-old-videos`) | ||
81 | |||
82 | await waitJobs(servers) | ||
83 | |||
84 | for (const server of servers) { | ||
85 | const res = await getVideosList(server.url) | ||
86 | const videos: Video[] = res.body.data | ||
87 | |||
88 | expect(videos).to.have.lengthOf(2) | ||
89 | |||
90 | for (const video of videos) { | ||
91 | await viewVideo(server.url, video.uuid) | ||
92 | |||
93 | // Refresh video | ||
94 | await waitJobs(servers) | ||
95 | await wait(5000) | ||
96 | await waitJobs(servers) | ||
97 | |||
98 | const res2 = await getVideo(server.url, video.uuid) | ||
99 | const videosDetails: VideoDetails = res2.body | ||
100 | |||
101 | expect(videosDetails.files).to.have.lengthOf(1) | ||
102 | const file = videosDetails.files[0] | ||
103 | |||
104 | expect(file.size).to.be.below(5000000) | ||
105 | |||
106 | const path = join(root(), 'test1', 'videos', video.uuid + '-' + file.resolution.id + '.mp4') | ||
107 | const bitrate = await getVideoFileBitrate(path) | ||
108 | const fps = await getVideoFileFPS(path) | ||
109 | const resolution = await getVideoFileResolution(path) | ||
110 | |||
111 | expect(resolution.videoFileResolution).to.equal(file.resolution.id) | ||
112 | expect(bitrate).to.be.below(getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)) | ||
113 | } | ||
114 | } | ||
115 | }) | ||
116 | |||
117 | after(async function () { | ||
118 | killallServers(servers) | ||
119 | }) | ||
120 | }) | ||
diff --git a/server/tests/utils/miscs/miscs.ts b/server/tests/utils/miscs/miscs.ts index d20fa96b8..589daa420 100644 --- a/server/tests/utils/miscs/miscs.ts +++ b/server/tests/utils/miscs/miscs.ts | |||
@@ -4,7 +4,8 @@ import * as chai from 'chai' | |||
4 | import { isAbsolute, join } from 'path' | 4 | import { isAbsolute, join } from 'path' |
5 | import * as request from 'supertest' | 5 | import * as request from 'supertest' |
6 | import * as WebTorrent from 'webtorrent' | 6 | import * as WebTorrent from 'webtorrent' |
7 | import { readFile } from 'fs-extra' | 7 | import { pathExists, readFile } from 'fs-extra' |
8 | import * as ffmpeg from 'fluent-ffmpeg' | ||
8 | 9 | ||
9 | const expect = chai.expect | 10 | const expect = chai.expect |
10 | let webtorrent = new WebTorrent() | 11 | let webtorrent = new WebTorrent() |
@@ -61,6 +62,31 @@ function buildAbsoluteFixturePath (path: string, customTravisPath = false) { | |||
61 | return join(__dirname, '..', '..', 'fixtures', path) | 62 | return join(__dirname, '..', '..', 'fixtures', path) |
62 | } | 63 | } |
63 | 64 | ||
65 | async function generateHighBitrateVideo () { | ||
66 | const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true) | ||
67 | |||
68 | const exists = await pathExists(tempFixturePath) | ||
69 | if (!exists) { | ||
70 | |||
71 | // Generate a random, high bitrate video on the fly, so we don't have to include | ||
72 | // a large file in the repo. The video needs to have a certain minimum length so | ||
73 | // that FFmpeg properly applies bitrate limits. | ||
74 | // https://stackoverflow.com/a/15795112 | ||
75 | return new Promise<string>(async (res, rej) => { | ||
76 | ffmpeg() | ||
77 | .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ]) | ||
78 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
79 | .outputOptions([ '-maxrate 10M', '-bufsize 10M' ]) | ||
80 | .output(tempFixturePath) | ||
81 | .on('error', rej) | ||
82 | .on('end', () => res(tempFixturePath)) | ||
83 | .run() | ||
84 | }) | ||
85 | } | ||
86 | |||
87 | return tempFixturePath | ||
88 | } | ||
89 | |||
64 | // --------------------------------------------------------------------------- | 90 | // --------------------------------------------------------------------------- |
65 | 91 | ||
66 | export { | 92 | export { |
@@ -70,5 +96,6 @@ export { | |||
70 | immutableAssign, | 96 | immutableAssign, |
71 | testImage, | 97 | testImage, |
72 | buildAbsoluteFixturePath, | 98 | buildAbsoluteFixturePath, |
73 | root | 99 | root, |
100 | generateHighBitrateVideo | ||
74 | } | 101 | } |