diff --git a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts
index 63e0343fa..9b55cb43c 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts
@@ -17,6 +17,10 @@ export class EditConfigurationService {
label: $localize`Audio-only`,
description: $localize`A .mp4
that keeps the original audio track, with no video`
},
+ {
+ id: '144p',
+ label: $localize`144p`
+ },
{
id: '240p',
label: $localize`240p`
diff --git a/config/default.yaml b/config/default.yaml
index cf9d69a62..c70e6a205 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -323,6 +323,7 @@ transcoding:
resolutions: # Only created if the original video has a higher resolution, uses more storage!
0p: false # audio-only (creates mp4 without video stream, always created when enabled)
+ 144p: false
240p: false
360p: false
480p: false
@@ -382,6 +383,7 @@ live:
profile: 'default'
resolutions:
+ 144p: false
240p: false
360p: false
480p: false
diff --git a/config/production.yaml.example b/config/production.yaml.example
index 70993bf57..0da96f612 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -333,6 +333,7 @@ transcoding:
resolutions: # Only created if the original video has a higher resolution, uses more storage!
0p: false # audio-only (creates mp4 without video stream, always created when enabled)
+ 144p: false
240p: false
360p: false
480p: false
@@ -392,6 +393,7 @@ live:
profile: 'default'
resolutions:
+ 144p: false
240p: false
360p: false
480p: false
diff --git a/config/test.yaml b/config/test.yaml
index 3eb2f04d8..e9731d863 100644
--- a/config/test.yaml
+++ b/config/test.yaml
@@ -80,6 +80,7 @@ transcoding:
concurrency: 2
resolutions:
0p: false
+ 144p: false
240p: true
360p: true
480p: true
@@ -105,6 +106,7 @@ live:
threads: 2
resolutions:
+ 144p: false
240p: false
360p: false
480p: false
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 8965cacc9..805ad99c7 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -208,6 +208,7 @@ function customConfig (): CustomConfig {
profile: CONFIG.TRANSCODING.PROFILE,
resolutions: {
'0p': CONFIG.TRANSCODING.RESOLUTIONS['0p'],
+ '144p': CONFIG.TRANSCODING.RESOLUTIONS['144p'],
'240p': CONFIG.TRANSCODING.RESOLUTIONS['240p'],
'360p': CONFIG.TRANSCODING.RESOLUTIONS['360p'],
'480p': CONFIG.TRANSCODING.RESOLUTIONS['480p'],
@@ -234,6 +235,7 @@ function customConfig (): CustomConfig {
threads: CONFIG.LIVE.TRANSCODING.THREADS,
profile: CONFIG.LIVE.TRANSCODING.PROFILE,
resolutions: {
+ '144p': CONFIG.LIVE.TRANSCODING.RESOLUTIONS['144p'],
'240p': CONFIG.LIVE.TRANSCODING.RESOLUTIONS['240p'],
'360p': CONFIG.LIVE.TRANSCODING.RESOLUTIONS['360p'],
'480p': CONFIG.LIVE.TRANSCODING.RESOLUTIONS['480p'],
diff --git a/server/helpers/ffprobe-utils.ts b/server/helpers/ffprobe-utils.ts
index 767f37f9c..907f13651 100644
--- a/server/helpers/ffprobe-utils.ts
+++ b/server/helpers/ffprobe-utils.ts
@@ -220,6 +220,7 @@ function computeResolutionsToTranscode (videoFileResolution: number, type: 'vod'
VideoResolution.H_360P,
VideoResolution.H_720P,
VideoResolution.H_240P,
+ VideoResolution.H_144P,
VideoResolution.H_1080P,
VideoResolution.H_1440P,
VideoResolution.H_4K
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts
index 72acdd422..39f0cebf6 100644
--- a/server/initializers/checker-before-init.ts
+++ b/server/initializers/checker-before-init.ts
@@ -28,8 +28,9 @@ function checkMissedConfig () {
'redundancy.videos.strategies', 'redundancy.videos.check_interval',
'transcoding.enabled', 'transcoding.threads', 'transcoding.allow_additional_extensions', 'transcoding.hls.enabled',
'transcoding.profile', 'transcoding.concurrency',
- 'transcoding.resolutions.0p', 'transcoding.resolutions.240p', 'transcoding.resolutions.360p', 'transcoding.resolutions.480p',
- 'transcoding.resolutions.720p', 'transcoding.resolutions.1080p', 'transcoding.resolutions.1440p', 'transcoding.resolutions.2160p',
+ 'transcoding.resolutions.0p', 'transcoding.resolutions.144p', 'transcoding.resolutions.240p', 'transcoding.resolutions.360p',
+ 'transcoding.resolutions.480p', 'transcoding.resolutions.720p', 'transcoding.resolutions.1080p', 'transcoding.resolutions.1440p',
+ 'transcoding.resolutions.2160p',
'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'auto_blacklist.videos.of_users.enabled',
'trending.videos.interval_days',
'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route',
@@ -47,9 +48,9 @@ function checkMissedConfig () {
'search.search_index.disable_local_search', 'search.search_index.is_default_search',
'live.enabled', 'live.allow_replay', 'live.max_duration', 'live.max_user_lives', 'live.max_instance_lives',
'live.transcoding.enabled', 'live.transcoding.threads', 'live.transcoding.profile',
- 'live.transcoding.resolutions.240p', 'live.transcoding.resolutions.360p', 'live.transcoding.resolutions.480p',
- 'live.transcoding.resolutions.720p', 'live.transcoding.resolutions.1080p', 'live.transcoding.resolutions.1440p',
- 'live.transcoding.resolutions.2160p'
+ 'live.transcoding.resolutions.144p', 'live.transcoding.resolutions.240p', 'live.transcoding.resolutions.360p',
+ 'live.transcoding.resolutions.480p', 'live.transcoding.resolutions.720p', 'live.transcoding.resolutions.1080p',
+ 'live.transcoding.resolutions.1440p', 'live.transcoding.resolutions.2160p'
]
const requiredAlternatives = [
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 8375bf430..0d5e29499 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -245,6 +245,7 @@ const CONFIG = {
get PROFILE () { return config.get('transcoding.profile') },
RESOLUTIONS: {
get '0p' () { return config.get('transcoding.resolutions.0p') },
+ get '144p' () { return config.get('transcoding.resolutions.144p') },
get '240p' () { return config.get('transcoding.resolutions.240p') },
get '360p' () { return config.get('transcoding.resolutions.360p') },
get '480p' () { return config.get('transcoding.resolutions.480p') },
@@ -279,6 +280,7 @@ const CONFIG = {
get PROFILE () { return config.get('live.transcoding.profile') },
RESOLUTIONS: {
+ get '144p' () { return config.get('live.transcoding.resolutions.144p') },
get '240p' () { return config.get('live.transcoding.resolutions.240p') },
get '360p' () { return config.get('live.transcoding.resolutions.360p') },
get '480p' () { return config.get('live.transcoding.resolutions.480p') },
diff --git a/server/middlewares/validators/config.ts b/server/middlewares/validators/config.ts
index da52b14ba..8b14feb3c 100644
--- a/server/middlewares/validators/config.ts
+++ b/server/middlewares/validators/config.ts
@@ -45,6 +45,7 @@ const customConfigUpdateValidator = [
body('transcoding.threads').isInt().withMessage('Should have a valid transcoding threads number'),
body('transcoding.concurrency').isInt({ min: 1 }).withMessage('Should have a valid transcoding concurrency number'),
body('transcoding.resolutions.0p').isBoolean().withMessage('Should have a valid transcoding 0p resolution enabled boolean'),
+ body('transcoding.resolutions.144p').isBoolean().withMessage('Should have a valid transcoding 144p resolution enabled boolean'),
body('transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
body('transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
body('transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
@@ -80,6 +81,7 @@ const customConfigUpdateValidator = [
body('live.maxUserLives').custom(isIntOrNull).withMessage('Should have a valid max user lives'),
body('live.transcoding.enabled').isBoolean().withMessage('Should have a valid live transcoding enabled boolean'),
body('live.transcoding.threads').isInt().withMessage('Should have a valid live transcoding threads'),
+ body('live.transcoding.resolutions.144p').isBoolean().withMessage('Should have a valid transcoding 144p resolution enabled boolean'),
body('live.transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
body('live.transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
body('live.transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index 273b1f718..d0cd7722b 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -93,6 +93,7 @@ describe('Test config API validators', function () {
profile: 'vod_profile',
resolutions: {
'0p': false,
+ '144p': false,
'240p': false,
'360p': true,
'480p': true,
@@ -121,6 +122,7 @@ describe('Test config API validators', function () {
threads: 4,
profile: 'live_profile',
resolutions: {
+ '144p': true,
'240p': true,
'360p': true,
'480p': true,
diff --git a/server/tests/api/live/live-constraints.ts b/server/tests/api/live/live-constraints.ts
index 4acde3cc5..6a6a11796 100644
--- a/server/tests/api/live/live-constraints.ts
+++ b/server/tests/api/live/live-constraints.ts
@@ -168,7 +168,7 @@ describe('Test live constraints', function () {
await waitUntilLivePublishedOnAllServers(userVideoLiveoId)
await waitJobs(servers)
- await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240 ])
+ await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240, 144 ])
})
after(async function () {
diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts
index 0b405dd94..619602d0b 100644
--- a/server/tests/api/live/live.ts
+++ b/server/tests/api/live/live.ts
@@ -421,6 +421,7 @@ describe('Test live', function () {
transcoding: {
enabled: true,
resolutions: {
+ '144p': resolutions.includes(144),
'240p': resolutions.includes(240),
'360p': resolutions.includes(360),
'480p': resolutions.includes(480),
diff --git a/server/tests/api/object-storage/live.ts b/server/tests/api/object-storage/live.ts
index d3e6777f2..3726a717b 100644
--- a/server/tests/api/object-storage/live.ts
+++ b/server/tests/api/object-storage/live.ts
@@ -123,7 +123,7 @@ describe('Object storage for lives', function () {
expect(video.streamingPlaylists).to.have.lengthOf(1)
const files = video.streamingPlaylists[0].files
- expect(files).to.have.lengthOf(4)
+ expect(files).to.have.lengthOf(5)
await checkFiles(files)
}
diff --git a/server/tests/api/object-storage/video-imports.ts b/server/tests/api/object-storage/video-imports.ts
index efc01f550..363fe3b5b 100644
--- a/server/tests/api/object-storage/video-imports.ts
+++ b/server/tests/api/object-storage/video-imports.ts
@@ -88,9 +88,9 @@ describe('Object storage for video import', function () {
const video = await server.videos.get({ id: uuid })
- expect(video.files).to.have.lengthOf(4)
+ expect(video.files).to.have.lengthOf(5)
expect(video.streamingPlaylists).to.have.lengthOf(1)
- expect(video.streamingPlaylists[0].files).to.have.lengthOf(4)
+ expect(video.streamingPlaylists[0].files).to.have.lengthOf(5)
for (const file of video.files) {
expectStartWith(file.fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl())
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index 8d5b3ac7f..ea524723c 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -66,6 +66,7 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
expect(data.transcoding.threads).to.equal(2)
expect(data.transcoding.concurrency).to.equal(2)
expect(data.transcoding.profile).to.equal('default')
+ expect(data.transcoding.resolutions['144p']).to.be.false
expect(data.transcoding.resolutions['240p']).to.be.true
expect(data.transcoding.resolutions['360p']).to.be.true
expect(data.transcoding.resolutions['480p']).to.be.true
@@ -84,6 +85,7 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
expect(data.live.transcoding.enabled).to.be.false
expect(data.live.transcoding.threads).to.equal(2)
expect(data.live.transcoding.profile).to.equal('default')
+ expect(data.live.transcoding.resolutions['144p']).to.be.false
expect(data.live.transcoding.resolutions['240p']).to.be.false
expect(data.live.transcoding.resolutions['360p']).to.be.false
expect(data.live.transcoding.resolutions['480p']).to.be.false
@@ -163,6 +165,7 @@ function checkUpdatedConfig (data: CustomConfig) {
expect(data.transcoding.allowAdditionalExtensions).to.be.true
expect(data.transcoding.allowAudioFiles).to.be.true
expect(data.transcoding.profile).to.equal('vod_profile')
+ expect(data.transcoding.resolutions['144p']).to.be.false
expect(data.transcoding.resolutions['240p']).to.be.false
expect(data.transcoding.resolutions['360p']).to.be.true
expect(data.transcoding.resolutions['480p']).to.be.true
@@ -180,6 +183,7 @@ function checkUpdatedConfig (data: CustomConfig) {
expect(data.live.transcoding.enabled).to.be.true
expect(data.live.transcoding.threads).to.equal(4)
expect(data.live.transcoding.profile).to.equal('live_profile')
+ expect(data.live.transcoding.resolutions['144p']).to.be.true
expect(data.live.transcoding.resolutions['240p']).to.be.true
expect(data.live.transcoding.resolutions['360p']).to.be.true
expect(data.live.transcoding.resolutions['480p']).to.be.true
@@ -281,6 +285,7 @@ const newCustomConfig: CustomConfig = {
profile: 'vod_profile',
resolutions: {
'0p': false,
+ '144p': false,
'240p': false,
'360p': true,
'480p': true,
@@ -307,6 +312,7 @@ const newCustomConfig: CustomConfig = {
threads: 4,
profile: 'live_profile',
resolutions: {
+ '144p': true,
'240p': true,
'360p': true,
'480p': true,
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index 5ec771429..efc80463c 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -198,6 +198,7 @@ describe('Test stats (excluding redundancy)', function () {
},
resolutions: {
'0p': false,
+ '144p': false,
'240p': false,
'360p': false,
'480p': false,
diff --git a/server/tests/api/videos/audio-only.ts b/server/tests/api/videos/audio-only.ts
index 7fac6e738..f4b635bd5 100644
--- a/server/tests/api/videos/audio-only.ts
+++ b/server/tests/api/videos/audio-only.ts
@@ -21,6 +21,7 @@ describe('Test audio only video transcoding', function () {
enabled: true,
resolutions: {
'0p': true,
+ '144p': false,
'240p': true,
'360p': false,
'480p': false,
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts
index 91124725f..a18c3d672 100644
--- a/server/tests/api/videos/video-hls.ts
+++ b/server/tests/api/videos/video-hls.ts
@@ -243,6 +243,7 @@ describe('Test HLS videos', function () {
enabled: true,
allowAudioFiles: true,
resolutions: {
+ '144p': false,
'240p': true,
'360p': true,
'480p': true,
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index bb1627a27..987f34e97 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -300,6 +300,7 @@ describe('Test video imports', function () {
transcoding: {
enabled: true,
resolutions: {
+ '144p': true,
'240p': true,
'360p': false,
'480p': false,
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index 21609fd82..b3226dbf7 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -40,6 +40,7 @@ function updateConfigForTranscoding (server: PeerTubeServer) {
webtorrent: { enabled: true },
resolutions: {
'0p': false,
+ '144p': true,
'240p': true,
'360p': true,
'480p': true,
@@ -119,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/)
@@ -205,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')
@@ -226,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 })
@@ -259,7 +260,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 file = videoDetails.files.find(f => f.resolution.id === 240)
const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
@@ -316,7 +317,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 fixturePath = buildAbsoluteFixturePath(attributes.fixture)
const fixtureVideoProbe = await getAudioStream(fixturePath)
@@ -348,6 +349,7 @@ describe('Test video transcoding', function () {
webtorrent: { enabled: true },
resolutions: {
'0p': false,
+ '144p': false,
'240p': false,
'360p': false,
'480p': false,
@@ -419,6 +421,7 @@ describe('Test video transcoding', function () {
webtorrent: { enabled: true },
resolutions: {
'0p': true,
+ '144p': false,
'240p': false,
'360p': false
}
@@ -473,13 +476,14 @@ 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 ]) {
+ 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)
@@ -586,6 +590,7 @@ describe('Test video transcoding', function () {
transcoding: {
enabled: true,
resolutions: {
+ '144p': true,
'240p': true,
'360p': true,
'480p': true,
@@ -667,7 +672,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
@@ -695,21 +700,21 @@ describe('Test video transcoding', function () {
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))) {
diff --git a/server/tests/cli/create-transcoding-job.ts b/server/tests/cli/create-transcoding-job.ts
index 2b388ab0c..fb9c2584f 100644
--- a/server/tests/cli/create-transcoding-job.ts
+++ b/server/tests/cli/create-transcoding-job.ts
@@ -220,9 +220,9 @@ function runTests (objectStorage: boolean) {
for (const server of servers) {
const videoDetails = await server.videos.get({ id: videosUUID[4] })
- expect(videoDetails.files).to.have.lengthOf(4)
+ expect(videoDetails.files).to.have.lengthOf(5)
expect(videoDetails.streamingPlaylists).to.have.lengthOf(1)
- expect(videoDetails.streamingPlaylists[0].files).to.have.lengthOf(4)
+ expect(videoDetails.streamingPlaylists[0].files).to.have.lengthOf(5)
if (objectStorage) {
await checkFilesInObjectStorage(videoDetails.files, 'webtorrent')
diff --git a/server/tests/helpers/core-utils.ts b/server/tests/helpers/core-utils.ts
index a6bf5b4c5..fa0a71341 100644
--- a/server/tests/helpers/core-utils.ts
+++ b/server/tests/helpers/core-utils.ts
@@ -104,6 +104,7 @@ describe('Bitrate', function () {
it('Should get appropriate max bitrate', function () {
const tests = [
+ { resolution: VideoResolution.H_144P, ratio: 16 / 9, fps: 24, min: 200, max: 400 },
{ resolution: VideoResolution.H_240P, ratio: 16 / 9, fps: 24, min: 600, max: 800 },
{ resolution: VideoResolution.H_360P, ratio: 16 / 9, fps: 24, min: 1200, max: 1600 },
{ resolution: VideoResolution.H_480P, ratio: 16 / 9, fps: 24, min: 2000, max: 2300 },
@@ -119,6 +120,7 @@ describe('Bitrate', function () {
it('Should get appropriate average bitrate', function () {
const tests = [
+ { resolution: VideoResolution.H_144P, ratio: 16 / 9, fps: 24, min: 50, max: 300 },
{ resolution: VideoResolution.H_240P, ratio: 16 / 9, fps: 24, min: 350, max: 450 },
{ resolution: VideoResolution.H_360P, ratio: 16 / 9, fps: 24, min: 700, max: 900 },
{ resolution: VideoResolution.H_480P, ratio: 16 / 9, fps: 24, min: 1100, max: 1300 },
diff --git a/shared/core-utils/videos/bitrate.ts b/shared/core-utils/videos/bitrate.ts
index a6712f8a4..18c6e2f6c 100644
--- a/shared/core-utils/videos/bitrate.ts
+++ b/shared/core-utils/videos/bitrate.ts
@@ -6,6 +6,7 @@ type BitPerPixel = { [ id in VideoResolution ]: number }
const averageBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0,
+ [VideoResolution.H_144P]: 0.19,
[VideoResolution.H_240P]: 0.17,
[VideoResolution.H_360P]: 0.15,
[VideoResolution.H_480P]: 0.12,
@@ -17,6 +18,7 @@ const averageBitPerPixel: BitPerPixel = {
const maxBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0,
+ [VideoResolution.H_144P]: 0.32,
[VideoResolution.H_240P]: 0.29,
[VideoResolution.H_360P]: 0.26,
[VideoResolution.H_480P]: 0.22,
@@ -73,6 +75,7 @@ function calculateBitrate (options: {
VideoResolution.H_480P,
VideoResolution.H_360P,
VideoResolution.H_240P,
+ VideoResolution.H_144P,
VideoResolution.H_NOVIDEO
]
diff --git a/shared/extra-utils/server/config-command.ts b/shared/extra-utils/server/config-command.ts
index 2746e9ac4..7a768b4df 100644
--- a/shared/extra-utils/server/config-command.ts
+++ b/shared/extra-utils/server/config-command.ts
@@ -8,6 +8,7 @@ export class ConfigCommand extends AbstractCommand {
static getCustomConfigResolutions (enabled: boolean) {
return {
+ '144p': enabled,
'240p': enabled,
'360p': enabled,
'480p': enabled,
@@ -232,6 +233,7 @@ export class ConfigCommand extends AbstractCommand {
profile: 'default',
resolutions: {
'0p': false,
+ '144p': false,
'240p': false,
'360p': true,
'480p': true,
@@ -258,6 +260,7 @@ export class ConfigCommand extends AbstractCommand {
threads: 4,
profile: 'default',
resolutions: {
+ '144p': true,
'240p': true,
'360p': true,
'480p': true,
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts
index 322fbb797..3ed932494 100644
--- a/shared/models/server/custom-config.model.ts
+++ b/shared/models/server/custom-config.model.ts
@@ -2,6 +2,7 @@ import { NSFWPolicyType } from '../videos/nsfw-policy.type'
import { BroadcastMessageLevel } from './broadcast-message-level.type'
export type ConfigResolutions = {
+ '144p': boolean
'240p': boolean
'360p': boolean
'480p': boolean
diff --git a/shared/models/videos/video-resolution.enum.ts b/shared/models/videos/video-resolution.enum.ts
index 24cd2d04d..5b48ad353 100644
--- a/shared/models/videos/video-resolution.enum.ts
+++ b/shared/models/videos/video-resolution.enum.ts
@@ -1,5 +1,6 @@
export const enum VideoResolution {
H_NOVIDEO = 0,
+ H_144P = 144,
H_240P = 240,
H_360P = 360,
H_480P = 480,
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml
index ec246bca0..48109664a 100644
--- a/support/doc/api/openapi.yaml
+++ b/support/doc/api/openapi.yaml
@@ -6167,6 +6167,8 @@ components:
properties:
0p:
type: boolean
+ 144p:
+ type: boolean
240p:
type: boolean
360p:
diff --git a/support/docker/production/config/custom-environment-variables.yaml b/support/docker/production/config/custom-environment-variables.yaml
index c7cd28e65..d5304b0dd 100644
--- a/support/docker/production/config/custom-environment-variables.yaml
+++ b/support/docker/production/config/custom-environment-variables.yaml
@@ -130,6 +130,9 @@ transcoding:
__name: "PEERTUBE_TRANSCODING_THREADS"
__format: "json"
resolutions:
+ 144p:
+ __name: "PEERTUBE_TRANSCODING_144P"
+ __format: "json"
240p:
__name: "PEERTUBE_TRANSCODING_240P"
__format: "json"