Rename studio to editor
This commit is contained in:
parent
1808a1f8e4
commit
92e66e04f7
|
@ -200,7 +200,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
|||
resolutions: {}
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: null
|
||||
},
|
||||
autoBlacklist: {
|
||||
|
|
|
@ -193,9 +193,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row mt-2"> <!-- video editor grid -->
|
||||
<div class="form-row mt-2"> <!-- video studio grid -->
|
||||
<div class="form-group col-12 col-lg-4 col-xl-3">
|
||||
<div i18n class="inner-form-title">VIDEO EDITOR</div>
|
||||
<div i18n class="inner-form-title">VIDEO STUDIO</div>
|
||||
<div i18n class="inner-form-description">
|
||||
Allows your users to edit their video (cut, add intro/outro, add a watermark etc)
|
||||
</div>
|
||||
|
@ -203,14 +203,14 @@
|
|||
|
||||
<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
|
||||
|
||||
<ng-container formGroupName="videoEditor">
|
||||
<ng-container formGroupName="videoStudio">
|
||||
<div class="form-group" [ngClass]="getTranscodingDisabledClass()">
|
||||
<my-peertube-checkbox
|
||||
inputName="videoEditorEnabled" formControlName="enabled"
|
||||
i18n-labelText labelText="Enable video editor"
|
||||
inputName="videoStudioEnabled" formControlName="enabled"
|
||||
i18n-labelText labelText="Enable video studio"
|
||||
>
|
||||
<ng-container ngProjectAs="description" *ngIf="!isTranscodingEnabled()">
|
||||
<span i18n>⚠️ You need to enable transcoding first to enable video editor</span>
|
||||
<span i18n>⚠️ You need to enable transcoding first to enable video studio</span>
|
||||
</ng-container>
|
||||
</my-peertube-checkbox>
|
||||
</div>
|
||||
|
|
|
@ -72,7 +72,7 @@ export class EditVODTranscodingComponent implements OnInit, OnChanges {
|
|||
|
||||
private checkTranscodingFields () {
|
||||
const transcodingControl = this.form.get('transcoding.enabled')
|
||||
const videoEditorControl = this.form.get('videoEditor.enabled')
|
||||
const videoStudioControl = this.form.get('videoStudio.enabled')
|
||||
const hlsControl = this.form.get('transcoding.hls.enabled')
|
||||
const webtorrentControl = this.form.get('transcoding.webtorrent.enabled')
|
||||
|
||||
|
@ -101,7 +101,7 @@ export class EditVODTranscodingComponent implements OnInit, OnChanges {
|
|||
transcodingControl.valueChanges
|
||||
.subscribe(newValue => {
|
||||
if (newValue === false) {
|
||||
videoEditorControl.setValue(false)
|
||||
videoStudioControl.setValue(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
|
|||
abuseStateChange: $localize`One of your abuse reports has been accepted or rejected by moderators`,
|
||||
newPeerTubeVersion: $localize`A new PeerTube version is available`,
|
||||
newPluginVersion: $localize`One of your plugin/theme has a new available version`,
|
||||
myVideoEditionFinished: $localize`Video edition finished`
|
||||
myVideoStudioEditionFinished: $localize`Video studio edition has finished`
|
||||
}
|
||||
this.notificationSettingGroups = [
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
|
|||
'blacklistOnMyVideo',
|
||||
'myVideoPublished',
|
||||
'myVideoImportFinished',
|
||||
'myVideoEditionFinished'
|
||||
'myVideoStudioEditionFinished'
|
||||
]
|
||||
},
|
||||
|
||||
|
|
|
@ -205,9 +205,9 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
|
|||
private buildActions () {
|
||||
this.videoActions = [
|
||||
{
|
||||
label: $localize`Editor`,
|
||||
linkBuilder: ({ video }) => [ '/video-editor/edit', video.uuid ],
|
||||
isDisplayed: ({ video }) => video.isEditableBy(this.authService.getUser(), this.serverService.getHTMLConfig().videoEditor.enabled),
|
||||
label: $localize`Studio`,
|
||||
linkBuilder: ({ video }) => [ '/studio/edit', video.uuid ],
|
||||
isDisplayed: ({ video }) => video.isEditableBy(this.authService.getUser(), this.serverService.getHTMLConfig().videoStudio.enabled),
|
||||
iconName: 'film'
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
export * from './video-editor-edit.component'
|
||||
export * from './video-editor-edit.resolver'
|
|
@ -1 +0,0 @@
|
|||
export * from './video-editor.module'
|
|
@ -1 +0,0 @@
|
|||
export * from './video-editor.service'
|
|
@ -1,30 +0,0 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { VideoEditorEditResolver } from './edit'
|
||||
import { VideoEditorEditComponent } from './edit/video-editor-edit.component'
|
||||
|
||||
const videoEditorRoutes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
children: [
|
||||
{
|
||||
path: 'edit/:videoId',
|
||||
component: VideoEditorEditComponent,
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Edit video`
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
video: VideoEditorEditResolver
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forChild(videoEditorRoutes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class VideoEditorRoutingModule {}
|
|
@ -1,27 +0,0 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { VideoEditorEditComponent, VideoEditorEditResolver } from './edit'
|
||||
import { VideoEditorService } from './shared'
|
||||
import { VideoEditorRoutingModule } from './video-editor-routing.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
VideoEditorRoutingModule,
|
||||
|
||||
SharedMainModule,
|
||||
SharedFormModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
VideoEditorEditComponent
|
||||
],
|
||||
|
||||
exports: [],
|
||||
|
||||
providers: [
|
||||
VideoEditorService,
|
||||
VideoEditorEditResolver
|
||||
]
|
||||
})
|
||||
export class VideoEditorModule { }
|
|
@ -0,0 +1,2 @@
|
|||
export * from './video-studio-edit.component'
|
||||
export * from './video-studio-edit.resolver'
|
|
@ -1,5 +1,5 @@
|
|||
<div class="margin-content">
|
||||
<h1 class="title-page title-page-single" i18n>Edit {{ video.name }}</h1>
|
||||
<h1 class="title-page title-page-single" i18n>Studio for {{ video.name }}</h1>
|
||||
|
||||
<div class="columns">
|
||||
<form role="form" [formGroup]="form">
|
|
@ -2,18 +2,18 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { ConfirmService, Notifier, ServerService } from '@app/core'
|
||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||
import { Video, VideoDetails } from '@app/shared/shared-main'
|
||||
import { VideoDetails } from '@app/shared/shared-main'
|
||||
import { LoadingBarService } from '@ngx-loading-bar/core'
|
||||
import { secondsToTime } from '@shared/core-utils'
|
||||
import { VideoEditorTask, VideoEditorTaskCut } from '@shared/models'
|
||||
import { VideoEditorService } from '../shared'
|
||||
import { VideoStudioTask, VideoStudioTaskCut } from '@shared/models'
|
||||
import { VideoStudioService } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-editor-edit',
|
||||
templateUrl: './video-editor-edit.component.html',
|
||||
styleUrls: [ './video-editor-edit.component.scss' ]
|
||||
selector: 'my-video-studio-edit',
|
||||
templateUrl: './video-studio-edit.component.html',
|
||||
styleUrls: [ './video-studio-edit.component.scss' ]
|
||||
})
|
||||
export class VideoEditorEditComponent extends FormReactive implements OnInit {
|
||||
export class VideoStudioEditComponent extends FormReactive implements OnInit {
|
||||
isRunningEdition = false
|
||||
|
||||
video: VideoDetails
|
||||
|
@ -24,7 +24,7 @@ export class VideoEditorEditComponent extends FormReactive implements OnInit {
|
|||
private notifier: Notifier,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private videoEditorService: VideoEditorService,
|
||||
private videoStudioService: VideoStudioService,
|
||||
private loadingBar: LoadingBarService,
|
||||
private confirmService: ConfirmService
|
||||
) {
|
||||
|
@ -84,11 +84,13 @@ export class VideoEditorEditComponent extends FormReactive implements OnInit {
|
|||
|
||||
this.loadingBar.useRef().start()
|
||||
|
||||
return this.videoEditorService.editVideo(this.video.uuid, tasks)
|
||||
return this.videoStudioService.editVideo(this.video.uuid, tasks)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.notifier.success($localize`Video updated.`)
|
||||
this.router.navigateByUrl(Video.buildWatchUrl(this.video))
|
||||
this.notifier.success($localize`Edition tasks created.`)
|
||||
|
||||
// Don't redirect to old video version watch page that could be confusing for users
|
||||
this.router.navigateByUrl('/my-library/videos')
|
||||
},
|
||||
|
||||
error: err => {
|
||||
|
@ -153,13 +155,13 @@ export class VideoEditorEditComponent extends FormReactive implements OnInit {
|
|||
}
|
||||
|
||||
private buildTasks () {
|
||||
const tasks: VideoEditorTask[] = []
|
||||
const tasks: VideoStudioTask[] = []
|
||||
const value = this.form.value
|
||||
|
||||
const cut = value['cut']
|
||||
if (cut['start'] !== 0 || cut['end'] !== this.video.duration) {
|
||||
|
||||
const options: VideoEditorTaskCut['options'] = {}
|
||||
const options: VideoStudioTaskCut['options'] = {}
|
||||
if (cut['start'] !== 0) options.start = cut['start']
|
||||
if (cut['end'] !== this.video.duration) options.end = cut['end']
|
||||
|
|
@ -4,7 +4,7 @@ import { ActivatedRouteSnapshot, Resolve } from '@angular/router'
|
|||
import { VideoService } from '@app/shared/shared-main'
|
||||
|
||||
@Injectable()
|
||||
export class VideoEditorEditResolver implements Resolve<any> {
|
||||
export class VideoStudioEditResolver implements Resolve<any> {
|
||||
constructor (
|
||||
private videoService: VideoService
|
||||
) {
|
|
@ -0,0 +1 @@
|
|||
export * from './video-studio.module'
|
|
@ -0,0 +1 @@
|
|||
export * from './video-studio.service'
|
|
@ -4,19 +4,19 @@ import { Injectable } from '@angular/core'
|
|||
import { RestExtractor } from '@app/core'
|
||||
import { objectToFormData } from '@app/helpers'
|
||||
import { VideoService } from '@app/shared/shared-main'
|
||||
import { VideoEditorCreateEdition, VideoEditorTask } from '@shared/models'
|
||||
import { VideoStudioCreateEdition, VideoStudioTask } from '@shared/models'
|
||||
|
||||
@Injectable()
|
||||
export class VideoEditorService {
|
||||
export class VideoStudioService {
|
||||
|
||||
constructor (
|
||||
private authHttp: HttpClient,
|
||||
private restExtractor: RestExtractor
|
||||
) {}
|
||||
|
||||
editVideo (videoId: number | string, tasks: VideoEditorTask[]) {
|
||||
const url = VideoService.BASE_VIDEO_URL + '/' + videoId + '/editor/edit'
|
||||
const body: VideoEditorCreateEdition = {
|
||||
editVideo (videoId: number | string, tasks: VideoStudioTask[]) {
|
||||
const url = VideoService.BASE_VIDEO_URL + '/' + videoId + '/studio/edit'
|
||||
const body: VideoStudioCreateEdition = {
|
||||
tasks
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { VideoStudioEditComponent, VideoStudioEditResolver } from './edit'
|
||||
|
||||
const videoStudioRoutes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
children: [
|
||||
{
|
||||
path: 'edit/:videoId',
|
||||
component: VideoStudioEditComponent,
|
||||
data: {
|
||||
meta: {
|
||||
title: $localize`Studio`
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
video: VideoStudioEditResolver
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forChild(videoStudioRoutes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class VideoStudioRoutingModule {}
|
|
@ -0,0 +1,27 @@
|
|||
import { NgModule } from '@angular/core'
|
||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||
import { SharedMainModule } from '@app/shared/shared-main'
|
||||
import { VideoStudioEditComponent, VideoStudioEditResolver } from './edit'
|
||||
import { VideoStudioService } from './shared'
|
||||
import { VideoStudioRoutingModule } from './video-studio-routing.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
VideoStudioRoutingModule,
|
||||
|
||||
SharedMainModule,
|
||||
SharedFormModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
VideoStudioEditComponent
|
||||
],
|
||||
|
||||
exports: [],
|
||||
|
||||
providers: [
|
||||
VideoStudioService,
|
||||
VideoStudioEditResolver
|
||||
]
|
||||
})
|
||||
export class VideoStudioModule { }
|
|
@ -35,7 +35,7 @@ export class ActionButtonsComponent implements OnInit, OnChanges {
|
|||
playlist: false,
|
||||
download: true,
|
||||
update: true,
|
||||
editor: true,
|
||||
studio: true,
|
||||
blacklist: true,
|
||||
delete: true,
|
||||
report: true,
|
||||
|
|
|
@ -144,8 +144,8 @@ const routes: Routes = [
|
|||
},
|
||||
|
||||
{
|
||||
path: 'video-editor',
|
||||
loadChildren: () => import('./+video-editor/video-editor.module').then(m => m.VideoEditorModule),
|
||||
path: 'studio',
|
||||
loadChildren: () => import('./+video-studio/video-studio.module').then(m => m.VideoStudioModule),
|
||||
canActivateChild: [ MetaGuard ]
|
||||
},
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ export class UserNotification implements UserNotificationServer {
|
|||
this.pluginQueryParams.pluginType = this.plugin.type + ''
|
||||
break
|
||||
|
||||
case UserNotificationType.MY_VIDEO_EDITION_FINISHED:
|
||||
case UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED:
|
||||
this.videoUrl = this.buildVideoUrl(this.video)
|
||||
break
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="19"> <!-- UserNotificationType.MY_VIDEO_EDITION_FINISHED -->
|
||||
<ng-container *ngSwitchCase="19"> <!-- UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED -->
|
||||
<my-global-icon iconName="film" aria-hidden="true"></my-global-icon>
|
||||
|
||||
<div class="message" i18n>
|
||||
|
|
|
@ -228,8 +228,8 @@ export class Video implements VideoServerModel {
|
|||
return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO))
|
||||
}
|
||||
|
||||
isEditableBy (user: AuthUser, videoEditorEnabled: boolean) {
|
||||
return videoEditorEnabled &&
|
||||
isEditableBy (user: AuthUser, videoStudioEnabled: boolean) {
|
||||
return videoStudioEnabled &&
|
||||
this.state?.id === VideoState.PUBLISHED &&
|
||||
this.isUpdatableBy(user)
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export type VideoActionsDisplayType = {
|
|||
liveInfo?: boolean
|
||||
removeFiles?: boolean
|
||||
transcoding?: boolean
|
||||
editor?: boolean
|
||||
studio?: boolean
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -61,7 +61,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
|
|||
liveInfo: false,
|
||||
removeFiles: false,
|
||||
transcoding: false,
|
||||
editor: true
|
||||
studio: true
|
||||
}
|
||||
@Input() placement = 'left'
|
||||
|
||||
|
@ -153,7 +153,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
|
|||
}
|
||||
|
||||
isVideoEditable () {
|
||||
return this.video.isEditableBy(this.user, this.serverService.getHTMLConfig().videoEditor.enabled)
|
||||
return this.video.isEditableBy(this.user, this.serverService.getHTMLConfig().videoStudio.enabled)
|
||||
}
|
||||
|
||||
isVideoRemovable () {
|
||||
|
@ -337,10 +337,10 @@ export class VideoActionsDropdownComponent implements OnChanges {
|
|||
isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable()
|
||||
},
|
||||
{
|
||||
label: $localize`Editor`,
|
||||
linkBuilder: ({ video }) => [ '/video-editor/edit', video.uuid ],
|
||||
label: $localize`Studio`,
|
||||
linkBuilder: ({ video }) => [ '/studio/edit', video.uuid ],
|
||||
iconName: 'film',
|
||||
isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.editor && this.isVideoEditable()
|
||||
isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.studio && this.isVideoEditable()
|
||||
},
|
||||
{
|
||||
label: $localize`Block`,
|
||||
|
|
|
@ -436,7 +436,7 @@ live:
|
|||
1440p: false
|
||||
2160p: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
# Enable video edition by users (cut, add intro/outro, add watermark etc)
|
||||
enabled: false
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ live:
|
|||
1440p: false
|
||||
2160p: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
# Enable video edition by users (cut, add intro/outro, add watermark etc)
|
||||
enabled: false
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ signup:
|
|||
transcoding:
|
||||
enabled: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: false
|
||||
|
||||
live:
|
||||
|
|
|
@ -31,5 +31,5 @@ admin:
|
|||
transcoding:
|
||||
enabled: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: false
|
||||
|
|
|
@ -31,5 +31,5 @@ admin:
|
|||
transcoding:
|
||||
enabled: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: false
|
||||
|
|
|
@ -31,5 +31,5 @@ admin:
|
|||
transcoding:
|
||||
enabled: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: false
|
||||
|
|
|
@ -31,5 +31,5 @@ admin:
|
|||
transcoding:
|
||||
enabled: false
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: false
|
||||
|
|
|
@ -168,5 +168,5 @@ views:
|
|||
local_buffer_update_interval: '5 seconds'
|
||||
ip_view_expiration: '1 second'
|
||||
|
||||
video_editor:
|
||||
video_studio:
|
||||
enabled: true
|
||||
|
|
|
@ -259,8 +259,8 @@ function customConfig (): CustomConfig {
|
|||
}
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
enabled: CONFIG.VIDEO_EDITOR.ENABLED
|
||||
videoStudio: {
|
||||
enabled: CONFIG.VIDEO_STUDIO.ENABLED
|
||||
},
|
||||
import: {
|
||||
videos: {
|
||||
|
|
|
@ -83,7 +83,7 @@ async function updateNotificationSettings (req: express.Request, res: express.Re
|
|||
abuseStateChange: body.abuseStateChange,
|
||||
newPeerTubeVersion: body.newPeerTubeVersion,
|
||||
newPluginVersion: body.newPluginVersion,
|
||||
myVideoEditionFinished: body.myVideoEditionFinished
|
||||
myVideoStudioEditionFinished: body.myVideoStudioEditionFinished
|
||||
}
|
||||
|
||||
await UserNotificationSettingModel.update(values, query)
|
||||
|
|
|
@ -35,7 +35,7 @@ import { VideoModel } from '../../../models/video/video'
|
|||
import { blacklistRouter } from './blacklist'
|
||||
import { videoCaptionsRouter } from './captions'
|
||||
import { videoCommentRouter } from './comment'
|
||||
import { editorRouter } from './editor'
|
||||
import { studioRouter } from './studio'
|
||||
import { filesRouter } from './files'
|
||||
import { videoImportsRouter } from './import'
|
||||
import { liveRouter } from './live'
|
||||
|
@ -52,7 +52,7 @@ const videosRouter = express.Router()
|
|||
videosRouter.use('/', blacklistRouter)
|
||||
videosRouter.use('/', rateVideoRouter)
|
||||
videosRouter.use('/', videoCommentRouter)
|
||||
videosRouter.use('/', editorRouter)
|
||||
videosRouter.use('/', studioRouter)
|
||||
videosRouter.use('/', videoCaptionsRouter)
|
||||
videosRouter.use('/', videoImportsRouter)
|
||||
videosRouter.use('/', ownershipVideoRouter)
|
||||
|
|
|
@ -2,26 +2,26 @@ import express from 'express'
|
|||
import { createAnyReqFiles } from '@server/helpers/express-utils'
|
||||
import { MIMETYPES } from '@server/initializers/constants'
|
||||
import { JobQueue } from '@server/lib/job-queue'
|
||||
import { buildTaskFileFieldname, getTaskFile } from '@server/lib/video-editor'
|
||||
import { buildTaskFileFieldname, getTaskFile } from '@server/lib/video-studio'
|
||||
import {
|
||||
HttpStatusCode,
|
||||
VideoEditionTaskPayload,
|
||||
VideoEditorCreateEdition,
|
||||
VideoEditorTask,
|
||||
VideoEditorTaskCut,
|
||||
VideoEditorTaskIntro,
|
||||
VideoEditorTaskOutro,
|
||||
VideoEditorTaskWatermark,
|
||||
VideoState
|
||||
VideoState,
|
||||
VideoStudioCreateEdition,
|
||||
VideoStudioTask,
|
||||
VideoStudioTaskCut,
|
||||
VideoStudioTaskIntro,
|
||||
VideoStudioTaskOutro,
|
||||
VideoStudioTaskPayload,
|
||||
VideoStudioTaskWatermark
|
||||
} from '@shared/models'
|
||||
import { asyncMiddleware, authenticate, videosEditorAddEditionValidator } from '../../../middlewares'
|
||||
import { asyncMiddleware, authenticate, videoStudioAddEditionValidator } from '../../../middlewares'
|
||||
|
||||
const editorRouter = express.Router()
|
||||
const studioRouter = express.Router()
|
||||
|
||||
const tasksFiles = createAnyReqFiles(
|
||||
MIMETYPES.VIDEO.MIMETYPE_EXT,
|
||||
(req: express.Request, file: Express.Multer.File, cb: (err: Error, result?: boolean) => void) => {
|
||||
const body = req.body as VideoEditorCreateEdition
|
||||
const body = req.body as VideoStudioCreateEdition
|
||||
|
||||
// Fetch array element
|
||||
const matches = file.fieldname.match(/tasks\[(\d+)\]/)
|
||||
|
@ -43,24 +43,24 @@ const tasksFiles = createAnyReqFiles(
|
|||
}
|
||||
)
|
||||
|
||||
editorRouter.post('/:videoId/editor/edit',
|
||||
studioRouter.post('/:videoId/studio/edit',
|
||||
authenticate,
|
||||
tasksFiles,
|
||||
asyncMiddleware(videosEditorAddEditionValidator),
|
||||
asyncMiddleware(videoStudioAddEditionValidator),
|
||||
asyncMiddleware(createEditionTasks)
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
editorRouter
|
||||
studioRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function createEditionTasks (req: express.Request, res: express.Response) {
|
||||
const files = req.files as Express.Multer.File[]
|
||||
const body = req.body as VideoEditorCreateEdition
|
||||
const body = req.body as VideoStudioCreateEdition
|
||||
const video = res.locals.videoAll
|
||||
|
||||
video.state = VideoState.TO_EDIT
|
||||
|
@ -71,13 +71,13 @@ async function createEditionTasks (req: express.Request, res: express.Response)
|
|||
tasks: body.tasks.map((t, i) => buildTaskPayload(t, i, files))
|
||||
}
|
||||
|
||||
JobQueue.Instance.createJob({ type: 'video-edition', payload })
|
||||
JobQueue.Instance.createJob({ type: 'video-studio-edition', payload })
|
||||
|
||||
return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
|
||||
}
|
||||
|
||||
const taskPayloadBuilders: {
|
||||
[id in VideoEditorTask['name']]: (task: VideoEditorTask, indice?: number, files?: Express.Multer.File[]) => VideoEditionTaskPayload
|
||||
[id in VideoStudioTask['name']]: (task: VideoStudioTask, indice?: number, files?: Express.Multer.File[]) => VideoStudioTaskPayload
|
||||
} = {
|
||||
'add-intro': buildIntroOutroTask,
|
||||
'add-outro': buildIntroOutroTask,
|
||||
|
@ -85,11 +85,11 @@ const taskPayloadBuilders: {
|
|||
'add-watermark': buildWatermarkTask
|
||||
}
|
||||
|
||||
function buildTaskPayload (task: VideoEditorTask, indice: number, files: Express.Multer.File[]): VideoEditionTaskPayload {
|
||||
function buildTaskPayload (task: VideoStudioTask, indice: number, files: Express.Multer.File[]): VideoStudioTaskPayload {
|
||||
return taskPayloadBuilders[task.name](task, indice, files)
|
||||
}
|
||||
|
||||
function buildIntroOutroTask (task: VideoEditorTaskIntro | VideoEditorTaskOutro, indice: number, files: Express.Multer.File[]) {
|
||||
function buildIntroOutroTask (task: VideoStudioTaskIntro | VideoStudioTaskOutro, indice: number, files: Express.Multer.File[]) {
|
||||
return {
|
||||
name: task.name,
|
||||
options: {
|
||||
|
@ -98,7 +98,7 @@ function buildIntroOutroTask (task: VideoEditorTaskIntro | VideoEditorTaskOutro,
|
|||
}
|
||||
}
|
||||
|
||||
function buildCutTask (task: VideoEditorTaskCut) {
|
||||
function buildCutTask (task: VideoStudioTaskCut) {
|
||||
return {
|
||||
name: task.name,
|
||||
options: {
|
||||
|
@ -108,7 +108,7 @@ function buildCutTask (task: VideoEditorTaskCut) {
|
|||
}
|
||||
}
|
||||
|
||||
function buildWatermarkTask (task: VideoEditorTaskWatermark, indice: number, files: Express.Multer.File[]) {
|
||||
function buildWatermarkTask (task: VideoStudioTaskWatermark, indice: number, files: Express.Multer.File[]) {
|
||||
return {
|
||||
name: task.name,
|
||||
options: {
|
|
@ -1,40 +1,40 @@
|
|||
import validator from 'validator'
|
||||
import { CONSTRAINTS_FIELDS } from '@server/initializers/constants'
|
||||
import { buildTaskFileFieldname } from '@server/lib/video-editor'
|
||||
import { VideoEditorTask } from '@shared/models'
|
||||
import { buildTaskFileFieldname } from '@server/lib/video-studio'
|
||||
import { VideoStudioTask } from '@shared/models'
|
||||
import { isArray } from './misc'
|
||||
import { isVideoFileMimeTypeValid, isVideoImageValid } from './videos'
|
||||
|
||||
function isValidEditorTasksArray (tasks: any) {
|
||||
function isValidStudioTasksArray (tasks: any) {
|
||||
if (!isArray(tasks)) return false
|
||||
|
||||
return tasks.length >= CONSTRAINTS_FIELDS.VIDEO_EDITOR.TASKS.min &&
|
||||
tasks.length <= CONSTRAINTS_FIELDS.VIDEO_EDITOR.TASKS.max
|
||||
return tasks.length >= CONSTRAINTS_FIELDS.VIDEO_STUDIO.TASKS.min &&
|
||||
tasks.length <= CONSTRAINTS_FIELDS.VIDEO_STUDIO.TASKS.max
|
||||
}
|
||||
|
||||
function isEditorCutTaskValid (task: VideoEditorTask) {
|
||||
function isStudioCutTaskValid (task: VideoStudioTask) {
|
||||
if (task.name !== 'cut') return false
|
||||
if (!task.options) return false
|
||||
|
||||
const { start, end } = task.options
|
||||
if (!start && !end) return false
|
||||
|
||||
if (start && !validator.isInt(start + '', CONSTRAINTS_FIELDS.VIDEO_EDITOR.CUT_TIME)) return false
|
||||
if (end && !validator.isInt(end + '', CONSTRAINTS_FIELDS.VIDEO_EDITOR.CUT_TIME)) return false
|
||||
if (start && !validator.isInt(start + '', CONSTRAINTS_FIELDS.VIDEO_STUDIO.CUT_TIME)) return false
|
||||
if (end && !validator.isInt(end + '', CONSTRAINTS_FIELDS.VIDEO_STUDIO.CUT_TIME)) return false
|
||||
|
||||
if (!start || !end) return true
|
||||
|
||||
return parseInt(start + '') < parseInt(end + '')
|
||||
}
|
||||
|
||||
function isEditorTaskAddIntroOutroValid (task: VideoEditorTask, indice: number, files: Express.Multer.File[]) {
|
||||
function isStudioTaskAddIntroOutroValid (task: VideoStudioTask, indice: number, files: Express.Multer.File[]) {
|
||||
const file = files.find(f => f.fieldname === buildTaskFileFieldname(indice, 'file'))
|
||||
|
||||
return (task.name === 'add-intro' || task.name === 'add-outro') &&
|
||||
file && isVideoFileMimeTypeValid([ file ], null)
|
||||
}
|
||||
|
||||
function isEditorTaskAddWatermarkValid (task: VideoEditorTask, indice: number, files: Express.Multer.File[]) {
|
||||
function isStudioTaskAddWatermarkValid (task: VideoStudioTask, indice: number, files: Express.Multer.File[]) {
|
||||
const file = files.find(f => f.fieldname === buildTaskFileFieldname(indice, 'file'))
|
||||
|
||||
return task.name === 'add-watermark' &&
|
||||
|
@ -44,9 +44,9 @@ function isEditorTaskAddWatermarkValid (task: VideoEditorTask, indice: number, f
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
isValidEditorTasksArray,
|
||||
isValidStudioTasksArray,
|
||||
|
||||
isEditorCutTaskValid,
|
||||
isEditorTaskAddIntroOutroValid,
|
||||
isEditorTaskAddWatermarkValid
|
||||
isStudioCutTaskValid,
|
||||
isStudioTaskAddIntroOutroValid,
|
||||
isStudioTaskAddWatermarkValid
|
||||
}
|
|
@ -49,7 +49,7 @@ function checkConfig () {
|
|||
checkSearchConfig()
|
||||
checkLiveConfig()
|
||||
checkObjectStorageConfig()
|
||||
checkVideoEditorConfig()
|
||||
checkVideoStudioConfig()
|
||||
}
|
||||
|
||||
// We get db by param to not import it in this file (import orders)
|
||||
|
@ -260,8 +260,8 @@ function checkObjectStorageConfig () {
|
|||
}
|
||||
}
|
||||
|
||||
function checkVideoEditorConfig () {
|
||||
if (CONFIG.VIDEO_EDITOR.ENABLED === true && CONFIG.TRANSCODING.ENABLED === false) {
|
||||
throw new Error('Video editor cannot be enabled if transcoding is disabled')
|
||||
function checkVideoStudioConfig () {
|
||||
if (CONFIG.VIDEO_STUDIO.ENABLED === true && CONFIG.TRANSCODING.ENABLED === false) {
|
||||
throw new Error('Video studio cannot be enabled if transcoding is disabled')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ function checkMissedConfig () {
|
|||
'transcoding.profile', 'transcoding.concurrency',
|
||||
'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', 'video_editor.enabled',
|
||||
'transcoding.resolutions.2160p', 'video_studio.enabled',
|
||||
'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'auto_blacklist.videos.of_users.enabled',
|
||||
'trending.videos.interval_days',
|
||||
'client.videos.miniature.display_author_avatar',
|
||||
|
|
|
@ -335,8 +335,8 @@ const CONFIG = {
|
|||
}
|
||||
}
|
||||
},
|
||||
VIDEO_EDITOR: {
|
||||
get ENABLED () { return config.get<boolean>('video_editor.enabled') }
|
||||
VIDEO_STUDIO: {
|
||||
get ENABLED () { return config.get<boolean>('video_studio.enabled') }
|
||||
},
|
||||
IMPORT: {
|
||||
VIDEOS: {
|
||||
|
|
|
@ -152,7 +152,7 @@ const JOB_ATTEMPTS: { [id in JobType]: number } = {
|
|||
'activitypub-refresher': 1,
|
||||
'video-redundancy': 1,
|
||||
'video-live-ending': 1,
|
||||
'video-edition': 1,
|
||||
'video-studio-edition': 1,
|
||||
'manage-video-torrent': 1,
|
||||
'move-to-object-storage': 3
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-im
|
|||
'activitypub-refresher': 1,
|
||||
'video-redundancy': 1,
|
||||
'video-live-ending': 10,
|
||||
'video-edition': 1,
|
||||
'video-studio-edition': 1,
|
||||
'manage-video-torrent': 1,
|
||||
'move-to-object-storage': 1
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ const JOB_TTL: { [id in JobType]: number } = {
|
|||
'activitypub-cleaner': 1000 * 3600, // 1 hour
|
||||
'video-file-import': 1000 * 3600, // 1 hour
|
||||
'video-transcoding': 1000 * 3600 * 48, // 2 days, transcoding could be long
|
||||
'video-edition': 1000 * 3600 * 10, // 10 hours
|
||||
'video-studio-edition': 1000 * 3600 * 10, // 10 hours
|
||||
'video-import': 1000 * 3600 * 2, // 2 hours
|
||||
'email': 60000 * 10, // 10 minutes
|
||||
'actor-keys': 60000 * 20, // 20 minutes
|
||||
|
@ -358,7 +358,7 @@ const CONSTRAINTS_FIELDS = {
|
|||
COMMONS: {
|
||||
URL: { min: 5, max: 2000 } // Length
|
||||
},
|
||||
VIDEO_EDITOR: {
|
||||
VIDEO_STUDIO: {
|
||||
TASKS: { min: 1, max: 10 }, // Number of tasks
|
||||
CUT_TIME: { min: 0 } // Value
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ async function up (utils: {
|
|||
defaultValue: null,
|
||||
allowNull: true
|
||||
}
|
||||
await utils.queryInterface.addColumn('userNotificationSetting', 'myVideoEditionFinished', data, { transaction })
|
||||
await utils.queryInterface.addColumn('userNotificationSetting', 'myVideoStudioEditionFinished', data, { transaction })
|
||||
}
|
||||
|
||||
{
|
||||
const query = 'UPDATE "userNotificationSetting" SET "myVideoEditionFinished" = 1'
|
||||
const query = 'UPDATE "userNotificationSetting" SET "myVideoStudioEditionFinished" = 1'
|
||||
await utils.sequelize.query(query, { transaction })
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ async function up (utils: {
|
|||
defaultValue: null,
|
||||
allowNull: false
|
||||
}
|
||||
await utils.queryInterface.changeColumn('userNotificationSetting', 'myVideoEditionFinished', data, { transaction })
|
||||
await utils.queryInterface.changeColumn('userNotificationSetting', 'myVideoStudioEditionFinished', data, { transaction })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import { generateWebTorrentVideoFilename } from '@server/lib/paths'
|
|||
import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles'
|
||||
import { isAbleToUploadVideo } from '@server/lib/user'
|
||||
import { addOptimizeOrMergeAudioJob } from '@server/lib/video'
|
||||
import { approximateIntroOutroAdditionalSize } from '@server/lib/video-editor'
|
||||
import { VideoPathManager } from '@server/lib/video-path-manager'
|
||||
import { approximateIntroOutroAdditionalSize } from '@server/lib/video-studio'
|
||||
import { UserModel } from '@server/models/user/user'
|
||||
import { VideoModel } from '@server/models/video/video'
|
||||
import { VideoFileModel } from '@server/models/video/video-file'
|
||||
|
@ -26,23 +26,23 @@ import {
|
|||
getVideoStreamFPS
|
||||
} from '@shared/extra-utils'
|
||||
import {
|
||||
VideoEditionPayload,
|
||||
VideoEditionTaskPayload,
|
||||
VideoEditorTask,
|
||||
VideoEditorTaskCutPayload,
|
||||
VideoEditorTaskIntroPayload,
|
||||
VideoEditorTaskOutroPayload,
|
||||
VideoEditorTaskWatermarkPayload
|
||||
VideoStudioEditionPayload,
|
||||
VideoStudioTaskPayload,
|
||||
VideoStudioTaskCutPayload,
|
||||
VideoStudioTaskIntroPayload,
|
||||
VideoStudioTaskOutroPayload,
|
||||
VideoStudioTaskWatermarkPayload,
|
||||
VideoStudioTask
|
||||
} from '@shared/models'
|
||||
import { logger, loggerTagsFactory } from '../../../helpers/logger'
|
||||
|
||||
const lTagsBase = loggerTagsFactory('video-edition')
|
||||
|
||||
async function processVideoEdition (job: Job) {
|
||||
const payload = job.data as VideoEditionPayload
|
||||
async function processVideoStudioEdition (job: Job) {
|
||||
const payload = job.data as VideoStudioEditionPayload
|
||||
const lTags = lTagsBase(payload.videoUUID)
|
||||
|
||||
logger.info('Process video edition of %s in job %d.', payload.videoUUID, job.id, lTags)
|
||||
logger.info('Process video studio edition of %s in job %d.', payload.videoUUID, job.id, lTags)
|
||||
|
||||
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID)
|
||||
|
||||
|
@ -106,12 +106,12 @@ async function processVideoEdition (job: Job) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
processVideoEdition
|
||||
processVideoStudioEdition
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type TaskProcessorOptions <T extends VideoEditionTaskPayload = VideoEditionTaskPayload> = {
|
||||
type TaskProcessorOptions <T extends VideoStudioTaskPayload = VideoStudioTaskPayload> = {
|
||||
inputPath: string
|
||||
outputPath: string
|
||||
video: MVideo
|
||||
|
@ -119,7 +119,7 @@ type TaskProcessorOptions <T extends VideoEditionTaskPayload = VideoEditionTaskP
|
|||
lTags: { tags: string[] }
|
||||
}
|
||||
|
||||
const taskProcessors: { [id in VideoEditorTask['name']]: (options: TaskProcessorOptions) => Promise<any> } = {
|
||||
const taskProcessors: { [id in VideoStudioTask['name']]: (options: TaskProcessorOptions) => Promise<any> } = {
|
||||
'add-intro': processAddIntroOutro,
|
||||
'add-outro': processAddIntroOutro,
|
||||
'cut': processCut,
|
||||
|
@ -137,7 +137,7 @@ async function processTask (options: TaskProcessorOptions) {
|
|||
return processor(options)
|
||||
}
|
||||
|
||||
function processAddIntroOutro (options: TaskProcessorOptions<VideoEditorTaskIntroPayload | VideoEditorTaskOutroPayload>) {
|
||||
function processAddIntroOutro (options: TaskProcessorOptions<VideoStudioTaskIntroPayload | VideoStudioTaskOutroPayload>) {
|
||||
const { task } = options
|
||||
|
||||
return addIntroOutro({
|
||||
|
@ -153,7 +153,7 @@ function processAddIntroOutro (options: TaskProcessorOptions<VideoEditorTaskIntr
|
|||
})
|
||||
}
|
||||
|
||||
function processCut (options: TaskProcessorOptions<VideoEditorTaskCutPayload>) {
|
||||
function processCut (options: TaskProcessorOptions<VideoStudioTaskCutPayload>) {
|
||||
const { task } = options
|
||||
|
||||
return cutVideo({
|
||||
|
@ -164,7 +164,7 @@ function processCut (options: TaskProcessorOptions<VideoEditorTaskCutPayload>) {
|
|||
})
|
||||
}
|
||||
|
||||
function processAddWatermark (options: TaskProcessorOptions<VideoEditorTaskWatermarkPayload>) {
|
||||
function processAddWatermark (options: TaskProcessorOptions<VideoStudioTaskWatermarkPayload>) {
|
||||
const { task } = options
|
||||
|
||||
return addWatermark({
|
||||
|
@ -212,10 +212,10 @@ async function removeAllFiles (video: MVideoWithAllFiles, webTorrentFileExceptio
|
|||
}
|
||||
}
|
||||
|
||||
async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoEditionPayload) {
|
||||
async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoStudioEditionPayload) {
|
||||
const user = await UserModel.loadByVideoId(video.id)
|
||||
|
||||
const filePathFinder = (i: number) => (payload.tasks[i] as VideoEditorTaskIntroPayload | VideoEditorTaskOutroPayload).options.file
|
||||
const filePathFinder = (i: number) => (payload.tasks[i] as VideoStudioTaskIntroPayload | VideoStudioTaskOutroPayload).options.file
|
||||
|
||||
const additionalBytes = await approximateIntroOutroAdditionalSize(video, payload.tasks, filePathFinder)
|
||||
if (await isAbleToUploadVideo(user.id, additionalBytes) === false) {
|
|
@ -15,11 +15,11 @@ import {
|
|||
ManageVideoTorrentPayload,
|
||||
MoveObjectStoragePayload,
|
||||
RefreshPayload,
|
||||
VideoEditionPayload,
|
||||
VideoFileImportPayload,
|
||||
VideoImportPayload,
|
||||
VideoLiveEndingPayload,
|
||||
VideoRedundancyPayload,
|
||||
VideoStudioEditionPayload,
|
||||
VideoTranscodingPayload
|
||||
} from '../../../shared/models'
|
||||
import { logger } from '../../helpers/logger'
|
||||
|
@ -34,10 +34,10 @@ import { processActorKeys } from './handlers/actor-keys'
|
|||
import { processEmail } from './handlers/email'
|
||||
import { processManageVideoTorrent } from './handlers/manage-video-torrent'
|
||||
import { processMoveToObjectStorage } from './handlers/move-to-object-storage'
|
||||
import { processVideoEdition } from './handlers/video-edition'
|
||||
import { processVideoFileImport } from './handlers/video-file-import'
|
||||
import { processVideoImport } from './handlers/video-import'
|
||||
import { processVideoLiveEnding } from './handlers/video-live-ending'
|
||||
import { processVideoStudioEdition } from './handlers/video-studio-edition'
|
||||
import { processVideoTranscoding } from './handlers/video-transcoding'
|
||||
import { processVideosViewsStats } from './handlers/video-views-stats'
|
||||
|
||||
|
@ -57,7 +57,7 @@ type CreateJobArgument =
|
|||
{ type: 'actor-keys', payload: ActorKeysPayload } |
|
||||
{ type: 'video-redundancy', payload: VideoRedundancyPayload } |
|
||||
{ type: 'delete-resumable-upload-meta-file', payload: DeleteResumableUploadMetaFilePayload } |
|
||||
{ type: 'video-edition', payload: VideoEditionPayload } |
|
||||
{ type: 'video-studio-edition', payload: VideoStudioEditionPayload } |
|
||||
{ type: 'manage-video-torrent', payload: ManageVideoTorrentPayload } |
|
||||
{ type: 'move-to-object-storage', payload: MoveObjectStoragePayload }
|
||||
|
||||
|
@ -83,7 +83,7 @@ const handlers: { [id in JobType]: (job: Job) => Promise<any> } = {
|
|||
'video-redundancy': processVideoRedundancy,
|
||||
'move-to-object-storage': processMoveToObjectStorage,
|
||||
'manage-video-torrent': processManageVideoTorrent,
|
||||
'video-edition': processVideoEdition
|
||||
'video-studio-edition': processVideoStudioEdition
|
||||
}
|
||||
|
||||
const jobTypes: JobType[] = [
|
||||
|
@ -103,7 +103,7 @@ const jobTypes: JobType[] = [
|
|||
'video-live-ending',
|
||||
'move-to-object-storage',
|
||||
'manage-video-torrent',
|
||||
'video-edition'
|
||||
'video-studio-edition'
|
||||
]
|
||||
|
||||
class JobQueue {
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
AbuseStateChangeForReporter,
|
||||
AutoFollowForInstance,
|
||||
CommentMention,
|
||||
EditionFinishedForOwner,
|
||||
StudioEditionFinishedForOwner,
|
||||
FollowForInstance,
|
||||
FollowForUser,
|
||||
ImportFinishedForOwner,
|
||||
|
@ -55,7 +55,7 @@ class Notifier {
|
|||
newAbuseMessage: [ NewAbuseMessageForReporter, NewAbuseMessageForModerators ],
|
||||
newPeertubeVersion: [ NewPeerTubeVersionForAdmins ],
|
||||
newPluginVersion: [ NewPluginVersionForAdmins ],
|
||||
videoEditionFinished: [ EditionFinishedForOwner ]
|
||||
videoStudioEditionFinished: [ StudioEditionFinishedForOwner ]
|
||||
}
|
||||
|
||||
private static instance: Notifier
|
||||
|
@ -200,11 +200,11 @@ class Notifier {
|
|||
.catch(err => logger.error('Cannot notify on new plugin version %s.', plugin.name, { err }))
|
||||
}
|
||||
|
||||
notifyOfFinishedVideoEdition (video: MVideoFullLight) {
|
||||
const models = this.notificationModels.videoEditionFinished
|
||||
notifyOfFinishedVideoStudioEdition (video: MVideoFullLight) {
|
||||
const models = this.notificationModels.videoStudioEditionFinished
|
||||
|
||||
this.sendNotifications(models, video)
|
||||
.catch(err => logger.error('Cannot notify on finished edition %s.', video.url, { err }))
|
||||
.catch(err => logger.error('Cannot notify on finished studio edition %s.', video.url, { err }))
|
||||
}
|
||||
|
||||
private async notify <T> (object: AbstractNotification<T>) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export * from './new-video-for-subscribers'
|
||||
export * from './edition-finished-for-owner'
|
||||
export * from './import-finished-for-owner'
|
||||
export * from './owned-publication-after-auto-unblacklist'
|
||||
export * from './owned-publication-after-schedule-update'
|
||||
export * from './owned-publication-after-transcoding'
|
||||
export * from './studio-edition-finished-for-owner'
|
||||
|
|
|
@ -6,7 +6,7 @@ import { MUserDefault, MUserWithNotificationSetting, MVideoFullLight, UserNotifi
|
|||
import { UserNotificationType } from '@shared/models'
|
||||
import { AbstractNotification } from '../common/abstract-notification'
|
||||
|
||||
export class EditionFinishedForOwner extends AbstractNotification <MVideoFullLight> {
|
||||
export class StudioEditionFinishedForOwner extends AbstractNotification <MVideoFullLight> {
|
||||
private user: MUserDefault
|
||||
|
||||
async prepare () {
|
||||
|
@ -14,11 +14,11 @@ export class EditionFinishedForOwner extends AbstractNotification <MVideoFullLig
|
|||
}
|
||||
|
||||
log () {
|
||||
logger.info('Notifying user %s its video edition %s is finished.', this.user.username, this.payload.url)
|
||||
logger.info('Notifying user %s its video studio edition %s is finished.', this.user.username, this.payload.url)
|
||||
}
|
||||
|
||||
getSetting (user: MUserWithNotificationSetting) {
|
||||
return user.NotificationSetting.myVideoEditionFinished
|
||||
return user.NotificationSetting.myVideoStudioEditionFinished
|
||||
}
|
||||
|
||||
getTargetUsers () {
|
||||
|
@ -29,7 +29,7 @@ export class EditionFinishedForOwner extends AbstractNotification <MVideoFullLig
|
|||
|
||||
async createNotification (user: MUserWithNotificationSetting) {
|
||||
const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
|
||||
type: UserNotificationType.MY_VIDEO_EDITION_FINISHED,
|
||||
type: UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED,
|
||||
userId: user.id,
|
||||
videoId: this.payload.id
|
||||
})
|
|
@ -159,8 +159,8 @@ class ServerConfigManager {
|
|||
port: CONFIG.LIVE.RTMP.PORT
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
enabled: CONFIG.VIDEO_EDITOR.ENABLED
|
||||
videoStudio: {
|
||||
enabled: CONFIG.VIDEO_STUDIO.ENABLED
|
||||
},
|
||||
import: {
|
||||
videos: {
|
||||
|
|
|
@ -253,7 +253,7 @@ function createDefaultUserNotificationSettings (user: MUserId, t: Transaction |
|
|||
autoInstanceFollowing: UserNotificationSettingValue.WEB,
|
||||
newPeerTubeVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
newPluginVersion: UserNotificationSettingValue.WEB,
|
||||
myVideoEditionFinished: UserNotificationSettingValue.WEB
|
||||
myVideoStudioEditionFinished: UserNotificationSettingValue.WEB
|
||||
}
|
||||
|
||||
return UserNotificationSettingModel.create(values, { transaction: t })
|
||||
|
|
|
@ -135,7 +135,7 @@ async function moveToPublishedState (options: {
|
|||
await federateVideoIfNeeded(video, isNewVideo, transaction)
|
||||
|
||||
if (previousState === VideoState.TO_EDIT) {
|
||||
Notifier.Instance.notifyOfFinishedVideoEdition(video)
|
||||
Notifier.Instance.notifyOfFinishedVideoStudioEdition(video)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { MVideoFullLight } from "@server/types/models"
|
||||
import { getVideoStreamDuration } from "@shared/extra-utils"
|
||||
import { VideoEditorTask } from "@shared/models"
|
||||
import { MVideoFullLight } from '@server/types/models'
|
||||
import { getVideoStreamDuration } from '@shared/extra-utils'
|
||||
import { VideoStudioTask } from '@shared/models'
|
||||
|
||||
function buildTaskFileFieldname (indice: number, fieldName = 'file') {
|
||||
return `tasks[${indice}][options][${fieldName}]`
|
||||
|
@ -10,7 +10,7 @@ function getTaskFile (files: Express.Multer.File[], indice: number, fieldName =
|
|||
return files.find(f => f.fieldname === buildTaskFileFieldname(indice, fieldName))
|
||||
}
|
||||
|
||||
async function approximateIntroOutroAdditionalSize (video: MVideoFullLight, tasks: VideoEditorTask[], fileFinder: (i: number) => string) {
|
||||
async function approximateIntroOutroAdditionalSize (video: MVideoFullLight, tasks: VideoStudioTask[], fileFinder: (i: number) => string) {
|
||||
let additionalDuration = 0
|
||||
|
||||
for (let i = 0; i < tasks.length; i++) {
|
|
@ -57,7 +57,7 @@ const customConfigUpdateValidator = [
|
|||
body('transcoding.webtorrent.enabled').isBoolean().withMessage('Should have a valid webtorrent transcoding enabled boolean'),
|
||||
body('transcoding.hls.enabled').isBoolean().withMessage('Should have a valid hls transcoding enabled boolean'),
|
||||
|
||||
body('videoEditor.enabled').isBoolean().withMessage('Should have a valid video editor enabled boolean'),
|
||||
body('videoStudio.enabled').isBoolean().withMessage('Should have a valid video studio enabled boolean'),
|
||||
|
||||
body('import.videos.concurrency').isInt({ min: 0 }).withMessage('Should have a valid import concurrency number'),
|
||||
body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'),
|
||||
|
@ -106,7 +106,7 @@ const customConfigUpdateValidator = [
|
|||
if (!checkInvalidConfigIfEmailDisabled(req.body, res)) return
|
||||
if (!checkInvalidTranscodingConfig(req.body, res)) return
|
||||
if (!checkInvalidLiveConfig(req.body, res)) return
|
||||
if (!checkInvalidVideoEditorConfig(req.body, res)) return
|
||||
if (!checkInvalidVideoStudioConfig(req.body, res)) return
|
||||
|
||||
return next()
|
||||
}
|
||||
|
@ -163,11 +163,11 @@ function checkInvalidLiveConfig (customConfig: CustomConfig, res: express.Respon
|
|||
return true
|
||||
}
|
||||
|
||||
function checkInvalidVideoEditorConfig (customConfig: CustomConfig, res: express.Response) {
|
||||
if (customConfig.videoEditor.enabled === false) return true
|
||||
function checkInvalidVideoStudioConfig (customConfig: CustomConfig, res: express.Response) {
|
||||
if (customConfig.videoStudio.enabled === false) return true
|
||||
|
||||
if (customConfig.videoEditor.enabled === true && customConfig.transcoding.enabled === false) {
|
||||
res.fail({ message: 'You cannot enable video editor if transcoding is not enabled' })
|
||||
if (customConfig.videoStudio.enabled === true && customConfig.transcoding.enabled === false) {
|
||||
res.fail({ message: 'You cannot enable video studio if transcoding is not enabled' })
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ export * from './video-blacklist'
|
|||
export * from './video-captions'
|
||||
export * from './video-channels'
|
||||
export * from './video-comments'
|
||||
export * from './video-editor'
|
||||
export * from './video-files'
|
||||
export * from './video-imports'
|
||||
export * from './video-live'
|
||||
|
@ -10,5 +9,6 @@ export * from './video-ownership-changes'
|
|||
export * from './video-watch'
|
||||
export * from './video-rates'
|
||||
export * from './video-shares'
|
||||
export * from './video-studio'
|
||||
export * from './video-transcoding'
|
||||
export * from './videos'
|
||||
|
|
|
@ -2,31 +2,31 @@ import express from 'express'
|
|||
import { body, param } from 'express-validator'
|
||||
import { isIdOrUUIDValid } from '@server/helpers/custom-validators/misc'
|
||||
import {
|
||||
isEditorCutTaskValid,
|
||||
isEditorTaskAddIntroOutroValid,
|
||||
isEditorTaskAddWatermarkValid,
|
||||
isValidEditorTasksArray
|
||||
} from '@server/helpers/custom-validators/video-editor'
|
||||
isStudioCutTaskValid,
|
||||
isStudioTaskAddIntroOutroValid,
|
||||
isStudioTaskAddWatermarkValid,
|
||||
isValidStudioTasksArray
|
||||
} from '@server/helpers/custom-validators/video-studio'
|
||||
import { cleanUpReqFiles } from '@server/helpers/express-utils'
|
||||
import { CONFIG } from '@server/initializers/config'
|
||||
import { approximateIntroOutroAdditionalSize, getTaskFile } from '@server/lib/video-editor'
|
||||
import { approximateIntroOutroAdditionalSize, getTaskFile } from '@server/lib/video-studio'
|
||||
import { isAudioFile } from '@shared/extra-utils'
|
||||
import { HttpStatusCode, UserRight, VideoEditorCreateEdition, VideoEditorTask, VideoState } from '@shared/models'
|
||||
import { HttpStatusCode, UserRight, VideoState, VideoStudioCreateEdition, VideoStudioTask } from '@shared/models'
|
||||
import { logger } from '../../../helpers/logger'
|
||||
import { areValidationErrors, checkUserCanManageVideo, checkUserQuota, doesVideoExist } from '../shared'
|
||||
|
||||
const videosEditorAddEditionValidator = [
|
||||
const videoStudioAddEditionValidator = [
|
||||
param('videoId').custom(isIdOrUUIDValid).withMessage('Should have a valid video id/uuid'),
|
||||
|
||||
body('tasks').custom(isValidEditorTasksArray).withMessage('Should have a valid array of tasks'),
|
||||
body('tasks').custom(isValidStudioTasksArray).withMessage('Should have a valid array of tasks'),
|
||||
|
||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
logger.debug('Checking videosEditorAddEditionValidator parameters.', { parameters: req.params, body: req.body, files: req.files })
|
||||
logger.debug('Checking videoStudioAddEditionValidator parameters.', { parameters: req.params, body: req.body, files: req.files })
|
||||
|
||||
if (CONFIG.VIDEO_EDITOR.ENABLED !== true) {
|
||||
if (CONFIG.VIDEO_STUDIO.ENABLED !== true) {
|
||||
res.fail({
|
||||
status: HttpStatusCode.BAD_REQUEST_400,
|
||||
message: 'Video editor is disabled on this instance'
|
||||
message: 'Video studio is disabled on this instance'
|
||||
})
|
||||
|
||||
return cleanUpReqFiles(req)
|
||||
|
@ -34,7 +34,7 @@ const videosEditorAddEditionValidator = [
|
|||
|
||||
if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
|
||||
|
||||
const body: VideoEditorCreateEdition = req.body
|
||||
const body: VideoStudioCreateEdition = req.body
|
||||
const files = req.files as Express.Multer.File[]
|
||||
|
||||
for (let i = 0; i < body.tasks.length; i++) {
|
||||
|
@ -90,21 +90,21 @@ const videosEditorAddEditionValidator = [
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
videosEditorAddEditionValidator
|
||||
videoStudioAddEditionValidator
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const taskCheckers: {
|
||||
[id in VideoEditorTask['name']]: (task: VideoEditorTask, indice?: number, files?: Express.Multer.File[]) => boolean
|
||||
[id in VideoStudioTask['name']]: (task: VideoStudioTask, indice?: number, files?: Express.Multer.File[]) => boolean
|
||||
} = {
|
||||
'cut': isEditorCutTaskValid,
|
||||
'add-intro': isEditorTaskAddIntroOutroValid,
|
||||
'add-outro': isEditorTaskAddIntroOutroValid,
|
||||
'add-watermark': isEditorTaskAddWatermarkValid
|
||||
'cut': isStudioCutTaskValid,
|
||||
'add-intro': isStudioTaskAddIntroOutroValid,
|
||||
'add-outro': isStudioTaskAddIntroOutroValid,
|
||||
'add-watermark': isStudioTaskAddWatermarkValid
|
||||
}
|
||||
|
||||
function checkTask (req: express.Request, task: VideoEditorTask, indice?: number) {
|
||||
function checkTask (req: express.Request, task: VideoStudioTask, indice?: number) {
|
||||
const checker = taskCheckers[task.name]
|
||||
if (!checker) return false
|
||||
|
|
@ -178,11 +178,11 @@ export class UserNotificationSettingModel extends Model<Partial<AttributesOnly<U
|
|||
@AllowNull(false)
|
||||
@Default(null)
|
||||
@Is(
|
||||
'UserNotificationSettingMyVideoEditionFinished',
|
||||
value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoEditionFinished')
|
||||
'UserNotificationSettingMyVideoStudioEditionFinished',
|
||||
value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoStudioEditionFinished')
|
||||
)
|
||||
@Column
|
||||
myVideoEditionFinished: UserNotificationSettingValue
|
||||
myVideoStudioEditionFinished: UserNotificationSettingValue
|
||||
|
||||
@ForeignKey(() => UserModel)
|
||||
@Column
|
||||
|
@ -225,7 +225,7 @@ export class UserNotificationSettingModel extends Model<Partial<AttributesOnly<U
|
|||
abuseNewMessage: this.abuseNewMessage,
|
||||
abuseStateChange: this.abuseStateChange,
|
||||
newPeerTubeVersion: this.newPeerTubeVersion,
|
||||
myVideoEditionFinished: this.myVideoEditionFinished,
|
||||
myVideoStudioEditionFinished: this.myVideoStudioEditionFinished,
|
||||
newPluginVersion: this.newPluginVersion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ describe('Test config API validators', function () {
|
|||
}
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: true
|
||||
},
|
||||
import: {
|
||||
|
|
|
@ -25,7 +25,7 @@ import './video-blacklist'
|
|||
import './video-captions'
|
||||
import './video-channels'
|
||||
import './video-comments'
|
||||
import './video-editor'
|
||||
import './video-studio'
|
||||
import './video-imports'
|
||||
import './video-playlists'
|
||||
import './videos'
|
||||
|
|
|
@ -171,7 +171,7 @@ describe('Test user notifications API validators', function () {
|
|||
abuseNewMessage: UserNotificationSettingValue.WEB,
|
||||
abuseStateChange: UserNotificationSettingValue.WEB,
|
||||
newPeerTubeVersion: UserNotificationSettingValue.WEB,
|
||||
myVideoEditionFinished: UserNotificationSettingValue.WEB,
|
||||
myVideoStudioEditionFinished: UserNotificationSettingValue.WEB,
|
||||
newPluginVersion: UserNotificationSettingValue.WEB
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
import { HttpStatusCode, VideoEditorTask } from '@shared/models'
|
||||
import { HttpStatusCode, VideoStudioTask } from '@shared/models'
|
||||
import {
|
||||
cleanupTests,
|
||||
createSingleServer,
|
||||
PeerTubeServer,
|
||||
setAccessTokensToServers,
|
||||
VideoEditorCommand,
|
||||
VideoStudioCommand,
|
||||
waitJobs
|
||||
} from '@shared/server-commands'
|
||||
|
||||
describe('Test video editor API validator', function () {
|
||||
describe('Test video studio API validator', function () {
|
||||
let server: PeerTubeServer
|
||||
let command: VideoEditorCommand
|
||||
let command: VideoStudioCommand
|
||||
let userAccessToken: string
|
||||
let videoUUID: string
|
||||
|
||||
|
@ -32,7 +32,7 @@ describe('Test video editor API validator', function () {
|
|||
const { uuid } = await server.videos.quickUpload({ name: 'video' })
|
||||
videoUUID = uuid
|
||||
|
||||
command = server.videoEditor
|
||||
command = server.videoStudio
|
||||
|
||||
await waitJobs([ server ])
|
||||
})
|
||||
|
@ -41,10 +41,10 @@ describe('Test video editor API validator', function () {
|
|||
|
||||
describe('Config settings', function () {
|
||||
|
||||
it('Should fail if editor is disabled', async function () {
|
||||
it('Should fail if studio is disabled', async function () {
|
||||
await server.config.updateExistingSubConfig({
|
||||
newConfig: {
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
@ -52,15 +52,15 @@ describe('Test video editor API validator', function () {
|
|||
|
||||
await command.createEditionTasks({
|
||||
videoId: videoUUID,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
})
|
||||
})
|
||||
|
||||
it('Should fail to enable editor if transcoding is disabled', async function () {
|
||||
it('Should fail to enable studio if transcoding is disabled', async function () {
|
||||
await server.config.updateExistingSubConfig({
|
||||
newConfig: {
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: true
|
||||
},
|
||||
transcoding: {
|
||||
|
@ -71,10 +71,10 @@ describe('Test video editor API validator', function () {
|
|||
})
|
||||
})
|
||||
|
||||
it('Should succeed to enable video editor', async function () {
|
||||
it('Should succeed to enable video studio', async function () {
|
||||
await server.config.updateExistingSubConfig({
|
||||
newConfig: {
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: true
|
||||
},
|
||||
transcoding: {
|
||||
|
@ -91,7 +91,7 @@ describe('Test video editor API validator', function () {
|
|||
await command.createEditionTasks({
|
||||
token: null,
|
||||
videoId: videoUUID,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.UNAUTHORIZED_401
|
||||
})
|
||||
})
|
||||
|
@ -100,7 +100,7 @@ describe('Test video editor API validator', function () {
|
|||
await command.createEditionTasks({
|
||||
token: userAccessToken,
|
||||
videoId: videoUUID,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.FORBIDDEN_403
|
||||
})
|
||||
})
|
||||
|
@ -108,7 +108,7 @@ describe('Test video editor API validator', function () {
|
|||
it('Should fail with an invalid video', async function () {
|
||||
await command.createEditionTasks({
|
||||
videoId: 'tintin',
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
})
|
||||
})
|
||||
|
@ -116,7 +116,7 @@ describe('Test video editor API validator', function () {
|
|||
it('Should fail with an unknown video', async function () {
|
||||
await command.createEditionTasks({
|
||||
videoId: 42,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.NOT_FOUND_404
|
||||
})
|
||||
})
|
||||
|
@ -132,7 +132,7 @@ describe('Test video editor API validator', function () {
|
|||
|
||||
await command.createEditionTasks({
|
||||
videoId: uuid,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.CONFLICT_409
|
||||
})
|
||||
|
||||
|
@ -171,7 +171,7 @@ describe('Test video editor API validator', function () {
|
|||
})
|
||||
|
||||
it('Should fail with too many tasks', async function () {
|
||||
const tasks: VideoEditorTask[] = []
|
||||
const tasks: VideoStudioTask[] = []
|
||||
|
||||
for (let i = 0; i < 110; i++) {
|
||||
tasks.push({
|
||||
|
@ -194,7 +194,7 @@ describe('Test video editor API validator', function () {
|
|||
|
||||
await command.createEditionTasks({
|
||||
videoId: videoUUID,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
})
|
||||
|
@ -204,7 +204,7 @@ describe('Test video editor API validator', function () {
|
|||
|
||||
await command.createEditionTasks({
|
||||
videoId: videoUUID,
|
||||
tasks: VideoEditorCommand.getComplexTask(),
|
||||
tasks: VideoStudioCommand.getComplexTask(),
|
||||
expectedStatus: HttpStatusCode.CONFLICT_409
|
||||
})
|
||||
|
|
@ -7,7 +7,7 @@ import {
|
|||
checkMyVideoImportIsFinished,
|
||||
checkNewActorFollow,
|
||||
checkNewVideoFromSubscription,
|
||||
checkVideoEditionIsFinished,
|
||||
checkVideoStudioEditionIsFinished,
|
||||
checkVideoIsPublished,
|
||||
FIXTURE_URLS,
|
||||
MockSmtpServer,
|
||||
|
@ -16,7 +16,7 @@ import {
|
|||
} from '@server/tests/shared'
|
||||
import { wait } from '@shared/core-utils'
|
||||
import { buildUUID } from '@shared/extra-utils'
|
||||
import { UserNotification, UserNotificationType, VideoEditorTask, VideoPrivacy } from '@shared/models'
|
||||
import { UserNotification, UserNotificationType, VideoStudioTask, VideoPrivacy } from '@shared/models'
|
||||
import { cleanupTests, PeerTubeServer, waitJobs } from '@shared/server-commands'
|
||||
|
||||
const expect = chai.expect
|
||||
|
@ -323,7 +323,7 @@ describe('Test user notifications', function () {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Video editor', function () {
|
||||
describe('Video studio', function () {
|
||||
let baseParams: CheckerBaseParams
|
||||
|
||||
before(() => {
|
||||
|
@ -335,7 +335,7 @@ describe('Test user notifications', function () {
|
|||
}
|
||||
})
|
||||
|
||||
it('Should send a notification after editor edition', async function () {
|
||||
it('Should send a notification after studio edition', async function () {
|
||||
this.timeout(240000)
|
||||
|
||||
const { name, shortUUID, id } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true })
|
||||
|
@ -343,7 +343,7 @@ describe('Test user notifications', function () {
|
|||
await waitJobs(servers)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
|
||||
const tasks: VideoEditorTask[] = [
|
||||
const tasks: VideoStudioTask[] = [
|
||||
{
|
||||
name: 'cut',
|
||||
options: {
|
||||
|
@ -352,10 +352,10 @@ describe('Test user notifications', function () {
|
|||
}
|
||||
}
|
||||
]
|
||||
await servers[1].videoEditor.createEditionTasks({ videoId: id, tasks })
|
||||
await servers[1].videoStudio.createEditionTasks({ videoId: id, tasks })
|
||||
await waitJobs(servers)
|
||||
|
||||
await checkVideoEditionIsFinished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
await checkVideoStudioEditionIsFinished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
|
|||
expect(data.live.transcoding.resolutions['1440p']).to.be.false
|
||||
expect(data.live.transcoding.resolutions['2160p']).to.be.false
|
||||
|
||||
expect(data.videoEditor.enabled).to.be.false
|
||||
expect(data.videoStudio.enabled).to.be.false
|
||||
|
||||
expect(data.import.videos.concurrency).to.equal(2)
|
||||
expect(data.import.videos.http.enabled).to.be.true
|
||||
|
@ -201,7 +201,7 @@ function checkUpdatedConfig (data: CustomConfig) {
|
|||
expect(data.live.transcoding.resolutions['1080p']).to.be.true
|
||||
expect(data.live.transcoding.resolutions['2160p']).to.be.true
|
||||
|
||||
expect(data.videoEditor.enabled).to.be.true
|
||||
expect(data.videoStudio.enabled).to.be.true
|
||||
|
||||
expect(data.import.videos.concurrency).to.equal(4)
|
||||
expect(data.import.videos.http.enabled).to.be.false
|
||||
|
@ -350,7 +350,7 @@ const newCustomConfig: CustomConfig = {
|
|||
}
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: true
|
||||
},
|
||||
import: {
|
||||
|
|
|
@ -2,4 +2,4 @@ export * from './audio-only'
|
|||
export * from './create-transcoding'
|
||||
export * from './hls'
|
||||
export * from './transcoder'
|
||||
export * from './video-editor'
|
||||
export * from './video-studio'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { expect } from 'chai'
|
||||
import { expectStartWith, getAllFiles } from '@server/tests/shared'
|
||||
import { areObjectStorageTestsDisabled } from '@shared/core-utils'
|
||||
import { VideoEditorTask } from '@shared/models'
|
||||
import { VideoStudioTask } from '@shared/models'
|
||||
import {
|
||||
cleanupTests,
|
||||
createMultipleServers,
|
||||
|
@ -10,11 +10,11 @@ import {
|
|||
PeerTubeServer,
|
||||
setAccessTokensToServers,
|
||||
setDefaultVideoChannel,
|
||||
VideoEditorCommand,
|
||||
VideoStudioCommand,
|
||||
waitJobs
|
||||
} from '@shared/server-commands'
|
||||
|
||||
describe('Test video editor', function () {
|
||||
describe('Test video studio', function () {
|
||||
let servers: PeerTubeServer[] = []
|
||||
let videoUUID: string
|
||||
|
||||
|
@ -39,8 +39,8 @@ describe('Test video editor', function () {
|
|||
await waitJobs(servers)
|
||||
}
|
||||
|
||||
async function createTasks (tasks: VideoEditorTask[]) {
|
||||
await servers[0].videoEditor.createEditionTasks({ videoId: videoUUID, tasks })
|
||||
async function createTasks (tasks: VideoStudioTask[]) {
|
||||
await servers[0].videoStudio.createEditionTasks({ videoId: videoUUID, tasks })
|
||||
await waitJobs(servers)
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ describe('Test video editor', function () {
|
|||
|
||||
await servers[0].config.enableMinimumTranscoding()
|
||||
|
||||
await servers[0].config.enableEditor()
|
||||
await servers[0].config.enableStudio()
|
||||
})
|
||||
|
||||
describe('Cutting', function () {
|
||||
|
@ -276,7 +276,7 @@ describe('Test video editor', function () {
|
|||
this.timeout(240_000)
|
||||
await renewVideo()
|
||||
|
||||
await createTasks(VideoEditorCommand.getComplexTask())
|
||||
await createTasks(VideoStudioCommand.getComplexTask())
|
||||
|
||||
for (const server of servers) {
|
||||
await checkDuration(server, 9)
|
||||
|
@ -303,7 +303,7 @@ describe('Test video editor', function () {
|
|||
this.timeout(240_000)
|
||||
await renewVideo()
|
||||
|
||||
await createTasks(VideoEditorCommand.getComplexTask())
|
||||
await createTasks(VideoStudioCommand.getComplexTask())
|
||||
|
||||
for (const server of servers) {
|
||||
const video = await server.videos.get({ id: videoUUID })
|
||||
|
@ -333,7 +333,7 @@ describe('Test video editor', function () {
|
|||
const video = await servers[0].videos.get({ id: videoUUID })
|
||||
const oldFileUrls = getAllFiles(video).map(f => f.fileUrl)
|
||||
|
||||
await createTasks(VideoEditorCommand.getComplexTask())
|
||||
await createTasks(VideoStudioCommand.getComplexTask())
|
||||
|
||||
for (const server of servers) {
|
||||
const video = await server.videos.get({ id: videoUUID })
|
|
@ -47,7 +47,7 @@ function getAllNotificationsSettings (): UserNotificationSetting {
|
|||
abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
newPeerTubeVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
myVideoEditionFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
myVideoStudioEditionFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
|
||||
newPluginVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
|
||||
}
|
||||
}
|
||||
|
@ -110,13 +110,13 @@ async function checkVideoIsPublished (options: CheckerBaseParams & {
|
|||
await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
|
||||
}
|
||||
|
||||
async function checkVideoEditionIsFinished (options: CheckerBaseParams & {
|
||||
async function checkVideoStudioEditionIsFinished (options: CheckerBaseParams & {
|
||||
videoName: string
|
||||
shortUUID: string
|
||||
checkType: CheckerType
|
||||
}) {
|
||||
const { videoName, shortUUID } = options
|
||||
const notificationType = UserNotificationType.MY_VIDEO_EDITION_FINISHED
|
||||
const notificationType = UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED
|
||||
|
||||
function notificationChecker (notification: UserNotification, checkType: CheckerType) {
|
||||
if (checkType === 'presence') {
|
||||
|
@ -685,7 +685,7 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
|
|||
await setDefaultChannelAvatar(servers)
|
||||
await setDefaultAccountAvatar(servers)
|
||||
|
||||
await servers[1].config.enableEditor()
|
||||
await servers[1].config.enableStudio()
|
||||
|
||||
if (serversCount > 1) {
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
|
@ -756,7 +756,7 @@ export {
|
|||
checkNewAccountAbuseForModerators,
|
||||
checkNewPeerTubeVersion,
|
||||
checkNewPluginVersion,
|
||||
checkVideoEditionIsFinished
|
||||
checkVideoStudioEditionIsFinished
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -147,7 +147,7 @@ export interface CustomConfig {
|
|||
}
|
||||
}
|
||||
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ContextType } from '../activitypub/context'
|
||||
import { VideoState } from '../videos'
|
||||
import { VideoEditorTaskCut } from '../videos/editor'
|
||||
import { VideoStudioTaskCut } from '../videos/studio'
|
||||
import { VideoResolution } from '../videos/file/video-resolution.enum'
|
||||
import { SendEmailOptions } from './emailer.model'
|
||||
|
||||
|
@ -23,7 +23,7 @@ export type JobType =
|
|||
| 'actor-keys'
|
||||
| 'manage-video-torrent'
|
||||
| 'move-to-object-storage'
|
||||
| 'video-edition'
|
||||
| 'video-studio-edition'
|
||||
|
||||
export interface Job {
|
||||
id: number
|
||||
|
@ -117,9 +117,6 @@ export type ManageVideoTorrentPayload =
|
|||
interface BaseTranscodingPayload {
|
||||
videoUUID: string
|
||||
isNewVideo?: boolean
|
||||
|
||||
// Custom notification when the task is finished
|
||||
notification?: 'default' | 'video-edition'
|
||||
}
|
||||
|
||||
export interface HLSTranscodingPayload extends BaseTranscodingPayload {
|
||||
|
@ -178,9 +175,9 @@ export interface MoveObjectStoragePayload {
|
|||
previousVideoState: VideoState
|
||||
}
|
||||
|
||||
export type VideoEditorTaskCutPayload = VideoEditorTaskCut
|
||||
export type VideoStudioTaskCutPayload = VideoStudioTaskCut
|
||||
|
||||
export type VideoEditorTaskIntroPayload = {
|
||||
export type VideoStudioTaskIntroPayload = {
|
||||
name: 'add-intro'
|
||||
|
||||
options: {
|
||||
|
@ -188,7 +185,7 @@ export type VideoEditorTaskIntroPayload = {
|
|||
}
|
||||
}
|
||||
|
||||
export type VideoEditorTaskOutroPayload = {
|
||||
export type VideoStudioTaskOutroPayload = {
|
||||
name: 'add-outro'
|
||||
|
||||
options: {
|
||||
|
@ -196,7 +193,7 @@ export type VideoEditorTaskOutroPayload = {
|
|||
}
|
||||
}
|
||||
|
||||
export type VideoEditorTaskWatermarkPayload = {
|
||||
export type VideoStudioTaskWatermarkPayload = {
|
||||
name: 'add-watermark'
|
||||
|
||||
options: {
|
||||
|
@ -204,13 +201,13 @@ export type VideoEditorTaskWatermarkPayload = {
|
|||
}
|
||||
}
|
||||
|
||||
export type VideoEditionTaskPayload =
|
||||
VideoEditorTaskCutPayload |
|
||||
VideoEditorTaskIntroPayload |
|
||||
VideoEditorTaskOutroPayload |
|
||||
VideoEditorTaskWatermarkPayload
|
||||
export type VideoStudioTaskPayload =
|
||||
VideoStudioTaskCutPayload |
|
||||
VideoStudioTaskIntroPayload |
|
||||
VideoStudioTaskOutroPayload |
|
||||
VideoStudioTaskWatermarkPayload
|
||||
|
||||
export interface VideoEditionPayload {
|
||||
export interface VideoStudioEditionPayload {
|
||||
videoUUID: string
|
||||
tasks: VideoEditionTaskPayload[]
|
||||
tasks: VideoStudioTaskPayload[]
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ export interface ServerConfig {
|
|||
}
|
||||
}
|
||||
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,5 @@ export interface UserNotificationSetting {
|
|||
newPeerTubeVersion: UserNotificationSettingValue
|
||||
newPluginVersion: UserNotificationSettingValue
|
||||
|
||||
myVideoEditionFinished: UserNotificationSettingValue
|
||||
myVideoStudioEditionFinished: UserNotificationSettingValue
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export const enum UserNotificationType {
|
|||
NEW_PLUGIN_VERSION = 17,
|
||||
NEW_PEERTUBE_VERSION = 18,
|
||||
|
||||
MY_VIDEO_EDITION_FINISHED = 19
|
||||
MY_VIDEO_STUDIO_EDITION_FINISHED = 19
|
||||
}
|
||||
|
||||
export interface VideoInfo {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * from './video-editor-create-edit.model'
|
|
@ -1,42 +0,0 @@
|
|||
export interface VideoEditorCreateEdition {
|
||||
tasks: VideoEditorTask[]
|
||||
}
|
||||
|
||||
export type VideoEditorTask =
|
||||
VideoEditorTaskCut |
|
||||
VideoEditorTaskIntro |
|
||||
VideoEditorTaskOutro |
|
||||
VideoEditorTaskWatermark
|
||||
|
||||
export interface VideoEditorTaskCut {
|
||||
name: 'cut'
|
||||
|
||||
options: {
|
||||
start?: number
|
||||
end?: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoEditorTaskIntro {
|
||||
name: 'add-intro'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoEditorTaskOutro {
|
||||
name: 'add-outro'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoEditorTaskWatermark {
|
||||
name: 'add-watermark'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ export * from './caption'
|
|||
export * from './change-ownership'
|
||||
export * from './channel'
|
||||
export * from './comment'
|
||||
export * from './editor'
|
||||
export * from './studio'
|
||||
export * from './live'
|
||||
export * from './file'
|
||||
export * from './import'
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from './video-studio-create-edit.model'
|
|
@ -0,0 +1,42 @@
|
|||
export interface VideoStudioCreateEdition {
|
||||
tasks: VideoStudioTask[]
|
||||
}
|
||||
|
||||
export type VideoStudioTask =
|
||||
VideoStudioTaskCut |
|
||||
VideoStudioTaskIntro |
|
||||
VideoStudioTaskOutro |
|
||||
VideoStudioTaskWatermark
|
||||
|
||||
export interface VideoStudioTaskCut {
|
||||
name: 'cut'
|
||||
|
||||
options: {
|
||||
start?: number
|
||||
end?: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoStudioTaskIntro {
|
||||
name: 'add-intro'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoStudioTaskOutro {
|
||||
name: 'add-outro'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
||||
|
||||
export interface VideoStudioTaskWatermark {
|
||||
name: 'add-watermark'
|
||||
|
||||
options: {
|
||||
file: Blob | string
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ export class ConfigCommand extends AbstractCommand {
|
|||
transcoding: {
|
||||
enabled: false
|
||||
},
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
@ -111,10 +111,10 @@ export class ConfigCommand extends AbstractCommand {
|
|||
})
|
||||
}
|
||||
|
||||
enableEditor () {
|
||||
enableStudio () {
|
||||
return this.updateExistingSubConfig({
|
||||
newConfig: {
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ export class ConfigCommand extends AbstractCommand {
|
|||
}
|
||||
}
|
||||
},
|
||||
videoEditor: {
|
||||
videoStudio: {
|
||||
enabled: false
|
||||
},
|
||||
import: {
|
||||
|
|
|
@ -25,7 +25,7 @@ import {
|
|||
PlaylistsCommand,
|
||||
ServicesCommand,
|
||||
StreamingPlaylistsCommand,
|
||||
VideoEditorCommand,
|
||||
VideoStudioCommand,
|
||||
VideosCommand
|
||||
} from '../videos'
|
||||
import { CommentsCommand } from '../videos/comments-command'
|
||||
|
@ -125,7 +125,7 @@ export class PeerTubeServer {
|
|||
login?: LoginCommand
|
||||
users?: UsersCommand
|
||||
objectStorage?: ObjectStorageCommand
|
||||
videoEditor?: VideoEditorCommand
|
||||
videoStudio?: VideoStudioCommand
|
||||
videos?: VideosCommand
|
||||
|
||||
constructor (options: { serverNumber: number } | { url: string }) {
|
||||
|
@ -396,6 +396,6 @@ export class PeerTubeServer {
|
|||
this.users = new UsersCommand(this)
|
||||
this.videos = new VideosCommand(this)
|
||||
this.objectStorage = new ObjectStorageCommand(this)
|
||||
this.videoEditor = new VideoEditorCommand(this)
|
||||
this.videoStudio = new VideoStudioCommand(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ export * from './playlists-command'
|
|||
export * from './services-command'
|
||||
export * from './streaming-playlists-command'
|
||||
export * from './comments-command'
|
||||
export * from './video-editor-command'
|
||||
export * from './video-studio-command'
|
||||
export * from './videos-command'
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { HttpStatusCode, VideoEditorTask } from '@shared/models'
|
||||
import { HttpStatusCode, VideoStudioTask } from '@shared/models'
|
||||
import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
||||
|
||||
export class VideoEditorCommand extends AbstractCommand {
|
||||
export class VideoStudioCommand extends AbstractCommand {
|
||||
|
||||
static getComplexTask (): VideoEditorTask[] {
|
||||
static getComplexTask (): VideoStudioTask[] {
|
||||
return [
|
||||
// Total duration: 2
|
||||
{
|
||||
|
@ -41,9 +41,9 @@ export class VideoEditorCommand extends AbstractCommand {
|
|||
|
||||
createEditionTasks (options: OverrideCommandOptions & {
|
||||
videoId: number | string
|
||||
tasks: VideoEditorTask[]
|
||||
tasks: VideoStudioTask[]
|
||||
}) {
|
||||
const path = '/api/v1/videos/' + options.videoId + '/editor/edit'
|
||||
const path = '/api/v1/videos/' + options.videoId + '/studio/edit'
|
||||
const attaches: { [id: string]: any } = {}
|
||||
|
||||
for (let i = 0; i < options.tasks.length; i++) {
|
|
@ -85,7 +85,7 @@ server {
|
|||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/videos/(upload|([^/]+/editor/edit))$ {
|
||||
location ~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$ {
|
||||
limit_except POST HEAD { deny all; }
|
||||
|
||||
# This is the maximum upload size, which roughly matches the maximum size of a video file.
|
||||
|
|
Loading…
Reference in New Issue