1 <div class=
"video-edit" [formGroup]=
"form">
2 <div ngbNav #
nav=
"ngbNav" class=
"nav-tabs">
4 <ng-template #pluginSettingTemplate let-pluginSetting
>
5 <div class=
"form-group" [hidden]=
"isPluginFieldHidden(pluginSetting)">
6 <my-dynamic-form-field [form]=
"pluginDataFormGroup" [formErrors]=
"formErrors['pluginData']" [setting]=
"pluginSetting.commonOptions"></my-dynamic-form-field>
10 <ng-container ngbNavItem
>
11 <a ngbNavLink i18n
>Basic info
</a>
13 <ng-template ngbNavContent
>
14 <div class=
"form-columns">
15 <div class=
"col-video-edit">
16 <div class=
"form-group">
17 <label i18n
for=
"name">Title
</label>
18 <input type=
"text" id=
"name" class=
"form-control" formControlName=
"name" />
19 <div *
ngIf=
"formErrors.name" class=
"form-error">
24 <div class=
"form-group">
25 <label for=
"label-tags" i18n
class=
"label-tags">Tags
</label>
28 <ng-template ptTemplate=
"customHtml">
30 Tags could be used to suggest relevant recommendations.
<br />
31 There is a maximum of
5 tags.
<br />
32 Press
<kbd>Enter
</kbd> to add a new tag.
37 <my-select-tags labelForId=
"label-tags" formControlName=
"tags"></my-select-tags>
38 <div *
ngIf=
"formErrors.tags" class=
"form-error">
43 <div class=
"form-group">
44 <label i18n
for=
"description">Description
</label>
46 <my-help helpType=
"markdownText">
47 <ng-template ptTemplate=
"preHtml">
48 <ng-container i18n
>Video descriptions are truncated by default and require manual action to expand them.
</ng-container>
52 <ng-container i18n
>A timestamp (
<i>00:
05</i> for example) is automatically converted into a link to a part of the video.
</ng-container>
57 formControlName=
"description" [markdownVideo]=
"videoToUpdate"
58 [formError]=
"formErrors.description" [truncate]=
"250"
59 ></my-markdown-textarea>
63 <div class=
"col-video-edit">
64 <div class=
"form-group">
65 <label i18n
for=
"channel">Channel
</label>
66 <my-select-channel labelForId=
"channel" [items]=
"userVideoChannels" formControlName=
"channelId"></my-select-channel>
69 <div class=
"form-group">
70 <label i18n
for=
"category">Category
</label>
72 labelForId=
"category" [items]=
"videoCategories" formControlName=
"category" [clearable]=
"true"
75 <div *
ngIf=
"formErrors.category" class=
"form-error">
76 {{ formErrors.category }}
80 <div class=
"form-group">
81 <label i18n
for=
"licence">Licence
</label>
84 <ng-template ptTemplate=
"customHtml">
86 <a href=
"https://chooser-beta.creativecommons.org/" target=
"_blank" rel=
"noopener noreferrer">Choose
</a> the appropriate licence for your work.
92 labelForId=
"licence" [items]=
"videoLicences" formControlName=
"licence" [clearable]=
"true"
95 <div *
ngIf=
"formErrors.licence" class=
"form-error">
96 {{ formErrors.licence }}
100 <div class=
"form-group">
101 <label i18n
for=
"language">Language
</label>
103 labelForId=
"language" [items]=
"videoLanguages" formControlName=
"language"
104 [clearable]=
"true" [searchable]=
"true" [groupBy]=
"'group'"
105 ></my-select-options>
107 <div *
ngIf=
"formErrors.language" class=
"form-error">
108 {{ formErrors.language }}
112 <div class=
"form-group">
113 <label i18n
for=
"privacy">Privacy
</label>
115 labelForId=
"privacy" [items]=
"videoPrivacies" formControlName=
"privacy" [clearable]=
"false"
116 ></my-select-options>
118 <div *
ngIf=
"formErrors.privacy" class=
"form-error">
119 {{ formErrors.privacy }}
123 <div *
ngIf=
"schedulePublicationEnabled" class=
"form-group">
124 <label i18n
for=
"schedulePublicationAt">Schedule publication ({{ calendarTimezone }})
</label>
126 id=
"schedulePublicationAt" formControlName=
"schedulePublicationAt" [dateFormat]=
"calendarDateFormat"
127 [firstDayOfWeek]=
"0" [minDate]=
"minScheduledDate" [showTime]=
"true" [hideOnDateTimeSelect]=
"true"
131 <div *
ngIf=
"formErrors.schedulePublicationAt" class=
"form-error">
132 {{ formErrors.schedulePublicationAt }}
136 <my-peertube-checkbox inputName=
"nsfw" formControlName=
"nsfw" helpPlacement=
"bottom-right">
137 <ng-template ptTemplate=
"label">
138 <ng-container i18n
>Contains sensitive content
</ng-container>
141 <ng-template ptTemplate=
"help">
142 <ng-container i18n
>Some instances hide videos containing mature or explicit content by default.
</ng-container>
144 </my-peertube-checkbox>
146 <my-peertube-checkbox *
ngIf=
"!hideWaitTranscoding" inputName=
"waitTranscoding" formControlName=
"waitTranscoding" helpPlacement=
"bottom-right">
147 <ng-template ptTemplate=
"label">
148 <ng-container i18n
>Publish after transcoding
</ng-container>
151 <ng-template ptTemplate=
"help">
152 <ng-container i18n
>The video may be unplayable during the transcoding process. It's the reason why we prefer to publish publicly the video after transcoding.
</ng-container>
154 </my-peertube-checkbox>
157 *
ngFor=
"let pluginSetting of getPluginsFields('main')"
158 [ngTemplateOutlet]=
"pluginSettingTemplate" [ngTemplateOutletContext]=
"{ $implicit: pluginSetting }"
166 <ng-container ngbNavItem *
ngIf=
"!liveVideo">
167 <a ngbNavLink i18n
>Captions
</a>
169 <ng-template ngbNavContent
>
170 <div class=
"captions">
172 <div class=
"captions-header">
173 <button (click)=
"openAddCaptionModal()" class=
"peertube-create-button">
174 <my-global-icon iconName=
"add" aria-hidden=
"true"></my-global-icon>
175 <ng-container i18n
>Add another caption
</ng-container>
179 <div class=
"form-group" *
ngFor=
"let videoCaption of videoCaptions">
181 <div class=
"caption-entry">
182 <ng-container *
ngIf=
"!videoCaption.action">
184 i18n-title
title=
"See the subtitle file" class=
"caption-entry-label" target=
"_blank" rel=
"noopener noreferrer"
185 [href]=
"videoCaption.captionPath"
186 >{{ videoCaption.language.label }}
</a>
188 <div i18n
class=
"caption-entry-state">Already uploaded on {{ videoCaption.updatedAt | date }}
✔</div>
190 <button i18n
class=
"caption-entry-edit" (click)=
"openEditCaptionModal(videoCaption)">Edit
</button>
191 <button i18n
class=
"caption-entry-delete" (click)=
"deleteCaption(videoCaption)">Delete
</button>
194 <ng-container *
ngIf=
"videoCaption.action === 'CREATE'">
195 <span class=
"caption-entry-label">{{ videoCaption.language.label }}
</span>
197 <div i18n
class=
"caption-entry-state caption-entry-state-create">Will be created on update
</div>
199 <button i18n
class=
"caption-entry-delete" (click)=
"deleteCaption(videoCaption)">Cancel create
</button>
202 <ng-container *
ngIf=
"videoCaption.action === 'UPDATE'">
203 <span class=
"caption-entry-label">{{ videoCaption.language.label }}
</span>
205 <div i18n
class=
"caption-entry-state caption-entry-state-create">Will be edited on update
</div>
207 <button i18n
class=
"caption-entry-delete" (click)=
"deleteCaption(videoCaption)">Cancel edition
</button>
210 <ng-container *
ngIf=
"videoCaption.action === 'REMOVE'">
211 <span class=
"caption-entry-label">{{ videoCaption.language.label }}
</span>
213 <div i18n
class=
"caption-entry-state caption-entry-state-delete">Will be deleted on update
</div>
215 <button i18n
class=
"caption-entry-delete" (click)=
"deleteCaption(videoCaption)">Cancel deletion
</button>
220 <div i18n
class=
"no-caption" *
ngIf=
"videoCaptions?.length === 0">
228 <ng-container ngbNavItem *
ngIf=
"liveVideo">
229 <a ngbNavLink i18n
>Live settings
</a>
231 <ng-template ngbNavContent
>
232 <div class=
"row live-settings">
233 <div class=
"col-md-12">
234 <div class=
"alert pt-alert-primary">
235 <my-live-documentation-link></my-live-documentation-link>
238 <div *
ngIf=
"liveVideo.rtmpUrl" class=
"form-group">
239 <label for=
"liveVideoRTMPUrl" i18n
>Live RTMP Url
</label>
240 <my-input-text inputId=
"liveVideoRTMPUrl" [value]=
"liveVideo.rtmpUrl" [withToggle]=
"false" [withCopy]=
"true" [show]=
"true" [readonly]=
"true"></my-input-text>
243 <div *
ngIf=
"liveVideo.rtmpsUrl" class=
"form-group">
244 <label for=
"liveVideoRTMPSUrl" i18n
>Live RTMPS Url
</label>
245 <my-input-text inputId=
"liveVideoRTMPSUrl" [value]=
"liveVideo.rtmpsUrl" [withToggle]=
"false" [withCopy]=
"true" [show]=
"true" [readonly]=
"true"></my-input-text>
248 <div class=
"form-group">
249 <label for=
"liveVideoStreamKey" i18n
>Live stream key
</label>
250 <my-input-text inputId=
"liveVideoStreamKey" [value]=
"liveVideo.streamKey" [withCopy]=
"true" [readonly]=
"true"></my-input-text>
252 <div class=
"form-group-description" i18n
>⚠️ Never share your stream key with anyone.
</div>
255 <div class=
"form-group">
256 <div class=
"peertube-radio-container">
257 <input type=
"radio" formControlName=
"permanentLive" id=
"permanentLiveFalse" [value]=
"false">
258 <label i18n
for=
"permanentLiveFalse" class=
"radio">This is a normal live
</label>
260 <span class=
"form-group-description" i18n
>
261 You can stream only once in a normal live. If you enable replay, it will be saved under the same URL as your live
265 <div class=
"peertube-radio-container">
266 <input type=
"radio" formControlName=
"permanentLive" id=
"permanentLiveTrue" [value]=
"true">
267 <label i18n
for=
"permanentLiveTrue" class=
"radio">This is a permanent/recurring live
</label>
269 <span class=
"form-group-description" i18n
>
270 You can stream multiple times in a permanent/recurring live. If you enable replays, they will be saved as separate videos
275 <div class=
"form-group" *
ngIf=
"isSaveReplayAllowed()">
276 <my-peertube-checkbox inputName=
"liveVideoSaveReplay" formControlName=
"saveReplay">
277 <ng-template ptTemplate=
"label">
278 <ng-container i18n
>Automatically publish a replay when your live ends
</ng-container>
281 <ng-container ngProjectAs=
"description">
282 <span i18n
>⚠️ If you enable this option, your live will be terminated if you exceed your video quota
</span>
284 </my-peertube-checkbox>
287 <div class=
"form-group mx-4" *
ngIf=
"isSaveReplayEnabled()">
288 <label i18n
for=
"replayPrivacy">Privacy of the new replay
</label>
290 labelForId=
"replayPrivacy" [items]=
"videoPrivacies" [clearable]=
"false" formControlName=
"replayPrivacy"
291 ></my-select-options>
294 <div class=
"form-group" *
ngIf=
"isLatencyModeEnabled()">
295 <label i18n
for=
"latencyMode">Latency mode
</label>
297 labelForId=
"latencyMode" [items]=
"latencyModes" formControlName=
"latencyMode" [clearable]=
"true"
298 ></my-select-options>
300 <div *
ngIf=
"formErrors.latencyMode" class=
"form-error">
301 {{ formErrors.latencyMode }}
311 <ng-container ngbNavItem
>
312 <a ngbNavLink i18n
>Advanced settings
</a>
314 <ng-template ngbNavContent
>
315 <div class=
"row advanced-settings">
316 <div class=
"col-md-12 col-xl-8">
318 <div class=
"form-group">
319 <label i18n
for=
"previewfile">Video thumbnail
</label>
322 i18n-inputLabel
inputLabel=
"Edit" inputName=
"previewfile" formControlName=
"previewfile"
323 previewWidth=
"360px" previewHeight=
"200px"
324 ></my-preview-upload>
327 <div class=
"form-group">
328 <label i18n
for=
"support">Support
</label>
329 <my-help helpType=
"markdownEnhanced">
330 <ng-template ptTemplate=
"preHtml">
332 Short text to tell people how they can support you (membership platform...).
337 <my-markdown-textarea
338 id=
"support" formControlName=
"support" markdownType=
"enhanced"
339 [formError]=
"formErrors['support']"
340 ></my-markdown-textarea>
344 <div class=
"col-md-12 col-xl-4">
346 <div *
ngIf=
"videoSource" class=
"form-group">
347 <label i18n
for=
"filename">Filename
</label>
350 <ng-template ptTemplate=
"preHtml">
352 Name of the uploaded file
357 <input type=
"text" [disabled]=
"true" id=
"filename" class=
"form-control" [value]=
"videoSource.filename" />
360 <div class=
"form-group originally-published-at">
361 <label i18n
for=
"originallyPublishedAt">Original publication date
</label>
363 <ng-template ptTemplate=
"preHtml">
365 This is the date when the content was originally published (e.g. the release date for a film)
370 id=
"originallyPublishedAt" formControlName=
"originallyPublishedAt" [dateFormat]=
"calendarDateFormat" [firstDayOfWeek]=
"0"
371 [showTime]=
"true" [hideOnDateTimeSelect]=
"true" [monthNavigator]=
"true" [yearNavigator]=
"true" [yearRange]=
"myYearRange"
375 <div *
ngIf=
"formErrors.originallyPublishedAt" class=
"form-error">
376 {{ formErrors.originallyPublishedAt }}
380 <my-peertube-checkbox
381 inputName=
"commentsEnabled" formControlName=
"commentsEnabled"
382 i18n-labelText
labelText=
"Enable video comments"
383 ></my-peertube-checkbox>
385 <my-peertube-checkbox
386 inputName=
"downloadEnabled" formControlName=
"downloadEnabled"
387 i18n-labelText
labelText=
"Enable download"
388 ></my-peertube-checkbox>
394 <ng-container ngbNavItem *
ngIf=
"getPluginsFields('plugin-settings').length !== 0">
395 <a ngbNavLink i18n
>Plugin settings
</a>
397 <ng-template ngbNavContent
>
398 <div class=
"row plugin-settings">
400 <div class=
"col-md-12 col-xl-8">
402 *
ngFor=
"let pluginSetting of getPluginsFields('plugin-settings')"
403 [ngTemplateOutlet]=
"pluginSettingTemplate" [ngTemplateOutletContext]=
"{ $implicit: pluginSetting }"
413 <div [ngbNavOutlet]=
"nav"></div>
416 <my-video-caption-add-modal
417 #videoCaptionAddModal [existingCaptions]=
"getExistingCaptions()" [serverConfig]=
"serverConfig" (captionAdded)=
"onCaptionEdited($event)"
418 ></my-video-caption-add-modal>