slightly clearer layout of transcoding configuration

pull/3467/head
Rigel Kent 2020-12-14 12:47:10 +01:00
parent 421fd85337
commit ea5cdc11ff
No known key found for this signature in database
GPG Key ID: 5E53E96A494E452F
4 changed files with 260 additions and 130 deletions

View File

@ -701,7 +701,28 @@
<ng-template ngbNavContent>
<div class="form-row mt-5"> <!-- transcoding grid -->
<div class="form-row mt-4"> <!-- transcoding grid -->
<div class="form-group col-12 col-lg-4 col-xl-3"></div>
<div class="form-group form-group-right col-12 col-lg-8">
<div class="callout callout-info">
<span i18n>
Estimating a server's capacity to transcode and stream videos isn't easy and we can't tune PeerTube automatically.
</span>
<span i18n>
However, you may want to read our guidelines before tweaking the following values.
</span>
<div class="callout-container">
<a class="callout-link" target="_blank" rel="noopener noreferrer" href="https://docs.joinpeertube.org/#/admin-configuration?id=transcoding" i18n>Read guidelines</a>
</div>
</div>
</div>
</div>
<div class="form-row mt-2"> <!-- transcoding grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">TRANSCODING</div>
<div i18n class="inner-form-description">
@ -714,89 +735,179 @@
<ng-container formGroupName="transcoding">
<div class="form-group">
<my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled">
<div class="form-group mb-0 col-12 col-xl-11">
<my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true">
<ng-template ptTemplate="label">
<ng-container i18n>Transcoding enabled</ng-container>
</ng-template>
<ng-template ptTemplate="help">
<ng-container i18n>If you disable transcoding, many videos from your users will not work!</ng-container>
</ng-template>
<ng-container ngProjectAs="extra">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions"
i18n-labelText labelText="Allow additional extensions"
>
<ng-container ngProjectAs="description">
<span i18n>Allows users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, m2ts, .mxf, .nut videos.</span>
</ng-container>
</my-peertube-checkbox>
</div>
<div class="callout callout-light pt-2 pb-0">
<label i18n>Input formats</label>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles"
i18n-labelText labelText="Allow audio files upload"
>
<ng-container ngProjectAs="description">
<span i18n>Allows users to upload audio files that will be merged with the preview file on upload.</span>
</ng-container>
</my-peertube-checkbox>
</div>
<ng-container formGroupName="webtorrent">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingWebTorrentEnabled" formControlName="enabled"
i18n-labelText labelText="WebTorrent support enabled"
inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions"
i18n-labelText labelText="Allow additional extensions"
>
<ng-template ptTemplate="help">
<ng-container i18n>
<p>If you also enabled HLS support, it will multiply videos storage by 2</p>
<br />
<strong>If disabled, breaks federation with PeerTube instances < 2.1</strong>
</ng-container>
</ng-template>
<ng-container ngProjectAs="description">
<span i18n>Allows users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, m2ts, .mxf, or .nut videos.</span>
</ng-container>
</my-peertube-checkbox>
</div>
</ng-container>
<ng-container formGroupName="hls">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingHlsEnabled" formControlName="enabled"
i18n-labelText labelText="HLS with P2P support enabled"
inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles"
i18n-labelText labelText="Allow audio files upload"
>
<ng-template ptTemplate="help">
<ng-container i18n>
<strong>Requires ffmpeg >= 4.1</strong>
<p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with the current default player:</p>
<ul>
<li>Resolution change is smoother</li>
<li>Faster playback in particular with long videos</li>
<li>More stable playback (less bugs/infinite loading)</li>
</ul>
<p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p>
</ng-container>
</ng-template>
<ng-container ngProjectAs="description">
<div i18n>Allows users to upload .mp3, .ogg, .wma, .flac, .aac, or .ac3 audio files.</div>
<div i18n>The file will be merged in a still image video with the preview file on upload.</div>
</ng-container>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
<div class="callout callout-light pt-2 mt-2 pb-0">
<label i18n>Output formats</label>
<ng-container formGroupName="webtorrent">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingWebTorrentEnabled" formControlName="enabled"
i18n-labelText labelText="WebTorrent enabled"
>
<ng-template ptTemplate="help">
<ng-container i18n>
<p>If you also enabled HLS support, it will multiply videos storage by 2</p>
<br />
<strong>If disabled, breaks federation with PeerTube instances < 2.1</strong>
</ng-container>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
<ng-container formGroupName="hls">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<my-peertube-checkbox
inputName="transcodingHlsEnabled" formControlName="enabled"
i18n-labelText labelText="HLS with P2P support enabled"
[recommended]="true"
>
<ng-template ptTemplate="help">
<ng-container i18n>
<strong>Requires ffmpeg >= 4.1</strong>
<p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with plain WebTorrent:</p>
<ul>
<li>Resolution change is smoother</li>
<li>Faster playback especially with long videos</li>
<li>More stable playback (less bugs/infinite loading)</li>
</ul>
<p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p>
</ng-container>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<label i18n>Resolutions to generate per enabled format</label>
<div class="ml-2 mt-2 d-flex flex-column">
<ng-container formGroupName="resolutions">
<div class="form-group" *ngFor="let resolution of resolutions">
<my-peertube-checkbox
[inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
labelText="{{ resolution.label }}"
>
<ng-template *ngIf="resolution.description" ptTemplate="help">
<div [innerHTML]="resolution.description"></div>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
</div>
</div>
</ng-container>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
</div>
<div class="form-row mt-5"> <!-- transcoding live streams grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">TRANSCODING LIVE STREAMS</div>
<div i18n class="inner-form-description">
Same as above, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some.
</div>
</div>
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<ng-container formGroupName="live">
<ng-container formGroupName="transcoding">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
<my-peertube-checkbox
inputName="liveTranscodingEnabled" formControlName="enabled"
>
<ng-template ptTemplate="label">
<ng-container i18n>Transcoding enabled for live streams</ng-container>
</ng-template>
</my-peertube-checkbox>
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
<label i18n for="liveTranscodingThreads">Live resolutions to generate</label>
<div class="ml-2 mt-2 d-flex flex-column">
<ng-container formGroupName="resolutions">
<div class="form-group" *ngFor="let resolution of liveResolutions">
<my-peertube-checkbox
[inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
labelText="{{resolution.label}}"
>
<ng-template *ngIf="resolution.description" ptTemplate="help">
<div [innerHTML]="resolution.description"></div>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
</div>
</ng-container>
</ng-container>
</div>
</div>
<div class="form-row mt-5"> <!-- load repartition grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">LOAD REPARTITION</div>
<div i18n class="inner-form-description">
Share CPU power to prioritize one or the other. The total should not be above the number of available threads.
</div>
</div>
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
<ng-container formGroupName="transcoding">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<label i18n for="transcodingThreads">Transcoding threads</label>
<div class="peertube-select-container">
<select id="transcodingThreads" formControlName="threads" class="form-control">
<option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
@ -806,31 +917,29 @@
</div>
<div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div>
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
<label i18n>Resolutions to generate</label>
<div class="ml-2 mt-2 d-flex flex-column">
<ng-container formGroupName="resolutions">
<div class="form-group" *ngFor="let resolution of resolutions">
<my-peertube-checkbox
[inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
labelText="{{resolution.label}}"
>
<ng-template *ngIf="resolution.description" ptTemplate="help">
<div [innerHTML]="resolution.description"></div>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
</div>
</ng-container>
<ng-container formGroupName="live">
<ng-container formGroupName="transcoding">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
<label i18n for="liveTranscodingThreads">Live transcoding threads</label>
<div class="peertube-select-container">
<select id="liveTranscodingThreads" formControlName="threads" class="form-control">
<option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
{{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}}
</option>
</select>
</div>
<div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div>
</div>
</ng-container>
</ng-container>
<div *ngIf="getTotalTranscodingThreads().atMost" i18n>Transcoding will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }}.</div>
<div *ngIf="!getTotalTranscodingThreads().atMost" i18n>Transcoding will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }}.</div>
</div>
</div>
</ng-template>
@ -877,7 +986,7 @@
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
<label i18n for="liveMaxInstanceLives">Max lives created on your instance (-1 for "unlimited")</label>
<label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance <span class="text-muted">(-1 for "unlimited")</span></label>
<div class="number-with-unit">
<input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" />
<span i18n>{form.value['live']['maxInstanceLives'], plural, =1 {live} other {lives}}</span>
@ -885,7 +994,7 @@
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
<label i18n for="liveMaxUserLives">Max lives created per user (-1 for "unlimited")</label>
<label i18n for="liveMaxUserLives">Max simultaneous lives created per user <span class="text-muted">(-1 for "unlimited")</span></label>
<div class="number-with-unit">
<input type="number" name="liveMaxUserLives" formControlName="maxUserLives" />
<span i18n>{form.value['live']['maxUserLives'], plural, =1 {live} other {lives}}</span>
@ -903,51 +1012,6 @@
></ng-select>
</div>
</div>
<ng-container formGroupName="transcoding">
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
<my-peertube-checkbox
inputName="liveTranscodingEnabled" formControlName="enabled"
i18n-labelText labelText="Enable live transcoding"
>
<ng-container ngProjectAs="description" i18n>
Requires a lot of CPU!
</ng-container>
</my-peertube-checkbox>
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
<label i18n for="liveTranscodingThreads">Live transcoding threads</label>
<div class="peertube-select-container">
<select id="liveTranscodingThreads" formControlName="threads" class="form-control">
<option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
{{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}}
</option>
</select>
</div>
<div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div>
</div>
<div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
<label i18n for="liveTranscodingThreads">Live resolutions to generate</label>
<div class="ml-2 mt-2 d-flex flex-column">
<ng-container formGroupName="resolutions">
<div class="form-group" *ngFor="let resolution of liveResolutions">
<my-peertube-checkbox
[inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
labelText="{{resolution.label}}"
>
<ng-template *ngIf="resolution.description" ptTemplate="help">
<div [innerHTML]="resolution.description"></div>
</ng-template>
</my-peertube-checkbox>
</div>
</ng-container>
</div>
</div>
</ng-container>
</ng-container>
</my-peertube-checkbox>
</div>
@ -963,7 +1027,7 @@
<ng-template ngbNavContent>
<div class="form-row mt-4"> <!-- cache grid -->
<div class="form-row mt-5"> <!-- cache grid -->
<div class="form-group col-12 col-lg-4 col-xl-3">
<div i18n class="inner-form-title">CACHE</div>
<div i18n class="inner-form-description">

View File

@ -103,3 +103,23 @@ ngb-tabset:not(.previews) ::ng-deep {
width: fit-content;
margin-top: 10px;
}
.callout-container {
position: absolute;
display: flex;
height: 0;
width: 100%;
justify-content: right;
.callout-link {
@include peertube-button-link;
position: relative;
right: 3.3em;
top: .3em;
font-size: 90%;
color: pvar(--mainColor);
background-color: pvar(--mainBackgroundColor);
padding: 0 .3em;
}
}

View File

@ -119,6 +119,30 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A
.map(t => t.name)
}
getTotalTranscodingThreads () {
const transcodingEnabled = this.form.value['transcoding']['enabled']
const transcodingThreads = this.form.value['transcoding']['threads']
const liveTranscodingEnabled = this.form.value['live']['transcoding']['enabled']
const liveTranscodingThreads = this.form.value['live']['transcoding']['threads']
// checks whether all enabled method are on fixed values and not on auto (= 0)
let noneOnAuto = !transcodingEnabled || +transcodingThreads > 0
noneOnAuto &&= !liveTranscodingEnabled || +liveTranscodingThreads > 0
// count total of fixed value, repalcing auto by a single thread (knowing it will display "at least")
let value = 0
if (transcodingEnabled) value += +transcodingThreads || 1
if (liveTranscodingEnabled) value += +liveTranscodingThreads || 1
return {
value,
atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible
unit: value > 1
? $localize`threads`
: $localize`thread`
}
}
getResolutionKey (resolution: string) {
return 'transcoding.resolutions.' + resolution
}

View File

@ -361,3 +361,25 @@ ngb-tooltip-window {
display: none;
}
}
.callout {
padding: 1.25rem;
border: 1px solid #eee;
border-radius: .25rem;
& > label {
position: relative;
top: -5px;
left: -10px;
color: #6c757d !important;
}
&:not(.callout-light) {
border-left-width: .25rem;
}
&.callout-info {
border-color: pvar(--mainColorLightest);
border-left-color: pvar(--mainColor);
}
}