diff options
Diffstat (limited to 'shared')
45 files changed, 397 insertions, 117 deletions
diff --git a/shared/core-utils/common/array.ts b/shared/core-utils/common/array.ts index e1b422165..878ed1ffe 100644 --- a/shared/core-utils/common/array.ts +++ b/shared/core-utils/common/array.ts | |||
@@ -20,8 +20,22 @@ function uniqify <T> (elements: T[]) { | |||
20 | return Array.from(new Set(elements)) | 20 | return Array.from(new Set(elements)) |
21 | } | 21 | } |
22 | 22 | ||
23 | // Thanks: https://stackoverflow.com/a/12646864 | ||
24 | function shuffle <T> (elements: T[]) { | ||
25 | const shuffled = [ ...elements ] | ||
26 | |||
27 | for (let i = shuffled.length - 1; i > 0; i--) { | ||
28 | const j = Math.floor(Math.random() * (i + 1)); | ||
29 | |||
30 | [ shuffled[i], shuffled[j] ] = [ shuffled[j], shuffled[i] ] | ||
31 | } | ||
32 | |||
33 | return shuffled | ||
34 | } | ||
35 | |||
23 | export { | 36 | export { |
24 | uniqify, | 37 | uniqify, |
25 | findCommonElement, | 38 | findCommonElement, |
39 | shuffle, | ||
26 | arrayify | 40 | arrayify |
27 | } | 41 | } |
diff --git a/shared/core-utils/videos/common.ts b/shared/core-utils/videos/common.ts index 2c6efdb7f..0431edaaf 100644 --- a/shared/core-utils/videos/common.ts +++ b/shared/core-utils/videos/common.ts | |||
@@ -3,7 +3,7 @@ import { VideoPrivacy } from '../../models/videos/video-privacy.enum' | |||
3 | import { VideoDetails } from '../../models/videos/video.model' | 3 | import { VideoDetails } from '../../models/videos/video.model' |
4 | 4 | ||
5 | function getAllPrivacies () { | 5 | function getAllPrivacies () { |
6 | return [ VideoPrivacy.PUBLIC, VideoPrivacy.INTERNAL, VideoPrivacy.PRIVATE, VideoPrivacy.UNLISTED ] | 6 | return [ VideoPrivacy.PUBLIC, VideoPrivacy.INTERNAL, VideoPrivacy.PRIVATE, VideoPrivacy.UNLISTED, VideoPrivacy.PASSWORD_PROTECTED ] |
7 | } | 7 | } |
8 | 8 | ||
9 | function getAllFiles (video: Partial<Pick<VideoDetails, 'files' | 'streamingPlaylists'>>) { | 9 | function getAllFiles (video: Partial<Pick<VideoDetails, 'files' | 'streamingPlaylists'>>) { |
diff --git a/shared/ffmpeg/ffmpeg-images.ts b/shared/ffmpeg/ffmpeg-images.ts index 2db63bd8b..618fac7d1 100644 --- a/shared/ffmpeg/ffmpeg-images.ts +++ b/shared/ffmpeg/ffmpeg-images.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import { FFmpegCommandWrapper, FFmpegCommandWrapperOptions } from './ffmpeg-command-wrapper' | 1 | import { FFmpegCommandWrapper, FFmpegCommandWrapperOptions } from './ffmpeg-command-wrapper' |
2 | import { getVideoStreamDuration } from './ffprobe' | ||
2 | 3 | ||
3 | export class FFmpegImage { | 4 | export class FFmpegImage { |
4 | private readonly commandWrapper: FFmpegCommandWrapper | 5 | private readonly commandWrapper: FFmpegCommandWrapper |
@@ -36,24 +37,56 @@ export class FFmpegImage { | |||
36 | 37 | ||
37 | async generateThumbnailFromVideo (options: { | 38 | async generateThumbnailFromVideo (options: { |
38 | fromPath: string | 39 | fromPath: string |
39 | folder: string | 40 | output: string |
40 | imageName: string | ||
41 | }) { | 41 | }) { |
42 | const { fromPath, folder, imageName } = options | 42 | const { fromPath, output } = options |
43 | 43 | ||
44 | const pendingImageName = 'pending-' + imageName | 44 | let duration = await getVideoStreamDuration(fromPath) |
45 | if (isNaN(duration)) duration = 0 | ||
45 | 46 | ||
46 | const thumbnailOptions = { | 47 | this.commandWrapper.buildCommand(fromPath) |
47 | filename: pendingImageName, | 48 | .seekInput(duration / 2) |
48 | count: 1, | 49 | .videoFilter('thumbnail=500') |
49 | folder | 50 | .outputOption('-frames:v 1') |
51 | .output(output) | ||
52 | |||
53 | return this.commandWrapper.runCommand() | ||
54 | } | ||
55 | |||
56 | async generateStoryboardFromVideo (options: { | ||
57 | path: string | ||
58 | destination: string | ||
59 | |||
60 | sprites: { | ||
61 | size: { | ||
62 | width: number | ||
63 | height: number | ||
64 | } | ||
65 | |||
66 | count: { | ||
67 | width: number | ||
68 | height: number | ||
69 | } | ||
70 | |||
71 | duration: number | ||
50 | } | 72 | } |
73 | }) { | ||
74 | const { path, destination, sprites } = options | ||
75 | |||
76 | const command = this.commandWrapper.buildCommand(path) | ||
51 | 77 | ||
52 | return new Promise<string>((res, rej) => { | 78 | const filter = [ |
53 | this.commandWrapper.buildCommand(fromPath) | 79 | `setpts=N/round(FRAME_RATE)/TB`, |
54 | .on('error', rej) | 80 | `select='not(mod(t,${options.sprites.duration}))'`, |
55 | .on('end', () => res(imageName)) | 81 | `scale=${sprites.size.width}:${sprites.size.height}`, |
56 | .thumbnail(thumbnailOptions) | 82 | `tile=layout=${sprites.count.width}x${sprites.count.height}` |
57 | }) | 83 | ].join(',') |
84 | |||
85 | command.outputOption('-filter_complex', filter) | ||
86 | command.outputOption('-frames:v', '1') | ||
87 | command.outputOption('-q:v', '2') | ||
88 | command.output(destination) | ||
89 | |||
90 | return this.commandWrapper.runCommand() | ||
58 | } | 91 | } |
59 | } | 92 | } |
diff --git a/shared/models/activitypub/activity.ts b/shared/models/activitypub/activity.ts index fd5d38316..10cf53ead 100644 --- a/shared/models/activitypub/activity.ts +++ b/shared/models/activitypub/activity.ts | |||
@@ -1,20 +1,34 @@ | |||
1 | import { ActivityPubActor } from './activitypub-actor' | 1 | import { ActivityPubActor } from './activitypub-actor' |
2 | import { ActivityPubSignature } from './activitypub-signature' | 2 | import { ActivityPubSignature } from './activitypub-signature' |
3 | import { ActivityFlagReasonObject, CacheFileObject, VideoObject, WatchActionObject } from './objects' | 3 | import { |
4 | import { AbuseObject } from './objects/abuse-object' | 4 | ActivityFlagReasonObject, |
5 | import { DislikeObject } from './objects/dislike-object' | 5 | ActivityObject, |
6 | import { APObject } from './objects/object.model' | 6 | APObjectId, |
7 | import { PlaylistObject } from './objects/playlist-object' | 7 | CacheFileObject, |
8 | import { VideoCommentObject } from './objects/video-comment-object' | 8 | PlaylistObject, |
9 | VideoCommentObject, | ||
10 | VideoObject, | ||
11 | WatchActionObject | ||
12 | } from './objects' | ||
13 | |||
14 | export type ActivityUpdateObject = | ||
15 | Extract<ActivityObject, VideoObject | CacheFileObject | PlaylistObject | ActivityPubActor | string> | ActivityPubActor | ||
16 | |||
17 | // Cannot Extract from Activity because of circular reference | ||
18 | export type ActivityUndoObject = | ||
19 | ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate<CacheFileObject | string> | ActivityAnnounce | ||
20 | |||
21 | export type ActivityCreateObject = | ||
22 | Extract<ActivityObject, VideoObject | CacheFileObject | WatchActionObject | VideoCommentObject | PlaylistObject | string> | ||
9 | 23 | ||
10 | export type Activity = | 24 | export type Activity = |
11 | ActivityCreate | | 25 | ActivityCreate<ActivityCreateObject> | |
12 | ActivityUpdate | | 26 | ActivityUpdate<ActivityUpdateObject> | |
13 | ActivityDelete | | 27 | ActivityDelete | |
14 | ActivityFollow | | 28 | ActivityFollow | |
15 | ActivityAccept | | 29 | ActivityAccept | |
16 | ActivityAnnounce | | 30 | ActivityAnnounce | |
17 | ActivityUndo | | 31 | ActivityUndo<ActivityUndoObject> | |
18 | ActivityLike | | 32 | ActivityLike | |
19 | ActivityReject | | 33 | ActivityReject | |
20 | ActivityView | | 34 | ActivityView | |
@@ -50,19 +64,19 @@ export interface BaseActivity { | |||
50 | signature?: ActivityPubSignature | 64 | signature?: ActivityPubSignature |
51 | } | 65 | } |
52 | 66 | ||
53 | export interface ActivityCreate extends BaseActivity { | 67 | export interface ActivityCreate <T extends ActivityCreateObject> extends BaseActivity { |
54 | type: 'Create' | 68 | type: 'Create' |
55 | object: VideoObject | AbuseObject | DislikeObject | VideoCommentObject | CacheFileObject | PlaylistObject | WatchActionObject | 69 | object: T |
56 | } | 70 | } |
57 | 71 | ||
58 | export interface ActivityUpdate extends BaseActivity { | 72 | export interface ActivityUpdate <T extends ActivityUpdateObject> extends BaseActivity { |
59 | type: 'Update' | 73 | type: 'Update' |
60 | object: VideoObject | ActivityPubActor | CacheFileObject | PlaylistObject | 74 | object: T |
61 | } | 75 | } |
62 | 76 | ||
63 | export interface ActivityDelete extends BaseActivity { | 77 | export interface ActivityDelete extends BaseActivity { |
64 | type: 'Delete' | 78 | type: 'Delete' |
65 | object: string | { id: string } | 79 | object: APObjectId |
66 | } | 80 | } |
67 | 81 | ||
68 | export interface ActivityFollow extends BaseActivity { | 82 | export interface ActivityFollow extends BaseActivity { |
@@ -82,23 +96,23 @@ export interface ActivityReject extends BaseActivity { | |||
82 | 96 | ||
83 | export interface ActivityAnnounce extends BaseActivity { | 97 | export interface ActivityAnnounce extends BaseActivity { |
84 | type: 'Announce' | 98 | type: 'Announce' |
85 | object: APObject | 99 | object: APObjectId |
86 | } | 100 | } |
87 | 101 | ||
88 | export interface ActivityUndo extends BaseActivity { | 102 | export interface ActivityUndo <T extends ActivityUndoObject> extends BaseActivity { |
89 | type: 'Undo' | 103 | type: 'Undo' |
90 | object: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce | 104 | object: T |
91 | } | 105 | } |
92 | 106 | ||
93 | export interface ActivityLike extends BaseActivity { | 107 | export interface ActivityLike extends BaseActivity { |
94 | type: 'Like' | 108 | type: 'Like' |
95 | object: APObject | 109 | object: APObjectId |
96 | } | 110 | } |
97 | 111 | ||
98 | export interface ActivityView extends BaseActivity { | 112 | export interface ActivityView extends BaseActivity { |
99 | type: 'View' | 113 | type: 'View' |
100 | actor: string | 114 | actor: string |
101 | object: APObject | 115 | object: APObjectId |
102 | 116 | ||
103 | // If sending a "viewer" event | 117 | // If sending a "viewer" event |
104 | expires?: string | 118 | expires?: string |
@@ -108,13 +122,13 @@ export interface ActivityDislike extends BaseActivity { | |||
108 | id: string | 122 | id: string |
109 | type: 'Dislike' | 123 | type: 'Dislike' |
110 | actor: string | 124 | actor: string |
111 | object: APObject | 125 | object: APObjectId |
112 | } | 126 | } |
113 | 127 | ||
114 | export interface ActivityFlag extends BaseActivity { | 128 | export interface ActivityFlag extends BaseActivity { |
115 | type: 'Flag' | 129 | type: 'Flag' |
116 | content: string | 130 | content: string |
117 | object: APObject | APObject[] | 131 | object: APObjectId | APObjectId[] |
118 | tag?: ActivityFlagReasonObject[] | 132 | tag?: ActivityFlagReasonObject[] |
119 | startAt?: number | 133 | startAt?: number |
120 | endAt?: number | 134 | endAt?: number |
diff --git a/shared/models/activitypub/objects/activitypub-object.ts b/shared/models/activitypub/objects/activitypub-object.ts new file mode 100644 index 000000000..faeac2618 --- /dev/null +++ b/shared/models/activitypub/objects/activitypub-object.ts | |||
@@ -0,0 +1,17 @@ | |||
1 | import { AbuseObject } from './abuse-object' | ||
2 | import { CacheFileObject } from './cache-file-object' | ||
3 | import { PlaylistObject } from './playlist-object' | ||
4 | import { VideoCommentObject } from './video-comment-object' | ||
5 | import { VideoObject } from './video-object' | ||
6 | import { WatchActionObject } from './watch-action-object' | ||
7 | |||
8 | export type ActivityObject = | ||
9 | VideoObject | | ||
10 | AbuseObject | | ||
11 | VideoCommentObject | | ||
12 | CacheFileObject | | ||
13 | PlaylistObject | | ||
14 | WatchActionObject | | ||
15 | string | ||
16 | |||
17 | export type APObjectId = string | { id: string } | ||
diff --git a/shared/models/activitypub/objects/common-objects.ts b/shared/models/activitypub/objects/common-objects.ts index 9bf994379..db9c73658 100644 --- a/shared/models/activitypub/objects/common-objects.ts +++ b/shared/models/activitypub/objects/common-objects.ts | |||
@@ -114,10 +114,7 @@ export type ActivityUrlObject = | |||
114 | | ActivityVideoFileMetadataUrlObject | 114 | | ActivityVideoFileMetadataUrlObject |
115 | | ActivityTrackerUrlObject | 115 | | ActivityTrackerUrlObject |
116 | 116 | ||
117 | export interface ActivityPubAttributedTo { | 117 | export type ActivityPubAttributedTo = { type: 'Group' | 'Person', id: string } | string |
118 | type: 'Group' | 'Person' | ||
119 | id: string | ||
120 | } | ||
121 | 118 | ||
122 | export interface ActivityTombstoneObject { | 119 | export interface ActivityTombstoneObject { |
123 | '@context'?: any | 120 | '@context'?: any |
diff --git a/shared/models/activitypub/objects/dislike-object.ts b/shared/models/activitypub/objects/dislike-object.ts deleted file mode 100644 index 7218fb784..000000000 --- a/shared/models/activitypub/objects/dislike-object.ts +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | export interface DislikeObject { | ||
2 | id: string | ||
3 | type: 'Dislike' | ||
4 | actor: string | ||
5 | object: string | ||
6 | } | ||
diff --git a/shared/models/activitypub/objects/index.ts b/shared/models/activitypub/objects/index.ts index 9aa3c462c..753e02003 100644 --- a/shared/models/activitypub/objects/index.ts +++ b/shared/models/activitypub/objects/index.ts | |||
@@ -1,10 +1,9 @@ | |||
1 | export * from './abuse-object' | 1 | export * from './abuse-object' |
2 | export * from './activitypub-object' | ||
2 | export * from './cache-file-object' | 3 | export * from './cache-file-object' |
3 | export * from './common-objects' | 4 | export * from './common-objects' |
4 | export * from './dislike-object' | ||
5 | export * from './object.model' | ||
6 | export * from './playlist-element-object' | 5 | export * from './playlist-element-object' |
7 | export * from './playlist-object' | 6 | export * from './playlist-object' |
8 | export * from './video-comment-object' | 7 | export * from './video-comment-object' |
9 | export * from './video-torrent-object' | 8 | export * from './video-object' |
10 | export * from './watch-action-object' | 9 | export * from './watch-action-object' |
diff --git a/shared/models/activitypub/objects/object.model.ts b/shared/models/activitypub/objects/object.model.ts deleted file mode 100644 index 3fd33800a..000000000 --- a/shared/models/activitypub/objects/object.model.ts +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | export type APObject = string | { id: string } | ||
diff --git a/shared/models/activitypub/objects/playlist-object.ts b/shared/models/activitypub/objects/playlist-object.ts index 842c03790..0ccb71828 100644 --- a/shared/models/activitypub/objects/playlist-object.ts +++ b/shared/models/activitypub/objects/playlist-object.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { ActivityIconObject } from './common-objects' | 1 | import { ActivityIconObject, ActivityPubAttributedTo } from './common-objects' |
2 | 2 | ||
3 | export interface PlaylistObject { | 3 | export interface PlaylistObject { |
4 | id: string | 4 | id: string |
@@ -12,7 +12,7 @@ export interface PlaylistObject { | |||
12 | uuid: string | 12 | uuid: string |
13 | 13 | ||
14 | totalItems: number | 14 | totalItems: number |
15 | attributedTo: string[] | 15 | attributedTo: ActivityPubAttributedTo[] |
16 | 16 | ||
17 | icon?: ActivityIconObject | 17 | icon?: ActivityIconObject |
18 | 18 | ||
diff --git a/shared/models/activitypub/objects/video-comment-object.ts b/shared/models/activitypub/objects/video-comment-object.ts index ba9001730..fb1e6f8db 100644 --- a/shared/models/activitypub/objects/video-comment-object.ts +++ b/shared/models/activitypub/objects/video-comment-object.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { ActivityTagObject } from './common-objects' | 1 | import { ActivityPubAttributedTo, ActivityTagObject } from './common-objects' |
2 | 2 | ||
3 | export interface VideoCommentObject { | 3 | export interface VideoCommentObject { |
4 | type: 'Note' | 4 | type: 'Note' |
@@ -11,6 +11,6 @@ export interface VideoCommentObject { | |||
11 | published: string | 11 | published: string |
12 | updated: string | 12 | updated: string |
13 | url: string | 13 | url: string |
14 | attributedTo: string | 14 | attributedTo: ActivityPubAttributedTo |
15 | tag: ActivityTagObject[] | 15 | tag: ActivityTagObject[] |
16 | } | 16 | } |
diff --git a/shared/models/activitypub/objects/video-torrent-object.ts b/shared/models/activitypub/objects/video-object.ts index 23d54bdbd..a252a2df0 100644 --- a/shared/models/activitypub/objects/video-torrent-object.ts +++ b/shared/models/activitypub/objects/video-object.ts | |||
@@ -51,6 +51,22 @@ export interface VideoObject { | |||
51 | 51 | ||
52 | attributedTo: ActivityPubAttributedTo[] | 52 | attributedTo: ActivityPubAttributedTo[] |
53 | 53 | ||
54 | preview?: ActivityPubStoryboard[] | ||
55 | |||
54 | to?: string[] | 56 | to?: string[] |
55 | cc?: string[] | 57 | cc?: string[] |
56 | } | 58 | } |
59 | |||
60 | export interface ActivityPubStoryboard { | ||
61 | type: 'Image' | ||
62 | rel: [ 'storyboard' ] | ||
63 | url: { | ||
64 | href: string | ||
65 | mediaType: string | ||
66 | width: number | ||
67 | height: number | ||
68 | tileWidth: number | ||
69 | tileHeight: number | ||
70 | tileDuration: string | ||
71 | }[] | ||
72 | } | ||
diff --git a/shared/models/metrics/playback-metric-create.model.ts b/shared/models/metrics/playback-metric-create.model.ts index d669ab690..3a8f328c8 100644 --- a/shared/models/metrics/playback-metric-create.model.ts +++ b/shared/models/metrics/playback-metric-create.model.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { VideoResolution } from '../videos' | 1 | import { VideoResolution } from '../videos' |
2 | 2 | ||
3 | export interface PlaybackMetricCreate { | 3 | export interface PlaybackMetricCreate { |
4 | playerMode: 'p2p-media-loader' | 'webtorrent' | 4 | playerMode: 'p2p-media-loader' | 'webtorrent' | 'web-video' // FIXME: remove webtorrent player mode not used anymore in PeerTube v6 |
5 | 5 | ||
6 | resolution?: VideoResolution | 6 | resolution?: VideoResolution |
7 | fps?: number | 7 | fps?: number |
diff --git a/shared/models/plugins/client/client-hook.model.ts b/shared/models/plugins/client/client-hook.model.ts index bc3f5dd9f..4a0818c99 100644 --- a/shared/models/plugins/client/client-hook.model.ts +++ b/shared/models/plugins/client/client-hook.model.ts | |||
@@ -59,6 +59,10 @@ export const clientFilterHookObject = { | |||
59 | 'filter:internal.video-watch.player.build-options.params': true, | 59 | 'filter:internal.video-watch.player.build-options.params': true, |
60 | 'filter:internal.video-watch.player.build-options.result': true, | 60 | 'filter:internal.video-watch.player.build-options.result': true, |
61 | 61 | ||
62 | // Filter the options to load a new video in our player | ||
63 | 'filter:internal.video-watch.player.load-options.params': true, | ||
64 | 'filter:internal.video-watch.player.load-options.result': true, | ||
65 | |||
62 | // Filter our SVG icons content | 66 | // Filter our SVG icons content |
63 | 'filter:internal.common.svg-icons.get-content.params': true, | 67 | 'filter:internal.common.svg-icons.get-content.params': true, |
64 | 'filter:internal.common.svg-icons.get-content.result': true, | 68 | 'filter:internal.common.svg-icons.get-content.result': true, |
diff --git a/shared/models/search/videos-common-query.model.ts b/shared/models/search/videos-common-query.model.ts index da479c928..2c52ca8cf 100644 --- a/shared/models/search/videos-common-query.model.ts +++ b/shared/models/search/videos-common-query.model.ts | |||
@@ -30,7 +30,9 @@ export interface VideosCommonQuery { | |||
30 | tagsAllOf?: string[] | 30 | tagsAllOf?: string[] |
31 | 31 | ||
32 | hasHLSFiles?: boolean | 32 | hasHLSFiles?: boolean |
33 | hasWebtorrentFiles?: boolean | 33 | |
34 | hasWebtorrentFiles?: boolean // TODO: remove in v7 | ||
35 | hasWebVideoFiles?: boolean | ||
34 | 36 | ||
35 | skipCount?: boolean | 37 | skipCount?: boolean |
36 | 38 | ||
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts index 4202589f3..9aa66f2b8 100644 --- a/shared/models/server/custom-config.model.ts +++ b/shared/models/server/custom-config.model.ts | |||
@@ -78,6 +78,10 @@ export interface CustomConfig { | |||
78 | torrents: { | 78 | torrents: { |
79 | size: number | 79 | size: number |
80 | } | 80 | } |
81 | |||
82 | storyboards: { | ||
83 | size: number | ||
84 | } | ||
81 | } | 85 | } |
82 | 86 | ||
83 | signup: { | 87 | signup: { |
@@ -129,7 +133,7 @@ export interface CustomConfig { | |||
129 | 133 | ||
130 | alwaysTranscodeOriginalResolution: boolean | 134 | alwaysTranscodeOriginalResolution: boolean |
131 | 135 | ||
132 | webtorrent: { | 136 | webVideos: { |
133 | enabled: boolean | 137 | enabled: boolean |
134 | } | 138 | } |
135 | 139 | ||
diff --git a/shared/models/server/job.model.ts b/shared/models/server/job.model.ts index 22ecee324..c14806dab 100644 --- a/shared/models/server/job.model.ts +++ b/shared/models/server/job.model.ts | |||
@@ -30,6 +30,7 @@ export type JobType = | |||
30 | | 'video-studio-edition' | 30 | | 'video-studio-edition' |
31 | | 'video-transcoding' | 31 | | 'video-transcoding' |
32 | | 'videos-views-stats' | 32 | | 'videos-views-stats' |
33 | | 'generate-video-storyboard' | ||
33 | 34 | ||
34 | export interface Job { | 35 | export interface Job { |
35 | id: number | string | 36 | id: number | string |
@@ -147,17 +148,17 @@ export interface HLSTranscodingPayload extends BaseTranscodingPayload { | |||
147 | fps: number | 148 | fps: number |
148 | copyCodecs: boolean | 149 | copyCodecs: boolean |
149 | 150 | ||
150 | deleteWebTorrentFiles: boolean | 151 | deleteWebVideoFiles: boolean |
151 | } | 152 | } |
152 | 153 | ||
153 | export interface NewWebTorrentResolutionTranscodingPayload extends BaseTranscodingPayload { | 154 | export interface NewWebVideoResolutionTranscodingPayload extends BaseTranscodingPayload { |
154 | type: 'new-resolution-to-webtorrent' | 155 | type: 'new-resolution-to-web-video' |
155 | resolution: VideoResolution | 156 | resolution: VideoResolution |
156 | fps: number | 157 | fps: number |
157 | } | 158 | } |
158 | 159 | ||
159 | export interface MergeAudioTranscodingPayload extends BaseTranscodingPayload { | 160 | export interface MergeAudioTranscodingPayload extends BaseTranscodingPayload { |
160 | type: 'merge-audio-to-webtorrent' | 161 | type: 'merge-audio-to-web-video' |
161 | 162 | ||
162 | resolution: VideoResolution | 163 | resolution: VideoResolution |
163 | fps: number | 164 | fps: number |
@@ -166,7 +167,7 @@ export interface MergeAudioTranscodingPayload extends BaseTranscodingPayload { | |||
166 | } | 167 | } |
167 | 168 | ||
168 | export interface OptimizeTranscodingPayload extends BaseTranscodingPayload { | 169 | export interface OptimizeTranscodingPayload extends BaseTranscodingPayload { |
169 | type: 'optimize-to-webtorrent' | 170 | type: 'optimize-to-web-video' |
170 | 171 | ||
171 | quickTranscode: boolean | 172 | quickTranscode: boolean |
172 | 173 | ||
@@ -175,7 +176,7 @@ export interface OptimizeTranscodingPayload extends BaseTranscodingPayload { | |||
175 | 176 | ||
176 | export type VideoTranscodingPayload = | 177 | export type VideoTranscodingPayload = |
177 | HLSTranscodingPayload | 178 | HLSTranscodingPayload |
178 | | NewWebTorrentResolutionTranscodingPayload | 179 | | NewWebVideoResolutionTranscodingPayload |
179 | | OptimizeTranscodingPayload | 180 | | OptimizeTranscodingPayload |
180 | | MergeAudioTranscodingPayload | 181 | | MergeAudioTranscodingPayload |
181 | 182 | ||
@@ -294,3 +295,10 @@ export interface TranscodingJobBuilderPayload { | |||
294 | priority?: number | 295 | priority?: number |
295 | }[][] | 296 | }[][] |
296 | } | 297 | } |
298 | |||
299 | // --------------------------------------------------------------------------- | ||
300 | |||
301 | export interface GenerateStoryboardPayload { | ||
302 | videoUUID: string | ||
303 | federate: boolean | ||
304 | } | ||
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts index 024ed35bf..288cf84cd 100644 --- a/shared/models/server/server-config.model.ts +++ b/shared/models/server/server-config.model.ts | |||
@@ -140,7 +140,7 @@ export interface ServerConfig { | |||
140 | enabled: boolean | 140 | enabled: boolean |
141 | } | 141 | } |
142 | 142 | ||
143 | webtorrent: { | 143 | web_videos: { |
144 | enabled: boolean | 144 | enabled: boolean |
145 | } | 145 | } |
146 | 146 | ||
diff --git a/shared/models/server/server-error-code.enum.ts b/shared/models/server/server-error-code.enum.ts index 2b093380c..77d1e1d3f 100644 --- a/shared/models/server/server-error-code.enum.ts +++ b/shared/models/server/server-error-code.enum.ts | |||
@@ -49,7 +49,10 @@ export const enum ServerErrorCode { | |||
49 | 49 | ||
50 | RUNNER_JOB_NOT_IN_PROCESSING_STATE = 'runner_job_not_in_processing_state', | 50 | RUNNER_JOB_NOT_IN_PROCESSING_STATE = 'runner_job_not_in_processing_state', |
51 | RUNNER_JOB_NOT_IN_PENDING_STATE = 'runner_job_not_in_pending_state', | 51 | RUNNER_JOB_NOT_IN_PENDING_STATE = 'runner_job_not_in_pending_state', |
52 | UNKNOWN_RUNNER_TOKEN = 'unknown_runner_token' | 52 | UNKNOWN_RUNNER_TOKEN = 'unknown_runner_token', |
53 | |||
54 | VIDEO_REQUIRES_PASSWORD = 'video_requires_password', | ||
55 | INCORRECT_VIDEO_PASSWORD = 'incorrect_video_password' | ||
53 | } | 56 | } |
54 | 57 | ||
55 | /** | 58 | /** |
diff --git a/shared/models/users/user-update-me.model.ts b/shared/models/users/user-update-me.model.ts index f3cceb5f2..c1d5ffba4 100644 --- a/shared/models/users/user-update-me.model.ts +++ b/shared/models/users/user-update-me.model.ts | |||
@@ -5,8 +5,6 @@ export interface UserUpdateMe { | |||
5 | description?: string | 5 | description?: string |
6 | nsfwPolicy?: NSFWPolicyType | 6 | nsfwPolicy?: NSFWPolicyType |
7 | 7 | ||
8 | // FIXME: deprecated in favour of p2pEnabled in 4.1 | ||
9 | webTorrentEnabled?: boolean | ||
10 | p2pEnabled?: boolean | 8 | p2pEnabled?: boolean |
11 | 9 | ||
12 | autoPlayVideo?: boolean | 10 | autoPlayVideo?: boolean |
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts index 0761c1e32..9de4118b4 100644 --- a/shared/models/users/user.model.ts +++ b/shared/models/users/user.model.ts | |||
@@ -22,8 +22,6 @@ export interface User { | |||
22 | autoPlayNextVideo: boolean | 22 | autoPlayNextVideo: boolean |
23 | autoPlayNextVideoPlaylist: boolean | 23 | autoPlayNextVideoPlaylist: boolean |
24 | 24 | ||
25 | // @deprecated in favour of p2pEnabled | ||
26 | webTorrentEnabled: boolean | ||
27 | p2pEnabled: boolean | 25 | p2pEnabled: boolean |
28 | 26 | ||
29 | videosHistoryEnabled: boolean | 27 | videosHistoryEnabled: boolean |
diff --git a/shared/models/videos/index.ts b/shared/models/videos/index.ts index 4c1790228..b3ce6ad3f 100644 --- a/shared/models/videos/index.ts +++ b/shared/models/videos/index.ts | |||
@@ -15,6 +15,7 @@ export * from './channel-sync' | |||
15 | 15 | ||
16 | export * from './nsfw-policy.type' | 16 | export * from './nsfw-policy.type' |
17 | 17 | ||
18 | export * from './storyboard.model' | ||
18 | export * from './thumbnail.type' | 19 | export * from './thumbnail.type' |
19 | 20 | ||
20 | export * from './video-constant.model' | 21 | export * from './video-constant.model' |
@@ -39,3 +40,4 @@ export * from './video-update.model' | |||
39 | export * from './video-view.model' | 40 | export * from './video-view.model' |
40 | export * from './video.model' | 41 | export * from './video.model' |
41 | export * from './video-create-result.model' | 42 | export * from './video-create-result.model' |
43 | export * from './video-password.model' | ||
diff --git a/shared/models/videos/storyboard.model.ts b/shared/models/videos/storyboard.model.ts new file mode 100644 index 000000000..c92c81f09 --- /dev/null +++ b/shared/models/videos/storyboard.model.ts | |||
@@ -0,0 +1,11 @@ | |||
1 | export interface Storyboard { | ||
2 | storyboardPath: string | ||
3 | |||
4 | totalHeight: number | ||
5 | totalWidth: number | ||
6 | |||
7 | spriteHeight: number | ||
8 | spriteWidth: number | ||
9 | |||
10 | spriteDuration: number | ||
11 | } | ||
diff --git a/shared/models/videos/transcoding/video-transcoding-create.model.ts b/shared/models/videos/transcoding/video-transcoding-create.model.ts index aeb393e57..c6e756a0a 100644 --- a/shared/models/videos/transcoding/video-transcoding-create.model.ts +++ b/shared/models/videos/transcoding/video-transcoding-create.model.ts | |||
@@ -1,3 +1,3 @@ | |||
1 | export interface VideoTranscodingCreate { | 1 | export interface VideoTranscodingCreate { |
2 | transcodingType: 'hls' | 'webtorrent' | 2 | transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7 |
3 | } | 3 | } |
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts index 732d508d1..7a34b5afe 100644 --- a/shared/models/videos/video-create.model.ts +++ b/shared/models/videos/video-create.model.ts | |||
@@ -18,6 +18,7 @@ export interface VideoCreate { | |||
18 | privacy: VideoPrivacy | 18 | privacy: VideoPrivacy |
19 | scheduleUpdate?: VideoScheduleUpdate | 19 | scheduleUpdate?: VideoScheduleUpdate |
20 | originallyPublishedAt?: Date | string | 20 | originallyPublishedAt?: Date | string |
21 | videoPasswords?: string[] | ||
21 | 22 | ||
22 | thumbnailfile?: Blob | string | 23 | thumbnailfile?: Blob | string |
23 | previewfile?: Blob | string | 24 | previewfile?: Blob | string |
diff --git a/shared/models/videos/video-password.model.ts b/shared/models/videos/video-password.model.ts new file mode 100644 index 000000000..c0280b9b9 --- /dev/null +++ b/shared/models/videos/video-password.model.ts | |||
@@ -0,0 +1,7 @@ | |||
1 | export interface VideoPassword { | ||
2 | id: number | ||
3 | password: string | ||
4 | videoId: number | ||
5 | createdAt: Date | string | ||
6 | updatedAt: Date | string | ||
7 | } | ||
diff --git a/shared/models/videos/video-privacy.enum.ts b/shared/models/videos/video-privacy.enum.ts index 39fd0529f..12e1d196f 100644 --- a/shared/models/videos/video-privacy.enum.ts +++ b/shared/models/videos/video-privacy.enum.ts | |||
@@ -2,5 +2,6 @@ export const enum VideoPrivacy { | |||
2 | PUBLIC = 1, | 2 | PUBLIC = 1, |
3 | UNLISTED = 2, | 3 | UNLISTED = 2, |
4 | PRIVATE = 3, | 4 | PRIVATE = 3, |
5 | INTERNAL = 4 | 5 | INTERNAL = 4, |
6 | PASSWORD_PROTECTED = 5 | ||
6 | } | 7 | } |
diff --git a/shared/models/videos/video-update.model.ts b/shared/models/videos/video-update.model.ts index 86653b959..43537b5af 100644 --- a/shared/models/videos/video-update.model.ts +++ b/shared/models/videos/video-update.model.ts | |||
@@ -19,6 +19,7 @@ export interface VideoUpdate { | |||
19 | previewfile?: Blob | 19 | previewfile?: Blob |
20 | scheduleUpdate?: VideoScheduleUpdate | 20 | scheduleUpdate?: VideoScheduleUpdate |
21 | originallyPublishedAt?: Date | string | 21 | originallyPublishedAt?: Date | string |
22 | videoPasswords?: string[] | ||
22 | 23 | ||
23 | pluginData?: any | 24 | pluginData?: any |
24 | } | 25 | } |
diff --git a/shared/models/videos/video.model.ts b/shared/models/videos/video.model.ts index 06ffb327c..9004efb35 100644 --- a/shared/models/videos/video.model.ts +++ b/shared/models/videos/video.model.ts | |||
@@ -7,7 +7,7 @@ import { VideoScheduleUpdate } from './video-schedule-update.model' | |||
7 | import { VideoState } from './video-state.enum' | 7 | import { VideoState } from './video-state.enum' |
8 | import { VideoStreamingPlaylist } from './video-streaming-playlist.model' | 8 | import { VideoStreamingPlaylist } from './video-streaming-playlist.model' |
9 | 9 | ||
10 | export interface Video { | 10 | export interface Video extends Partial<VideoAdditionalAttributes> { |
11 | id: number | 11 | id: number |
12 | uuid: string | 12 | uuid: string |
13 | shortUUID: string | 13 | shortUUID: string |
@@ -57,20 +57,22 @@ export interface Video { | |||
57 | } | 57 | } |
58 | 58 | ||
59 | pluginData?: any | 59 | pluginData?: any |
60 | } | ||
60 | 61 | ||
61 | // Additional attributes dependending on the query | 62 | // Not included by default, needs query params |
62 | waitTranscoding?: boolean | 63 | export interface VideoAdditionalAttributes { |
63 | state?: VideoConstant<VideoState> | 64 | waitTranscoding: boolean |
64 | scheduledUpdate?: VideoScheduleUpdate | 65 | state: VideoConstant<VideoState> |
66 | scheduledUpdate: VideoScheduleUpdate | ||
65 | 67 | ||
66 | blacklisted?: boolean | 68 | blacklisted: boolean |
67 | blacklistedReason?: string | 69 | blacklistedReason: string |
68 | 70 | ||
69 | blockedOwner?: boolean | 71 | blockedOwner: boolean |
70 | blockedServer?: boolean | 72 | blockedServer: boolean |
71 | 73 | ||
72 | files?: VideoFile[] | 74 | files: VideoFile[] |
73 | streamingPlaylists?: VideoStreamingPlaylist[] | 75 | streamingPlaylists: VideoStreamingPlaylist[] |
74 | } | 76 | } |
75 | 77 | ||
76 | export interface VideoDetails extends Video { | 78 | export interface VideoDetails extends Video { |
diff --git a/shared/server-commands/requests/requests.ts b/shared/server-commands/requests/requests.ts index e3f1817f1..8227017eb 100644 --- a/shared/server-commands/requests/requests.ts +++ b/shared/server-commands/requests/requests.ts | |||
@@ -29,6 +29,7 @@ function makeRawRequest (options: { | |||
29 | range?: string | 29 | range?: string |
30 | query?: { [ id: string ]: string } | 30 | query?: { [ id: string ]: string } |
31 | method?: 'GET' | 'POST' | 31 | method?: 'GET' | 'POST' |
32 | headers?: { [ name: string ]: string } | ||
32 | }) { | 33 | }) { |
33 | const { host, protocol, pathname } = new URL(options.url) | 34 | const { host, protocol, pathname } = new URL(options.url) |
34 | 35 | ||
@@ -37,7 +38,7 @@ function makeRawRequest (options: { | |||
37 | path: pathname, | 38 | path: pathname, |
38 | contentType: undefined, | 39 | contentType: undefined, |
39 | 40 | ||
40 | ...pick(options, [ 'expectedStatus', 'range', 'token', 'query' ]) | 41 | ...pick(options, [ 'expectedStatus', 'range', 'token', 'query', 'headers' ]) |
41 | } | 42 | } |
42 | 43 | ||
43 | if (options.method === 'POST') { | 44 | if (options.method === 'POST') { |
@@ -132,6 +133,7 @@ function makePutBodyRequest (options: { | |||
132 | token?: string | 133 | token?: string |
133 | fields: { [ fieldName: string ]: any } | 134 | fields: { [ fieldName: string ]: any } |
134 | expectedStatus?: HttpStatusCode | 135 | expectedStatus?: HttpStatusCode |
136 | headers?: { [name: string]: string } | ||
135 | }) { | 137 | }) { |
136 | const req = request(options.url).put(options.path) | 138 | const req = request(options.url).put(options.path) |
137 | .send(options.fields) | 139 | .send(options.fields) |
diff --git a/shared/server-commands/server/config-command.ts b/shared/server-commands/server/config-command.ts index b94bd2625..7f1e9d977 100644 --- a/shared/server-commands/server/config-command.ts +++ b/shared/server-commands/server/config-command.ts | |||
@@ -131,7 +131,7 @@ export class ConfigCommand extends AbstractCommand { | |||
131 | } | 131 | } |
132 | 132 | ||
133 | // TODO: convert args to object | 133 | // TODO: convert args to object |
134 | enableTranscoding (webtorrent = true, hls = true, with0p = false) { | 134 | enableTranscoding (webVideo = true, hls = true, with0p = false) { |
135 | return this.updateExistingSubConfig({ | 135 | return this.updateExistingSubConfig({ |
136 | newConfig: { | 136 | newConfig: { |
137 | transcoding: { | 137 | transcoding: { |
@@ -142,8 +142,8 @@ export class ConfigCommand extends AbstractCommand { | |||
142 | 142 | ||
143 | resolutions: ConfigCommand.getCustomConfigResolutions(true, with0p), | 143 | resolutions: ConfigCommand.getCustomConfigResolutions(true, with0p), |
144 | 144 | ||
145 | webtorrent: { | 145 | webVideos: { |
146 | enabled: webtorrent | 146 | enabled: webVideo |
147 | }, | 147 | }, |
148 | hls: { | 148 | hls: { |
149 | enabled: hls | 149 | enabled: hls |
@@ -154,19 +154,23 @@ export class ConfigCommand extends AbstractCommand { | |||
154 | } | 154 | } |
155 | 155 | ||
156 | // TODO: convert args to object | 156 | // TODO: convert args to object |
157 | enableMinimumTranscoding (webtorrent = true, hls = true) { | 157 | enableMinimumTranscoding (webVideo = true, hls = true) { |
158 | return this.updateExistingSubConfig({ | 158 | return this.updateExistingSubConfig({ |
159 | newConfig: { | 159 | newConfig: { |
160 | transcoding: { | 160 | transcoding: { |
161 | enabled: true, | 161 | enabled: true, |
162 | |||
163 | allowAudioFiles: true, | ||
164 | allowAdditionalExtensions: true, | ||
165 | |||
162 | resolutions: { | 166 | resolutions: { |
163 | ...ConfigCommand.getCustomConfigResolutions(false), | 167 | ...ConfigCommand.getCustomConfigResolutions(false), |
164 | 168 | ||
165 | '240p': true | 169 | '240p': true |
166 | }, | 170 | }, |
167 | 171 | ||
168 | webtorrent: { | 172 | webVideos: { |
169 | enabled: webtorrent | 173 | enabled: webVideo |
170 | }, | 174 | }, |
171 | hls: { | 175 | hls: { |
172 | enabled: hls | 176 | enabled: hls |
@@ -368,6 +372,9 @@ export class ConfigCommand extends AbstractCommand { | |||
368 | }, | 372 | }, |
369 | torrents: { | 373 | torrents: { |
370 | size: 4 | 374 | size: 4 |
375 | }, | ||
376 | storyboards: { | ||
377 | size: 5 | ||
371 | } | 378 | } |
372 | }, | 379 | }, |
373 | signup: { | 380 | signup: { |
@@ -417,7 +424,7 @@ export class ConfigCommand extends AbstractCommand { | |||
417 | '2160p': false | 424 | '2160p': false |
418 | }, | 425 | }, |
419 | alwaysTranscodeOriginalResolution: true, | 426 | alwaysTranscodeOriginalResolution: true, |
420 | webtorrent: { | 427 | webVideos: { |
421 | enabled: true | 428 | enabled: true |
422 | }, | 429 | }, |
423 | hls: { | 430 | hls: { |
diff --git a/shared/server-commands/server/jobs.ts b/shared/server-commands/server/jobs.ts index ff3098063..8f131fba4 100644 --- a/shared/server-commands/server/jobs.ts +++ b/shared/server-commands/server/jobs.ts | |||
@@ -33,6 +33,8 @@ async function waitJobs ( | |||
33 | 33 | ||
34 | // Check if each server has pending request | 34 | // Check if each server has pending request |
35 | for (const server of servers) { | 35 | for (const server of servers) { |
36 | if (process.env.DEBUG) console.log('Checking ' + server.url) | ||
37 | |||
36 | for (const state of states) { | 38 | for (const state of states) { |
37 | 39 | ||
38 | const jobPromise = server.jobs.list({ | 40 | const jobPromise = server.jobs.list({ |
@@ -45,6 +47,10 @@ async function waitJobs ( | |||
45 | .then(jobs => { | 47 | .then(jobs => { |
46 | if (jobs.length !== 0) { | 48 | if (jobs.length !== 0) { |
47 | pendingRequests = true | 49 | pendingRequests = true |
50 | |||
51 | if (process.env.DEBUG) { | ||
52 | console.log(jobs) | ||
53 | } | ||
48 | } | 54 | } |
49 | }) | 55 | }) |
50 | 56 | ||
@@ -55,6 +61,10 @@ async function waitJobs ( | |||
55 | .then(obj => { | 61 | .then(obj => { |
56 | if (obj.activityPubMessagesWaiting !== 0) { | 62 | if (obj.activityPubMessagesWaiting !== 0) { |
57 | pendingRequests = true | 63 | pendingRequests = true |
64 | |||
65 | if (process.env.DEBUG) { | ||
66 | console.log('AP messages waiting: ' + obj.activityPubMessagesWaiting) | ||
67 | } | ||
58 | } | 68 | } |
59 | }) | 69 | }) |
60 | tasks.push(debugPromise) | 70 | tasks.push(debugPromise) |
@@ -65,12 +75,15 @@ async function waitJobs ( | |||
65 | for (const job of data) { | 75 | for (const job of data) { |
66 | if (job.state.id !== RunnerJobState.COMPLETED) { | 76 | if (job.state.id !== RunnerJobState.COMPLETED) { |
67 | pendingRequests = true | 77 | pendingRequests = true |
78 | |||
79 | if (process.env.DEBUG) { | ||
80 | console.log(job) | ||
81 | } | ||
68 | } | 82 | } |
69 | } | 83 | } |
70 | }) | 84 | }) |
71 | tasks.push(runnerJobsPromise) | 85 | tasks.push(runnerJobsPromise) |
72 | } | 86 | } |
73 | |||
74 | } | 87 | } |
75 | 88 | ||
76 | return tasks | 89 | return tasks |
diff --git a/shared/server-commands/server/object-storage-command.ts b/shared/server-commands/server/object-storage-command.ts index 7d8ec93cd..6bb232c36 100644 --- a/shared/server-commands/server/object-storage-command.ts +++ b/shared/server-commands/server/object-storage-command.ts | |||
@@ -42,7 +42,7 @@ export class ObjectStorageCommand { | |||
42 | bucket_name: this.getMockStreamingPlaylistsBucketName() | 42 | bucket_name: this.getMockStreamingPlaylistsBucketName() |
43 | }, | 43 | }, |
44 | 44 | ||
45 | videos: { | 45 | web_videos: { |
46 | bucket_name: this.getMockWebVideosBucketName() | 46 | bucket_name: this.getMockWebVideosBucketName() |
47 | } | 47 | } |
48 | } | 48 | } |
@@ -136,9 +136,9 @@ export class ObjectStorageCommand { | |||
136 | prefix: `test:server-${serverNumber}-streaming-playlists:` | 136 | prefix: `test:server-${serverNumber}-streaming-playlists:` |
137 | }, | 137 | }, |
138 | 138 | ||
139 | videos: { | 139 | web_videos: { |
140 | bucket_name: this.DEFAULT_SCALEWAY_BUCKET, | 140 | bucket_name: this.DEFAULT_SCALEWAY_BUCKET, |
141 | prefix: `test:server-${serverNumber}-videos:` | 141 | prefix: `test:server-${serverNumber}-web-videos:` |
142 | } | 142 | } |
143 | } | 143 | } |
144 | } | 144 | } |
diff --git a/shared/server-commands/server/server.ts b/shared/server-commands/server/server.ts index 70f7a3ee2..38568a890 100644 --- a/shared/server-commands/server/server.ts +++ b/shared/server-commands/server/server.ts | |||
@@ -32,8 +32,10 @@ import { | |||
32 | HistoryCommand, | 32 | HistoryCommand, |
33 | ImportsCommand, | 33 | ImportsCommand, |
34 | LiveCommand, | 34 | LiveCommand, |
35 | VideoPasswordsCommand, | ||
35 | PlaylistsCommand, | 36 | PlaylistsCommand, |
36 | ServicesCommand, | 37 | ServicesCommand, |
38 | StoryboardCommand, | ||
37 | StreamingPlaylistsCommand, | 39 | StreamingPlaylistsCommand, |
38 | VideosCommand, | 40 | VideosCommand, |
39 | VideoStudioCommand, | 41 | VideoStudioCommand, |
@@ -146,6 +148,9 @@ export class PeerTubeServer { | |||
146 | twoFactor?: TwoFactorCommand | 148 | twoFactor?: TwoFactorCommand |
147 | videoToken?: VideoTokenCommand | 149 | videoToken?: VideoTokenCommand |
148 | registrations?: RegistrationsCommand | 150 | registrations?: RegistrationsCommand |
151 | videoPasswords?: VideoPasswordsCommand | ||
152 | |||
153 | storyboard?: StoryboardCommand | ||
149 | 154 | ||
150 | runners?: RunnersCommand | 155 | runners?: RunnersCommand |
151 | runnerRegistrationTokens?: RunnerRegistrationTokensCommand | 156 | runnerRegistrationTokens?: RunnerRegistrationTokensCommand |
@@ -232,7 +237,7 @@ export class PeerTubeServer { | |||
232 | } | 237 | } |
233 | 238 | ||
234 | // Share the environment | 239 | // Share the environment |
235 | const env = Object.create(process.env) | 240 | const env = { ...process.env } |
236 | env['NODE_ENV'] = 'test' | 241 | env['NODE_ENV'] = 'test' |
237 | env['NODE_APP_INSTANCE'] = this.internalServerNumber.toString() | 242 | env['NODE_APP_INSTANCE'] = this.internalServerNumber.toString() |
238 | env['NODE_CONFIG'] = JSON.stringify(configOverride) | 243 | env['NODE_CONFIG'] = JSON.stringify(configOverride) |
@@ -365,12 +370,13 @@ export class PeerTubeServer { | |||
365 | tmp_persistent: this.getDirectoryPath('tmp-persistent') + '/', | 370 | tmp_persistent: this.getDirectoryPath('tmp-persistent') + '/', |
366 | bin: this.getDirectoryPath('bin') + '/', | 371 | bin: this.getDirectoryPath('bin') + '/', |
367 | avatars: this.getDirectoryPath('avatars') + '/', | 372 | avatars: this.getDirectoryPath('avatars') + '/', |
368 | videos: this.getDirectoryPath('videos') + '/', | 373 | web_videos: this.getDirectoryPath('web-videos') + '/', |
369 | streaming_playlists: this.getDirectoryPath('streaming-playlists') + '/', | 374 | streaming_playlists: this.getDirectoryPath('streaming-playlists') + '/', |
370 | redundancy: this.getDirectoryPath('redundancy') + '/', | 375 | redundancy: this.getDirectoryPath('redundancy') + '/', |
371 | logs: this.getDirectoryPath('logs') + '/', | 376 | logs: this.getDirectoryPath('logs') + '/', |
372 | previews: this.getDirectoryPath('previews') + '/', | 377 | previews: this.getDirectoryPath('previews') + '/', |
373 | thumbnails: this.getDirectoryPath('thumbnails') + '/', | 378 | thumbnails: this.getDirectoryPath('thumbnails') + '/', |
379 | storyboards: this.getDirectoryPath('storyboards') + '/', | ||
374 | torrents: this.getDirectoryPath('torrents') + '/', | 380 | torrents: this.getDirectoryPath('torrents') + '/', |
375 | captions: this.getDirectoryPath('captions') + '/', | 381 | captions: this.getDirectoryPath('captions') + '/', |
376 | cache: this.getDirectoryPath('cache') + '/', | 382 | cache: this.getDirectoryPath('cache') + '/', |
@@ -434,8 +440,11 @@ export class PeerTubeServer { | |||
434 | this.videoToken = new VideoTokenCommand(this) | 440 | this.videoToken = new VideoTokenCommand(this) |
435 | this.registrations = new RegistrationsCommand(this) | 441 | this.registrations = new RegistrationsCommand(this) |
436 | 442 | ||
443 | this.storyboard = new StoryboardCommand(this) | ||
444 | |||
437 | this.runners = new RunnersCommand(this) | 445 | this.runners = new RunnersCommand(this) |
438 | this.runnerRegistrationTokens = new RunnerRegistrationTokensCommand(this) | 446 | this.runnerRegistrationTokens = new RunnerRegistrationTokensCommand(this) |
439 | this.runnerJobs = new RunnerJobsCommand(this) | 447 | this.runnerJobs = new RunnerJobsCommand(this) |
448 | this.videoPasswords = new VideoPasswordsCommand(this) | ||
440 | } | 449 | } |
441 | } | 450 | } |
diff --git a/shared/server-commands/server/servers-command.ts b/shared/server-commands/server/servers-command.ts index 19645cb93..c91c2b008 100644 --- a/shared/server-commands/server/servers-command.ts +++ b/shared/server-commands/server/servers-command.ts | |||
@@ -77,8 +77,8 @@ export class ServersCommand extends AbstractCommand { | |||
77 | return join(root(), 'test' + this.server.internalServerNumber, directory) | 77 | return join(root(), 'test' + this.server.internalServerNumber, directory) |
78 | } | 78 | } |
79 | 79 | ||
80 | buildWebTorrentFilePath (fileUrl: string) { | 80 | buildWebVideoFilePath (fileUrl: string) { |
81 | return this.buildDirectory(join('videos', basename(fileUrl))) | 81 | return this.buildDirectory(join('web-videos', basename(fileUrl))) |
82 | } | 82 | } |
83 | 83 | ||
84 | buildFragmentedFilePath (videoUUID: string, fileUrl: string) { | 84 | buildFragmentedFilePath (videoUUID: string, fileUrl: string) { |
diff --git a/shared/server-commands/shared/abstract-command.ts b/shared/server-commands/shared/abstract-command.ts index ca4ffada9..463acc26b 100644 --- a/shared/server-commands/shared/abstract-command.ts +++ b/shared/server-commands/shared/abstract-command.ts | |||
@@ -101,25 +101,29 @@ abstract class AbstractCommand { | |||
101 | 101 | ||
102 | protected putBodyRequest (options: InternalCommonCommandOptions & { | 102 | protected putBodyRequest (options: InternalCommonCommandOptions & { |
103 | fields?: { [ fieldName: string ]: any } | 103 | fields?: { [ fieldName: string ]: any } |
104 | headers?: { [name: string]: string } | ||
104 | }) { | 105 | }) { |
105 | const { fields } = options | 106 | const { fields, headers } = options |
106 | 107 | ||
107 | return makePutBodyRequest({ | 108 | return makePutBodyRequest({ |
108 | ...this.buildCommonRequestOptions(options), | 109 | ...this.buildCommonRequestOptions(options), |
109 | 110 | ||
110 | fields | 111 | fields, |
112 | headers | ||
111 | }) | 113 | }) |
112 | } | 114 | } |
113 | 115 | ||
114 | protected postBodyRequest (options: InternalCommonCommandOptions & { | 116 | protected postBodyRequest (options: InternalCommonCommandOptions & { |
115 | fields?: { [ fieldName: string ]: any } | 117 | fields?: { [ fieldName: string ]: any } |
118 | headers?: { [name: string]: string } | ||
116 | }) { | 119 | }) { |
117 | const { fields } = options | 120 | const { fields, headers } = options |
118 | 121 | ||
119 | return makePostBodyRequest({ | 122 | return makePostBodyRequest({ |
120 | ...this.buildCommonRequestOptions(options), | 123 | ...this.buildCommonRequestOptions(options), |
121 | 124 | ||
122 | fields | 125 | fields, |
126 | headers | ||
123 | }) | 127 | }) |
124 | } | 128 | } |
125 | 129 | ||
@@ -206,6 +210,12 @@ abstract class AbstractCommand { | |||
206 | 210 | ||
207 | return expectedStatus !== undefined ? expectedStatus : defaultExpectedStatus | 211 | return expectedStatus !== undefined ? expectedStatus : defaultExpectedStatus |
208 | } | 212 | } |
213 | |||
214 | protected buildVideoPasswordHeader (videoPassword: string) { | ||
215 | return videoPassword !== undefined && videoPassword !== null | ||
216 | ? { 'x-peertube-video-password': videoPassword } | ||
217 | : undefined | ||
218 | } | ||
209 | } | 219 | } |
210 | 220 | ||
211 | export { | 221 | export { |
diff --git a/shared/server-commands/videos/captions-command.ts b/shared/server-commands/videos/captions-command.ts index 62bf9c5e6..a26fcb57d 100644 --- a/shared/server-commands/videos/captions-command.ts +++ b/shared/server-commands/videos/captions-command.ts | |||
@@ -34,14 +34,16 @@ export class CaptionsCommand extends AbstractCommand { | |||
34 | 34 | ||
35 | list (options: OverrideCommandOptions & { | 35 | list (options: OverrideCommandOptions & { |
36 | videoId: string | number | 36 | videoId: string | number |
37 | videoPassword?: string | ||
37 | }) { | 38 | }) { |
38 | const { videoId } = options | 39 | const { videoId, videoPassword } = options |
39 | const path = '/api/v1/videos/' + videoId + '/captions' | 40 | const path = '/api/v1/videos/' + videoId + '/captions' |
40 | 41 | ||
41 | return this.getRequestBody<ResultList<VideoCaption>>({ | 42 | return this.getRequestBody<ResultList<VideoCaption>>({ |
42 | ...options, | 43 | ...options, |
43 | 44 | ||
44 | path, | 45 | path, |
46 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
45 | implicitToken: false, | 47 | implicitToken: false, |
46 | defaultExpectedStatus: HttpStatusCode.OK_200 | 48 | defaultExpectedStatus: HttpStatusCode.OK_200 |
47 | }) | 49 | }) |
diff --git a/shared/server-commands/videos/comments-command.ts b/shared/server-commands/videos/comments-command.ts index 154ec0c24..0dab1b66a 100644 --- a/shared/server-commands/videos/comments-command.ts +++ b/shared/server-commands/videos/comments-command.ts | |||
@@ -36,11 +36,12 @@ export class CommentsCommand extends AbstractCommand { | |||
36 | 36 | ||
37 | listThreads (options: OverrideCommandOptions & { | 37 | listThreads (options: OverrideCommandOptions & { |
38 | videoId: number | string | 38 | videoId: number | string |
39 | videoPassword?: string | ||
39 | start?: number | 40 | start?: number |
40 | count?: number | 41 | count?: number |
41 | sort?: string | 42 | sort?: string |
42 | }) { | 43 | }) { |
43 | const { start, count, sort, videoId } = options | 44 | const { start, count, sort, videoId, videoPassword } = options |
44 | const path = '/api/v1/videos/' + videoId + '/comment-threads' | 45 | const path = '/api/v1/videos/' + videoId + '/comment-threads' |
45 | 46 | ||
46 | return this.getRequestBody<VideoCommentThreads>({ | 47 | return this.getRequestBody<VideoCommentThreads>({ |
@@ -48,6 +49,7 @@ export class CommentsCommand extends AbstractCommand { | |||
48 | 49 | ||
49 | path, | 50 | path, |
50 | query: { start, count, sort }, | 51 | query: { start, count, sort }, |
52 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
51 | implicitToken: false, | 53 | implicitToken: false, |
52 | defaultExpectedStatus: HttpStatusCode.OK_200 | 54 | defaultExpectedStatus: HttpStatusCode.OK_200 |
53 | }) | 55 | }) |
@@ -72,8 +74,9 @@ export class CommentsCommand extends AbstractCommand { | |||
72 | async createThread (options: OverrideCommandOptions & { | 74 | async createThread (options: OverrideCommandOptions & { |
73 | videoId: number | string | 75 | videoId: number | string |
74 | text: string | 76 | text: string |
77 | videoPassword?: string | ||
75 | }) { | 78 | }) { |
76 | const { videoId, text } = options | 79 | const { videoId, text, videoPassword } = options |
77 | const path = '/api/v1/videos/' + videoId + '/comment-threads' | 80 | const path = '/api/v1/videos/' + videoId + '/comment-threads' |
78 | 81 | ||
79 | const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ | 82 | const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ |
@@ -81,6 +84,7 @@ export class CommentsCommand extends AbstractCommand { | |||
81 | 84 | ||
82 | path, | 85 | path, |
83 | fields: { text }, | 86 | fields: { text }, |
87 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
84 | implicitToken: true, | 88 | implicitToken: true, |
85 | defaultExpectedStatus: HttpStatusCode.OK_200 | 89 | defaultExpectedStatus: HttpStatusCode.OK_200 |
86 | })) | 90 | })) |
@@ -95,8 +99,9 @@ export class CommentsCommand extends AbstractCommand { | |||
95 | videoId: number | string | 99 | videoId: number | string |
96 | toCommentId: number | 100 | toCommentId: number |
97 | text: string | 101 | text: string |
102 | videoPassword?: string | ||
98 | }) { | 103 | }) { |
99 | const { videoId, toCommentId, text } = options | 104 | const { videoId, toCommentId, text, videoPassword } = options |
100 | const path = '/api/v1/videos/' + videoId + '/comments/' + toCommentId | 105 | const path = '/api/v1/videos/' + videoId + '/comments/' + toCommentId |
101 | 106 | ||
102 | const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ | 107 | const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({ |
@@ -104,6 +109,7 @@ export class CommentsCommand extends AbstractCommand { | |||
104 | 109 | ||
105 | path, | 110 | path, |
106 | fields: { text }, | 111 | fields: { text }, |
112 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
107 | implicitToken: true, | 113 | implicitToken: true, |
108 | defaultExpectedStatus: HttpStatusCode.OK_200 | 114 | defaultExpectedStatus: HttpStatusCode.OK_200 |
109 | })) | 115 | })) |
diff --git a/shared/server-commands/videos/index.ts b/shared/server-commands/videos/index.ts index c17f6ef20..106d80af0 100644 --- a/shared/server-commands/videos/index.ts +++ b/shared/server-commands/videos/index.ts | |||
@@ -11,9 +11,11 @@ export * from './live-command' | |||
11 | export * from './live' | 11 | export * from './live' |
12 | export * from './playlists-command' | 12 | export * from './playlists-command' |
13 | export * from './services-command' | 13 | export * from './services-command' |
14 | export * from './storyboard-command' | ||
14 | export * from './streaming-playlists-command' | 15 | export * from './streaming-playlists-command' |
15 | export * from './comments-command' | 16 | export * from './comments-command' |
16 | export * from './video-studio-command' | 17 | export * from './video-studio-command' |
17 | export * from './video-token-command' | 18 | export * from './video-token-command' |
18 | export * from './views-command' | 19 | export * from './views-command' |
19 | export * from './videos-command' | 20 | export * from './videos-command' |
21 | export * from './video-passwords-command' | ||
diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index 44d625970..6006d9fe9 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts | |||
@@ -120,8 +120,13 @@ export class LiveCommand extends AbstractCommand { | |||
120 | saveReplay: boolean | 120 | saveReplay: boolean |
121 | permanentLive: boolean | 121 | permanentLive: boolean |
122 | privacy?: VideoPrivacy | 122 | privacy?: VideoPrivacy |
123 | videoPasswords?: string[] | ||
123 | }) { | 124 | }) { |
124 | const { saveReplay, permanentLive, privacy = VideoPrivacy.PUBLIC } = options | 125 | const { saveReplay, permanentLive, privacy = VideoPrivacy.PUBLIC, videoPasswords } = options |
126 | |||
127 | const replaySettings = privacy === VideoPrivacy.PASSWORD_PROTECTED | ||
128 | ? { privacy: VideoPrivacy.PRIVATE } | ||
129 | : { privacy } | ||
125 | 130 | ||
126 | const { uuid } = await this.create({ | 131 | const { uuid } = await this.create({ |
127 | ...options, | 132 | ...options, |
@@ -130,9 +135,10 @@ export class LiveCommand extends AbstractCommand { | |||
130 | name: 'live', | 135 | name: 'live', |
131 | permanentLive, | 136 | permanentLive, |
132 | saveReplay, | 137 | saveReplay, |
133 | replaySettings: { privacy }, | 138 | replaySettings, |
134 | channelId: this.server.store.channel.id, | 139 | channelId: this.server.store.channel.id, |
135 | privacy | 140 | privacy, |
141 | videoPasswords | ||
136 | } | 142 | } |
137 | }) | 143 | }) |
138 | 144 | ||
diff --git a/shared/server-commands/videos/storyboard-command.ts b/shared/server-commands/videos/storyboard-command.ts new file mode 100644 index 000000000..06d90fc12 --- /dev/null +++ b/shared/server-commands/videos/storyboard-command.ts | |||
@@ -0,0 +1,19 @@ | |||
1 | import { HttpStatusCode, Storyboard } from '@shared/models' | ||
2 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | ||
3 | |||
4 | export class StoryboardCommand extends AbstractCommand { | ||
5 | |||
6 | list (options: OverrideCommandOptions & { | ||
7 | id: number | string | ||
8 | }) { | ||
9 | const path = '/api/v1/videos/' + options.id + '/storyboards' | ||
10 | |||
11 | return this.getRequestBody<{ storyboards: Storyboard[] }>({ | ||
12 | ...options, | ||
13 | |||
14 | path, | ||
15 | implicitToken: true, | ||
16 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
17 | }) | ||
18 | } | ||
19 | } | ||
diff --git a/shared/server-commands/videos/video-passwords-command.ts b/shared/server-commands/videos/video-passwords-command.ts new file mode 100644 index 000000000..bf10335b4 --- /dev/null +++ b/shared/server-commands/videos/video-passwords-command.ts | |||
@@ -0,0 +1,55 @@ | |||
1 | import { HttpStatusCode, ResultList, VideoPassword } from '@shared/models' | ||
2 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | ||
3 | export class VideoPasswordsCommand extends AbstractCommand { | ||
4 | |||
5 | list (options: OverrideCommandOptions & { | ||
6 | videoId: number | string | ||
7 | start?: number | ||
8 | count?: number | ||
9 | sort?: string | ||
10 | }) { | ||
11 | const { start, count, sort, videoId } = options | ||
12 | const path = '/api/v1/videos/' + videoId + '/passwords' | ||
13 | |||
14 | return this.getRequestBody<ResultList<VideoPassword>>({ | ||
15 | ...options, | ||
16 | |||
17 | path, | ||
18 | query: { start, count, sort }, | ||
19 | implicitToken: true, | ||
20 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
21 | }) | ||
22 | } | ||
23 | |||
24 | updateAll (options: OverrideCommandOptions & { | ||
25 | videoId: number | string | ||
26 | passwords: string[] | ||
27 | }) { | ||
28 | const { videoId, passwords } = options | ||
29 | const path = `/api/v1/videos/${videoId}/passwords` | ||
30 | |||
31 | return this.putBodyRequest({ | ||
32 | ...options, | ||
33 | path, | ||
34 | fields: { passwords }, | ||
35 | implicitToken: true, | ||
36 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
37 | }) | ||
38 | } | ||
39 | |||
40 | remove (options: OverrideCommandOptions & { | ||
41 | id: number | ||
42 | videoId: number | string | ||
43 | }) { | ||
44 | const { id, videoId } = options | ||
45 | const path = `/api/v1/videos/${videoId}/passwords/${id}` | ||
46 | |||
47 | return this.deleteRequest({ | ||
48 | ...options, | ||
49 | |||
50 | path, | ||
51 | implicitToken: true, | ||
52 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
53 | }) | ||
54 | } | ||
55 | } | ||
diff --git a/shared/server-commands/videos/video-studio-command.ts b/shared/server-commands/videos/video-studio-command.ts index 9fe467cc2..675cd84b7 100644 --- a/shared/server-commands/videos/video-studio-command.ts +++ b/shared/server-commands/videos/video-studio-command.ts | |||
@@ -25,7 +25,7 @@ export class VideoStudioCommand extends AbstractCommand { | |||
25 | { | 25 | { |
26 | name: 'add-watermark', | 26 | name: 'add-watermark', |
27 | options: { | 27 | options: { |
28 | file: 'thumbnail.png' | 28 | file: 'custom-thumbnail.png' |
29 | } | 29 | } |
30 | }, | 30 | }, |
31 | 31 | ||
diff --git a/shared/server-commands/videos/video-token-command.ts b/shared/server-commands/videos/video-token-command.ts index 0531bee65..c4ed29a8c 100644 --- a/shared/server-commands/videos/video-token-command.ts +++ b/shared/server-commands/videos/video-token-command.ts | |||
@@ -8,12 +8,14 @@ export class VideoTokenCommand extends AbstractCommand { | |||
8 | 8 | ||
9 | create (options: OverrideCommandOptions & { | 9 | create (options: OverrideCommandOptions & { |
10 | videoId: number | string | 10 | videoId: number | string |
11 | videoPassword?: string | ||
11 | }) { | 12 | }) { |
12 | const { videoId } = options | 13 | const { videoId, videoPassword } = options |
13 | const path = '/api/v1/videos/' + videoId + '/token' | 14 | const path = '/api/v1/videos/' + videoId + '/token' |
14 | 15 | ||
15 | return unwrapBody<VideoToken>(this.postBodyRequest({ | 16 | return unwrapBody<VideoToken>(this.postBodyRequest({ |
16 | ...options, | 17 | ...options, |
18 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
17 | 19 | ||
18 | path, | 20 | path, |
19 | implicitToken: true, | 21 | implicitToken: true, |
@@ -23,6 +25,7 @@ export class VideoTokenCommand extends AbstractCommand { | |||
23 | 25 | ||
24 | async getVideoFileToken (options: OverrideCommandOptions & { | 26 | async getVideoFileToken (options: OverrideCommandOptions & { |
25 | videoId: number | string | 27 | videoId: number | string |
28 | videoPassword?: string | ||
26 | }) { | 29 | }) { |
27 | const { files } = await this.create(options) | 30 | const { files } = await this.create(options) |
28 | 31 | ||
diff --git a/shared/server-commands/videos/videos-command.ts b/shared/server-commands/videos/videos-command.ts index b5df9c325..9602fa7da 100644 --- a/shared/server-commands/videos/videos-command.ts +++ b/shared/server-commands/videos/videos-command.ts | |||
@@ -111,8 +111,9 @@ export class VideosCommand extends AbstractCommand { | |||
111 | rate (options: OverrideCommandOptions & { | 111 | rate (options: OverrideCommandOptions & { |
112 | id: number | string | 112 | id: number | string |
113 | rating: UserVideoRateType | 113 | rating: UserVideoRateType |
114 | videoPassword?: string | ||
114 | }) { | 115 | }) { |
115 | const { id, rating } = options | 116 | const { id, rating, videoPassword } = options |
116 | const path = '/api/v1/videos/' + id + '/rate' | 117 | const path = '/api/v1/videos/' + id + '/rate' |
117 | 118 | ||
118 | return this.putBodyRequest({ | 119 | return this.putBodyRequest({ |
@@ -120,6 +121,7 @@ export class VideosCommand extends AbstractCommand { | |||
120 | 121 | ||
121 | path, | 122 | path, |
122 | fields: { rating }, | 123 | fields: { rating }, |
124 | headers: this.buildVideoPasswordHeader(videoPassword), | ||
123 | implicitToken: true, | 125 | implicitToken: true, |
124 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 | 126 | defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 |
125 | }) | 127 | }) |
@@ -151,6 +153,23 @@ export class VideosCommand extends AbstractCommand { | |||
151 | }) | 153 | }) |
152 | } | 154 | } |
153 | 155 | ||
156 | getWithPassword (options: OverrideCommandOptions & { | ||
157 | id: number | string | ||
158 | password?: string | ||
159 | }) { | ||
160 | const path = '/api/v1/videos/' + options.id | ||
161 | |||
162 | return this.getRequestBody<VideoDetails>({ | ||
163 | ...options, | ||
164 | headers:{ | ||
165 | 'x-peertube-video-password': options.password | ||
166 | }, | ||
167 | path, | ||
168 | implicitToken: false, | ||
169 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
170 | }) | ||
171 | } | ||
172 | |||
154 | getSource (options: OverrideCommandOptions & { | 173 | getSource (options: OverrideCommandOptions & { |
155 | id: number | string | 174 | id: number | string |
156 | }) { | 175 | }) { |
@@ -608,11 +627,13 @@ export class VideosCommand extends AbstractCommand { | |||
608 | nsfw?: boolean | 627 | nsfw?: boolean |
609 | privacy?: VideoPrivacy | 628 | privacy?: VideoPrivacy |
610 | fixture?: string | 629 | fixture?: string |
630 | videoPasswords?: string[] | ||
611 | }) { | 631 | }) { |
612 | const attributes: VideoEdit = { name: options.name } | 632 | const attributes: VideoEdit = { name: options.name } |
613 | if (options.nsfw) attributes.nsfw = options.nsfw | 633 | if (options.nsfw) attributes.nsfw = options.nsfw |
614 | if (options.privacy) attributes.privacy = options.privacy | 634 | if (options.privacy) attributes.privacy = options.privacy |
615 | if (options.fixture) attributes.fixture = options.fixture | 635 | if (options.fixture) attributes.fixture = options.fixture |
636 | if (options.videoPasswords) attributes.videoPasswords = options.videoPasswords | ||
616 | 637 | ||
617 | return this.upload({ ...options, attributes }) | 638 | return this.upload({ ...options, attributes }) |
618 | } | 639 | } |
@@ -665,10 +686,10 @@ export class VideosCommand extends AbstractCommand { | |||
665 | }) | 686 | }) |
666 | } | 687 | } |
667 | 688 | ||
668 | removeAllWebTorrentFiles (options: OverrideCommandOptions & { | 689 | removeAllWebVideoFiles (options: OverrideCommandOptions & { |
669 | videoId: number | string | 690 | videoId: number | string |
670 | }) { | 691 | }) { |
671 | const path = '/api/v1/videos/' + options.videoId + '/webtorrent' | 692 | const path = '/api/v1/videos/' + options.videoId + '/web-videos' |
672 | 693 | ||
673 | return this.deleteRequest({ | 694 | return this.deleteRequest({ |
674 | ...options, | 695 | ...options, |
@@ -679,11 +700,11 @@ export class VideosCommand extends AbstractCommand { | |||
679 | }) | 700 | }) |
680 | } | 701 | } |
681 | 702 | ||
682 | removeWebTorrentFile (options: OverrideCommandOptions & { | 703 | removeWebVideoFile (options: OverrideCommandOptions & { |
683 | videoId: number | string | 704 | videoId: number | string |
684 | fileId: number | 705 | fileId: number |
685 | }) { | 706 | }) { |
686 | const path = '/api/v1/videos/' + options.videoId + '/webtorrent/' + options.fileId | 707 | const path = '/api/v1/videos/' + options.videoId + '/web-videos/' + options.fileId |
687 | 708 | ||
688 | return this.deleteRequest({ | 709 | return this.deleteRequest({ |
689 | ...options, | 710 | ...options, |
@@ -696,7 +717,7 @@ export class VideosCommand extends AbstractCommand { | |||
696 | 717 | ||
697 | runTranscoding (options: OverrideCommandOptions & { | 718 | runTranscoding (options: OverrideCommandOptions & { |
698 | videoId: number | string | 719 | videoId: number | string |
699 | transcodingType: 'hls' | 'webtorrent' | 720 | transcodingType: 'hls' | 'webtorrent' | 'web-video' |
700 | }) { | 721 | }) { |
701 | const path = '/api/v1/videos/' + options.videoId + '/transcoding' | 722 | const path = '/api/v1/videos/' + options.videoId + '/transcoding' |
702 | 723 | ||