X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Ftests%2Fapi%2Fvideos%2Fvideo-transcoder.ts;h=7ed55b8e8d3d18b0fb2c3e2fe98c0169f723d9f9;hb=a37e9e74ff07b057370d1ed6c0b391a02be8a6d2;hp=e4892bb24d03b34f38a64934134ee089a275f05e;hpb=4c7e60bc17ee5830399bac4aa273356903421b4c;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts index e4892bb24..7ed55b8e8 100644 --- a/server/tests/api/videos/video-transcoder.ts +++ b/server/tests/api/videos/video-transcoder.ts @@ -3,7 +3,7 @@ import 'mocha' import * as chai from 'chai' import { omit } from 'lodash' -import { join } from 'path' +import { getMaxBitrate, getMinLimitBitrate } from '@shared/core-utils' import { buildAbsoluteFixturePath, cleanupTests, @@ -17,8 +17,7 @@ import { waitJobs, webtorrentAdd } from '@shared/extra-utils' -import { getMaxBitrate, HttpStatusCode, VideoResolution, VideoState } from '@shared/models' -import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' +import { HttpStatusCode, VideoState } from '@shared/models' import { canDoQuickTranscode, getAudioStream, @@ -41,6 +40,7 @@ function updateConfigForTranscoding (server: PeerTubeServer) { webtorrent: { enabled: true }, resolutions: { '0p': false, + '144p': true, '240p': true, '360p': true, '480p': true, @@ -120,7 +120,7 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) + expect(videoDetails.files).to.have.lengthOf(5) const magnetUri = videoDetails.files[0].magnetUri expect(magnetUri).to.match(/\.mp4/) @@ -191,15 +191,6 @@ describe('Test video transcoding', function () { it('Should accept and transcode additional extensions', async function () { this.timeout(300_000) - let tempFixturePath: string - - { - tempFixturePath = await generateHighBitrateVideo() - - const bitrate = await getVideoFileBitrate(tempFixturePath) - expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 25, VIDEO_TRANSCODING_FPS)) - } - for (const fixture of [ 'video_short.mkv', 'video_short.avi' ]) { const attributes = { name: fixture, @@ -215,7 +206,7 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) + expect(videoDetails.files).to.have.lengthOf(5) const magnetUri = videoDetails.files[0].magnetUri expect(magnetUri).to.contain('.mp4') @@ -236,7 +227,7 @@ describe('Test video transcoding', function () { await waitJobs(servers) - const resolutions = [ 240, 360, 480, 720, 1080, 1440, 2160 ] + const resolutions = [ 144, 240, 360, 480, 720, 1080, 1440, 2160 ] for (const server of servers) { const videoDetails = await server.videos.get({ id: video4k }) @@ -269,9 +260,10 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) + expect(videoDetails.files).to.have.lengthOf(5) - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4')) + const file = videoDetails.files.find(f => f.resolution.id === 240) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const probe = await getAudioStream(path) if (probe.audioStream) { @@ -300,8 +292,9 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4')) + const file = videoDetails.files.find(f => f.resolution.id === 240) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) + const probe = await getAudioStream(path) expect(probe).to.not.have.property('audioStream') } @@ -324,11 +317,13 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) + expect(videoDetails.files).to.have.lengthOf(5) const fixturePath = buildAbsoluteFixturePath(attributes.fixture) const fixtureVideoProbe = await getAudioStream(fixturePath) - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4')) + + const file = videoDetails.files.find(f => f.resolution.id === 240) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const videoProbe = await getAudioStream(path) @@ -354,6 +349,7 @@ describe('Test video transcoding', function () { webtorrent: { enabled: true }, resolutions: { '0p': false, + '144p': false, '240p': false, '360p': false, '480p': false, @@ -425,6 +421,7 @@ describe('Test video transcoding', function () { webtorrent: { enabled: true }, resolutions: { '0p': true, + '144p': false, '240p': false, '360p': false } @@ -479,20 +476,23 @@ describe('Test video transcoding', function () { const video = data.find(v => v.name === attributes.name) const videoDetails = await server.videos.get({ id: video.id }) - expect(videoDetails.files).to.have.lengthOf(4) + expect(videoDetails.files).to.have.lengthOf(5) expect(videoDetails.files[0].fps).to.be.above(58).and.below(62) expect(videoDetails.files[1].fps).to.be.below(31) expect(videoDetails.files[2].fps).to.be.below(31) expect(videoDetails.files[3].fps).to.be.below(31) + expect(videoDetails.files[4].fps).to.be.below(31) - for (const resolution of [ '240', '360', '480' ]) { - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-' + resolution + '.mp4')) + for (const resolution of [ 144, 240, 360, 480 ]) { + const file = videoDetails.files.find(f => f.resolution.id === resolution) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const fps = await getVideoFileFPS(path) expect(fps).to.be.below(31) } - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-720.mp4')) + const file = videoDetails.files.find(f => f.resolution.id === 720) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const fps = await getVideoFileFPS(path) expect(fps).to.be.above(58).and.below(62) @@ -524,16 +524,19 @@ describe('Test video transcoding', function () { for (const server of servers) { const { data } = await server.videos.list() - const video = data.find(v => v.name === attributes.name) + const { id } = data.find(v => v.name === attributes.name) + const video = await server.videos.get({ id }) { - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4')) + const file = video.files.find(f => f.resolution.id === 240) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const fps = await getVideoFileFPS(path) expect(fps).to.be.equal(25) } { - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-720.mp4')) + const file = video.files.find(f => f.resolution.id === 720) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const fps = await getVideoFileFPS(path) expect(fps).to.be.equal(59) } @@ -542,17 +545,11 @@ describe('Test video transcoding', function () { }) describe('Bitrate control', function () { + it('Should respect maximum bitrate values', async function () { this.timeout(160_000) - let tempFixturePath: string - - { - tempFixturePath = await generateHighBitrateVideo() - - const bitrate = await getVideoFileBitrate(tempFixturePath) - expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 25, VIDEO_TRANSCODING_FPS)) - } + const tempFixturePath = await generateHighBitrateVideo() const attributes = { name: 'high bitrate video', @@ -567,28 +564,33 @@ describe('Test video transcoding', function () { for (const server of servers) { const { data } = await server.videos.list() - const video = data.find(v => v.name === attributes.name) + const { id } = data.find(v => v.name === attributes.name) + const video = await server.videos.get({ id }) - for (const resolution of [ '240', '360', '480', '720', '1080' ]) { - const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-' + resolution + '.mp4')) + for (const resolution of [ 240, 360, 480, 720, 1080 ]) { + const file = video.files.find(f => f.resolution.id === resolution) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const bitrate = await getVideoFileBitrate(path) const fps = await getVideoFileFPS(path) - const resolution2 = await getVideoFileResolution(path) + const dataResolution = await getVideoFileResolution(path) + + expect(resolution).to.equal(resolution) - expect(resolution2.videoFileResolution.toString()).to.equal(resolution) - expect(bitrate).to.be.below(getMaxBitrate(resolution2.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)) + const maxBitrate = getMaxBitrate({ ...dataResolution, fps }) + expect(bitrate).to.be.below(maxBitrate) } } }) - it('Should not transcode to an higher bitrate than the original file', async function () { + it('Should not transcode to an higher bitrate than the original file but above our low limit', async function () { this.timeout(160_000) const newConfig = { transcoding: { enabled: true, resolutions: { + '144p': true, '240p': true, '360p': true, '480p': true, @@ -608,15 +610,25 @@ describe('Test video transcoding', function () { fixture: 'low-bitrate.mp4' } - const { uuid } = await servers[1].videos.upload({ attributes }) + const { id } = await servers[1].videos.upload({ attributes }) await waitJobs(servers) + const video = await servers[1].videos.get({ id }) + const resolutions = [ 240, 360, 480, 720, 1080 ] for (const r of resolutions) { - const path = `videos/${uuid}-${r}.mp4` - const size = await servers[1].servers.getServerFileSize(path) - expect(size, `${path} not below ${60_000}`).to.be.below(60_000) + const file = video.files.find(f => f.resolution.id === r) + + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) + const bitrate = await getVideoFileBitrate(path) + + const inputBitrate = 60_000 + const limit = getMinLimitBitrate({ fps: 10, ratio: 1, resolution: r }) + let belowValue = Math.max(inputBitrate, limit) + belowValue += belowValue * 0.20 // Apply 20% margin because bitrate control is not very precise + + expect(bitrate, `${path} not below ${limit}`).to.be.below(belowValue) } }) }) @@ -630,7 +642,9 @@ describe('Test video transcoding', function () { await waitJobs(servers) { - const path = servers[1].servers.buildDirectory(join('videos', videoUUID + '-240.mp4')) + const video = await servers[1].videos.get({ id: videoUUID }) + const file = video.files.find(f => f.resolution.id === 240) + const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl) const metadata = await getMetadataFromFile(path) // expected format properties @@ -664,7 +678,7 @@ describe('Test video transcoding', function () { const videoFiles = videoDetails.files .concat(videoDetails.streamingPlaylists[0].files) - expect(videoFiles).to.have.lengthOf(8) + expect(videoFiles).to.have.lengthOf(10) for (const file of videoFiles) { expect(file.metadata).to.be.undefined @@ -689,24 +703,24 @@ describe('Test video transcoding', function () { describe('Transcoding job queue', function () { it('Should have the appropriate priorities for transcoding jobs', async function () { - const body = await servers[1].jobs.getJobsList({ + const body = await servers[1].jobs.list({ start: 0, count: 100, - sort: '-createdAt', + sort: 'createdAt', jobType: 'video-transcoding' }) const jobs = body.data const transcodingJobs = jobs.filter(j => j.data.videoUUID === video4k) - expect(transcodingJobs).to.have.lengthOf(14) + expect(transcodingJobs).to.have.lengthOf(16) const hlsJobs = transcodingJobs.filter(j => j.data.type === 'new-resolution-to-hls') const webtorrentJobs = transcodingJobs.filter(j => j.data.type === 'new-resolution-to-webtorrent') const optimizeJobs = transcodingJobs.filter(j => j.data.type === 'optimize-to-webtorrent') - expect(hlsJobs).to.have.lengthOf(7) - expect(webtorrentJobs).to.have.lengthOf(6) + expect(hlsJobs).to.have.lengthOf(8) + expect(webtorrentJobs).to.have.lengthOf(7) expect(optimizeJobs).to.have.lengthOf(1) for (const j of optimizeJobs.concat(hlsJobs.concat(webtorrentJobs))) {