Limit import depending on transcoding resolutions
This commit is contained in:
parent
64fd6158fd
commit
5e2afe4290
12 changed files with 144 additions and 43 deletions
|
@ -53,7 +53,7 @@ async function run () {
|
||||||
if (options.generateHls || CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false) {
|
if (options.generateHls || CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false) {
|
||||||
const resolutionsEnabled = options.resolution
|
const resolutionsEnabled = options.resolution
|
||||||
? [ parseInt(options.resolution) ]
|
? [ parseInt(options.resolution) ]
|
||||||
: computeResolutionsToTranscode({ inputResolution: maxResolution, type: 'vod', includeInputResolution: true })
|
: computeResolutionsToTranscode({ input: maxResolution, type: 'vod', includeInput: true, strictLower: false })
|
||||||
|
|
||||||
for (const resolution of resolutionsEnabled) {
|
for (const resolution of resolutionsEnabled) {
|
||||||
dataInput.push({
|
dataInput.push({
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { CONFIG, reloadConfig } from '../../initializers/config'
|
||||||
import { ClientHtml } from '../../lib/client-html'
|
import { ClientHtml } from '../../lib/client-html'
|
||||||
import { asyncMiddleware, authenticate, ensureUserHasRight, openapiOperationDoc } from '../../middlewares'
|
import { asyncMiddleware, authenticate, ensureUserHasRight, openapiOperationDoc } from '../../middlewares'
|
||||||
import { customConfigUpdateValidator, ensureConfigIsEditable } from '../../middlewares/validators/config'
|
import { customConfigUpdateValidator, ensureConfigIsEditable } from '../../middlewares/validators/config'
|
||||||
|
import { logger } from '@server/helpers/logger'
|
||||||
|
|
||||||
const configRouter = express.Router()
|
const configRouter = express.Router()
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ async function updateCustomConfig (req: express.Request, res: express.Response)
|
||||||
|
|
||||||
const data = customConfig()
|
const data = customConfig()
|
||||||
|
|
||||||
|
logger.info('coucou', { data })
|
||||||
auditLogger.update(
|
auditLogger.update(
|
||||||
getAuditIdFromRes(res),
|
getAuditIdFromRes(res),
|
||||||
new CustomConfigAuditView(data),
|
new CustomConfigAuditView(data),
|
||||||
|
|
|
@ -175,7 +175,11 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
|
||||||
const targetUrl = body.targetUrl
|
const targetUrl = body.targetUrl
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
const youtubeDL = new YoutubeDLWrapper(targetUrl, ServerConfigManager.Instance.getEnabledResolutions('vod'))
|
const youtubeDL = new YoutubeDLWrapper(
|
||||||
|
targetUrl,
|
||||||
|
ServerConfigManager.Instance.getEnabledResolutions('vod'),
|
||||||
|
CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
|
||||||
|
)
|
||||||
|
|
||||||
// Get video infos
|
// Get video infos
|
||||||
let youtubeDLInfo: YoutubeDLInfo
|
let youtubeDLInfo: YoutubeDLInfo
|
||||||
|
|
|
@ -32,7 +32,7 @@ async function createTranscoding (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
const { resolution: maxResolution, audioStream } = await video.probeMaxQualityFile()
|
const { resolution: maxResolution, audioStream } = await video.probeMaxQualityFile()
|
||||||
const resolutions = await Hooks.wrapObject(
|
const resolutions = await Hooks.wrapObject(
|
||||||
computeResolutionsToTranscode({ inputResolution: maxResolution, type: 'vod', includeInputResolution: true }),
|
computeResolutionsToTranscode({ input: maxResolution, type: 'vod', includeInput: true, strictLower: false }),
|
||||||
'filter:transcoding.manual.resolutions-to-transcode.result',
|
'filter:transcoding.manual.resolutions-to-transcode.result',
|
||||||
body
|
body
|
||||||
)
|
)
|
||||||
|
|
|
@ -91,11 +91,12 @@ async function getAudioStreamCodec (path: string, existingProbe?: FfprobeData) {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function computeResolutionsToTranscode (options: {
|
function computeResolutionsToTranscode (options: {
|
||||||
inputResolution: number
|
input: number
|
||||||
type: 'vod' | 'live'
|
type: 'vod' | 'live'
|
||||||
includeInputResolution: boolean
|
includeInput: boolean
|
||||||
|
strictLower: boolean
|
||||||
}) {
|
}) {
|
||||||
const { inputResolution, type, includeInputResolution } = options
|
const { input, type, includeInput, strictLower } = options
|
||||||
|
|
||||||
const configResolutions = type === 'vod'
|
const configResolutions = type === 'vod'
|
||||||
? CONFIG.TRANSCODING.RESOLUTIONS
|
? CONFIG.TRANSCODING.RESOLUTIONS
|
||||||
|
@ -117,13 +118,18 @@ function computeResolutionsToTranscode (options: {
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const resolution of availableResolutions) {
|
for (const resolution of availableResolutions) {
|
||||||
if (configResolutions[resolution + 'p'] === true && inputResolution > resolution) {
|
// Resolution not enabled
|
||||||
resolutionsEnabled.add(resolution)
|
if (configResolutions[resolution + 'p'] !== true) continue
|
||||||
}
|
// Too big resolution for input file
|
||||||
|
if (input < resolution) continue
|
||||||
|
// We only want lower resolutions than input file
|
||||||
|
if (strictLower && input === resolution) continue
|
||||||
|
|
||||||
|
resolutionsEnabled.add(resolution)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeInputResolution) {
|
if (includeInput) {
|
||||||
resolutionsEnabled.add(inputResolution)
|
resolutionsEnabled.add(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.from(resolutionsEnabled)
|
return Array.from(resolutionsEnabled)
|
||||||
|
|
|
@ -57,7 +57,7 @@ export class YoutubeDLCLI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getYoutubeDLVideoFormat (enabledResolutions: VideoResolution[]) {
|
static getYoutubeDLVideoFormat (enabledResolutions: VideoResolution[], useBestFormat: boolean) {
|
||||||
/**
|
/**
|
||||||
* list of format selectors in order or preference
|
* list of format selectors in order or preference
|
||||||
* see https://github.com/ytdl-org/youtube-dl#format-selection
|
* see https://github.com/ytdl-org/youtube-dl#format-selection
|
||||||
|
@ -69,18 +69,26 @@ export class YoutubeDLCLI {
|
||||||
*
|
*
|
||||||
* in any case we avoid AV1, see https://github.com/Chocobozzz/PeerTube/issues/3499
|
* in any case we avoid AV1, see https://github.com/Chocobozzz/PeerTube/issues/3499
|
||||||
**/
|
**/
|
||||||
const resolution = enabledResolutions.length === 0
|
|
||||||
? VideoResolution.H_720P
|
|
||||||
: Math.max(...enabledResolutions)
|
|
||||||
|
|
||||||
return [
|
let result: string[] = []
|
||||||
`bestvideo[vcodec^=avc1][height=${resolution}]+bestaudio[ext=m4a]`, // case #1
|
|
||||||
`bestvideo[vcodec!*=av01][vcodec!*=vp9.2][height=${resolution}]+bestaudio`, // case #2
|
if (!useBestFormat) {
|
||||||
`bestvideo[vcodec^=avc1][height<=${resolution}]+bestaudio[ext=m4a]`, // case #3
|
const resolution = enabledResolutions.length === 0
|
||||||
`bestvideo[vcodec!*=av01][vcodec!*=vp9.2]+bestaudio`,
|
? VideoResolution.H_720P
|
||||||
|
: Math.max(...enabledResolutions)
|
||||||
|
|
||||||
|
result = [
|
||||||
|
`bestvideo[vcodec^=avc1][height=${resolution}]+bestaudio[ext=m4a]`, // case #1
|
||||||
|
`bestvideo[vcodec!*=av01][vcodec!*=vp9.2][height=${resolution}]+bestaudio`, // case #2
|
||||||
|
`bestvideo[vcodec^=avc1][height<=${resolution}]+bestaudio[ext=m4a]` // case #
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.concat([
|
||||||
|
'bestvideo[vcodec!*=av01][vcodec!*=vp9.2]+bestaudio',
|
||||||
'best[vcodec!*=av01][vcodec!*=vp9.2]', // case fallback for known formats
|
'best[vcodec!*=av01][vcodec!*=vp9.2]', // case fallback for known formats
|
||||||
'best' // Ultimate fallback
|
'best' // Ultimate fallback
|
||||||
].join('/')
|
]).join('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor () {
|
private constructor () {
|
||||||
|
|
|
@ -21,7 +21,11 @@ const processOptions = {
|
||||||
|
|
||||||
class YoutubeDLWrapper {
|
class YoutubeDLWrapper {
|
||||||
|
|
||||||
constructor (private readonly url: string = '', private readonly enabledResolutions: number[] = []) {
|
constructor (
|
||||||
|
private readonly url: string,
|
||||||
|
private readonly enabledResolutions: number[],
|
||||||
|
private readonly useBestFormat: boolean
|
||||||
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +34,7 @@ class YoutubeDLWrapper {
|
||||||
|
|
||||||
const info = await youtubeDL.getInfo({
|
const info = await youtubeDL.getInfo({
|
||||||
url: this.url,
|
url: this.url,
|
||||||
format: YoutubeDLCLI.getYoutubeDLVideoFormat(this.enabledResolutions),
|
format: YoutubeDLCLI.getYoutubeDLVideoFormat(this.enabledResolutions, this.useBestFormat),
|
||||||
additionalYoutubeDLArgs: youtubeDLArgs,
|
additionalYoutubeDLArgs: youtubeDLArgs,
|
||||||
processOptions
|
processOptions
|
||||||
})
|
})
|
||||||
|
@ -80,7 +84,7 @@ class YoutubeDLWrapper {
|
||||||
try {
|
try {
|
||||||
await youtubeDL.download({
|
await youtubeDL.download({
|
||||||
url: this.url,
|
url: this.url,
|
||||||
format: YoutubeDLCLI.getYoutubeDLVideoFormat(this.enabledResolutions),
|
format: YoutubeDLCLI.getYoutubeDLVideoFormat(this.enabledResolutions, this.useBestFormat),
|
||||||
output: pathWithoutExtension,
|
output: pathWithoutExtension,
|
||||||
timeout,
|
timeout,
|
||||||
processOptions
|
processOptions
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Job } from 'bull'
|
||||||
import { move, remove, stat } from 'fs-extra'
|
import { move, remove, stat } from 'fs-extra'
|
||||||
import { retryTransactionWrapper } from '@server/helpers/database-utils'
|
import { retryTransactionWrapper } from '@server/helpers/database-utils'
|
||||||
import { YoutubeDLWrapper } from '@server/helpers/youtube-dl'
|
import { YoutubeDLWrapper } from '@server/helpers/youtube-dl'
|
||||||
|
import { CONFIG } from '@server/initializers/config'
|
||||||
import { isPostImportVideoAccepted } from '@server/lib/moderation'
|
import { isPostImportVideoAccepted } from '@server/lib/moderation'
|
||||||
import { generateWebTorrentVideoFilename } from '@server/lib/paths'
|
import { generateWebTorrentVideoFilename } from '@server/lib/paths'
|
||||||
import { Hooks } from '@server/lib/plugins/hooks'
|
import { Hooks } from '@server/lib/plugins/hooks'
|
||||||
|
@ -25,7 +26,7 @@ import {
|
||||||
VideoResolution,
|
VideoResolution,
|
||||||
VideoState
|
VideoState
|
||||||
} from '@shared/models'
|
} from '@shared/models'
|
||||||
import { ffprobePromise, getVideoStreamDuration, getVideoStreamFPS, getVideoStreamDimensionsInfo } from '../../../helpers/ffmpeg'
|
import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamDuration, getVideoStreamFPS } from '../../../helpers/ffmpeg'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { getSecureTorrentName } from '../../../helpers/utils'
|
import { getSecureTorrentName } from '../../../helpers/utils'
|
||||||
import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent'
|
import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent'
|
||||||
|
@ -80,7 +81,11 @@ async function processYoutubeDLImport (job: Job, videoImport: MVideoImportDefaul
|
||||||
|
|
||||||
const options = { type: payload.type, videoImportId: videoImport.id }
|
const options = { type: payload.type, videoImportId: videoImport.id }
|
||||||
|
|
||||||
const youtubeDL = new YoutubeDLWrapper(videoImport.targetUrl, ServerConfigManager.Instance.getEnabledResolutions('vod'))
|
const youtubeDL = new YoutubeDLWrapper(
|
||||||
|
videoImport.targetUrl,
|
||||||
|
ServerConfigManager.Instance.getEnabledResolutions('vod'),
|
||||||
|
CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
|
||||||
|
)
|
||||||
|
|
||||||
return processFile(
|
return processFile(
|
||||||
() => youtubeDL.downloadVideo(payload.fileExt, JOB_TTL['video-import']),
|
() => youtubeDL.downloadVideo(payload.fileExt, JOB_TTL['video-import']),
|
||||||
|
|
|
@ -265,7 +265,7 @@ async function createLowerResolutionsJobs (options: {
|
||||||
|
|
||||||
// Create transcoding jobs if there are enabled resolutions
|
// Create transcoding jobs if there are enabled resolutions
|
||||||
const resolutionsEnabled = await Hooks.wrapObject(
|
const resolutionsEnabled = await Hooks.wrapObject(
|
||||||
computeResolutionsToTranscode({ inputResolution: videoFileResolution, type: 'vod', includeInputResolution: false }),
|
computeResolutionsToTranscode({ input: videoFileResolution, type: 'vod', includeInput: false, strictLower: true }),
|
||||||
'filter:transcoding.auto.resolutions-to-transcode.result',
|
'filter:transcoding.auto.resolutions-to-transcode.result',
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
|
|
|
@ -456,10 +456,10 @@ class LiveManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildAllResolutionsToTranscode (originResolution: number) {
|
private buildAllResolutionsToTranscode (originResolution: number) {
|
||||||
const includeInputResolution = CONFIG.LIVE.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
|
const includeInput = CONFIG.LIVE.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
|
||||||
|
|
||||||
const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED
|
const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED
|
||||||
? computeResolutionsToTranscode({ inputResolution: originResolution, type: 'live', includeInputResolution })
|
? computeResolutionsToTranscode({ input: originResolution, type: 'live', includeInput, strictLower: false })
|
||||||
: []
|
: []
|
||||||
|
|
||||||
if (resolutionsEnabled.length === 0) {
|
if (resolutionsEnabled.length === 0) {
|
||||||
|
|
|
@ -366,7 +366,7 @@ async function generateHlsPlaylistCommon (options: {
|
||||||
function buildOriginalFileResolution (inputResolution: number) {
|
function buildOriginalFileResolution (inputResolution: number) {
|
||||||
if (CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION === true) return toEven(inputResolution)
|
if (CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION === true) return toEven(inputResolution)
|
||||||
|
|
||||||
const resolutions = computeResolutionsToTranscode({ inputResolution, type: 'vod', includeInputResolution: false })
|
const resolutions = computeResolutionsToTranscode({ input: inputResolution, type: 'vod', includeInput: false, strictLower: false })
|
||||||
if (resolutions.length === 0) return toEven(inputResolution)
|
if (resolutions.length === 0) return toEven(inputResolution)
|
||||||
|
|
||||||
return Math.max(...resolutions)
|
return Math.max(...resolutions)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { pathExists, readdir, remove } from 'fs-extra'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { FIXTURE_URLS, testCaptionFile, testImage } from '@server/tests/shared'
|
import { FIXTURE_URLS, testCaptionFile, testImage } from '@server/tests/shared'
|
||||||
import { areHttpImportTestsDisabled } from '@shared/core-utils'
|
import { areHttpImportTestsDisabled } from '@shared/core-utils'
|
||||||
import { HttpStatusCode, Video, VideoImportState, VideoPrivacy, VideoResolution, VideoState } from '@shared/models'
|
import { CustomConfig, HttpStatusCode, Video, VideoImportState, VideoPrivacy, VideoResolution, VideoState } from '@shared/models'
|
||||||
import {
|
import {
|
||||||
cleanupTests,
|
cleanupTests,
|
||||||
createMultipleServers,
|
createMultipleServers,
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
setDefaultVideoChannel,
|
setDefaultVideoChannel,
|
||||||
waitJobs
|
waitJobs
|
||||||
} from '@shared/server-commands'
|
} from '@shared/server-commands'
|
||||||
|
import { DeepPartial } from '@shared/typescript-utils'
|
||||||
|
|
||||||
async function checkVideosServer1 (server: PeerTubeServer, idHttp: string, idMagnet: string, idTorrent: string) {
|
async function checkVideosServer1 (server: PeerTubeServer, idHttp: string, idMagnet: string, idTorrent: string) {
|
||||||
const videoHttp = await server.videos.get({ id: idHttp })
|
const videoHttp = await server.videos.get({ id: idHttp })
|
||||||
|
@ -105,6 +106,16 @@ describe('Test video imports', function () {
|
||||||
await setAccessTokensToServers(servers)
|
await setAccessTokensToServers(servers)
|
||||||
await setDefaultVideoChannel(servers)
|
await setDefaultVideoChannel(servers)
|
||||||
|
|
||||||
|
for (const server of servers) {
|
||||||
|
await server.config.updateExistingSubConfig({
|
||||||
|
newConfig: {
|
||||||
|
transcoding: {
|
||||||
|
alwaysTranscodeOriginalResolution: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
await doubleFollow(servers[0], servers[1])
|
await doubleFollow(servers[0], servers[1])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -306,10 +317,11 @@ describe('Test video imports', function () {
|
||||||
it('Should import no HDR version on a HDR video', async function () {
|
it('Should import no HDR version on a HDR video', async function () {
|
||||||
this.timeout(300_000)
|
this.timeout(300_000)
|
||||||
|
|
||||||
const config = {
|
const config: DeepPartial<CustomConfig> = {
|
||||||
transcoding: {
|
transcoding: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
resolutions: {
|
resolutions: {
|
||||||
|
'0p': false,
|
||||||
'144p': true,
|
'144p': true,
|
||||||
'240p': true,
|
'240p': true,
|
||||||
'360p': false,
|
'360p': false,
|
||||||
|
@ -321,19 +333,9 @@ describe('Test video imports', function () {
|
||||||
},
|
},
|
||||||
webtorrent: { enabled: true },
|
webtorrent: { enabled: true },
|
||||||
hls: { enabled: false }
|
hls: { enabled: false }
|
||||||
},
|
|
||||||
import: {
|
|
||||||
videos: {
|
|
||||||
http: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
torrent: {
|
|
||||||
enabled: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await servers[0].config.updateCustomSubConfig({ newConfig: config })
|
await servers[0].config.updateExistingSubConfig({ newConfig: config })
|
||||||
|
|
||||||
const attributes = {
|
const attributes = {
|
||||||
name: 'hdr video',
|
name: 'hdr video',
|
||||||
|
@ -353,6 +355,76 @@ describe('Test video imports', function () {
|
||||||
expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_240P)
|
expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_240P)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should not import resolution higher than enabled transcoding resolution', async function () {
|
||||||
|
this.timeout(300_000)
|
||||||
|
|
||||||
|
const config: DeepPartial<CustomConfig> = {
|
||||||
|
transcoding: {
|
||||||
|
enabled: true,
|
||||||
|
resolutions: {
|
||||||
|
'0p': false,
|
||||||
|
'144p': true,
|
||||||
|
'240p': false,
|
||||||
|
'360p': false,
|
||||||
|
'480p': false,
|
||||||
|
'720p': false,
|
||||||
|
'1080p': false,
|
||||||
|
'1440p': false,
|
||||||
|
'2160p': false
|
||||||
|
},
|
||||||
|
alwaysTranscodeOriginalResolution: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await servers[0].config.updateExistingSubConfig({ newConfig: config })
|
||||||
|
|
||||||
|
const attributes = {
|
||||||
|
name: 'small resolution video',
|
||||||
|
targetUrl: FIXTURE_URLS.youtube,
|
||||||
|
channelId: servers[0].store.channel.id,
|
||||||
|
privacy: VideoPrivacy.PUBLIC
|
||||||
|
}
|
||||||
|
const { video: videoImported } = await servers[0].imports.importVideo({ attributes })
|
||||||
|
const videoUUID = videoImported.uuid
|
||||||
|
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
|
// test resolution
|
||||||
|
const video = await servers[0].videos.get({ id: videoUUID })
|
||||||
|
expect(video.name).to.equal('small resolution video')
|
||||||
|
expect(video.files).to.have.lengthOf(1)
|
||||||
|
expect(video.files[0].resolution.id).to.equal(144)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should import resolution higher than enabled transcoding resolution', async function () {
|
||||||
|
this.timeout(300_000)
|
||||||
|
|
||||||
|
const config: DeepPartial<CustomConfig> = {
|
||||||
|
transcoding: {
|
||||||
|
alwaysTranscodeOriginalResolution: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await servers[0].config.updateExistingSubConfig({ newConfig: config })
|
||||||
|
|
||||||
|
const attributes = {
|
||||||
|
name: 'bigger resolution video',
|
||||||
|
targetUrl: FIXTURE_URLS.youtube,
|
||||||
|
channelId: servers[0].store.channel.id,
|
||||||
|
privacy: VideoPrivacy.PUBLIC
|
||||||
|
}
|
||||||
|
const { video: videoImported } = await servers[0].imports.importVideo({ attributes })
|
||||||
|
const videoUUID = videoImported.uuid
|
||||||
|
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
|
// test resolution
|
||||||
|
const video = await servers[0].videos.get({ id: videoUUID })
|
||||||
|
expect(video.name).to.equal('bigger resolution video')
|
||||||
|
|
||||||
|
expect(video.files).to.have.lengthOf(2)
|
||||||
|
expect(video.files.find(f => f.resolution.id === 240)).to.exist
|
||||||
|
expect(video.files.find(f => f.resolution.id === 144)).to.exist
|
||||||
|
})
|
||||||
|
|
||||||
it('Should import a peertube video', async function () {
|
it('Should import a peertube video', async function () {
|
||||||
this.timeout(120_000)
|
this.timeout(120_000)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue