diff options
Diffstat (limited to 'shared/server-commands/videos')
-rw-r--r-- | shared/server-commands/videos/blacklist-command.ts | 3 | ||||
-rw-r--r-- | shared/server-commands/videos/captions-command.ts | 2 | ||||
-rw-r--r-- | shared/server-commands/videos/captions.ts | 21 | ||||
-rw-r--r-- | shared/server-commands/videos/channels-command.ts | 12 | ||||
-rw-r--r-- | shared/server-commands/videos/index.ts | 4 | ||||
-rw-r--r-- | shared/server-commands/videos/live-command.ts | 2 | ||||
-rw-r--r-- | shared/server-commands/videos/live.ts | 41 | ||||
-rw-r--r-- | shared/server-commands/videos/playlists.ts | 25 | ||||
-rw-r--r-- | shared/server-commands/videos/streaming-playlists.ts | 77 | ||||
-rw-r--r-- | shared/server-commands/videos/videos-command.ts | 4 | ||||
-rw-r--r-- | shared/server-commands/videos/videos.ts | 104 |
11 files changed, 15 insertions, 280 deletions
diff --git a/shared/server-commands/videos/blacklist-command.ts b/shared/server-commands/videos/blacklist-command.ts index 3a2ef89ba..47e23ebc8 100644 --- a/shared/server-commands/videos/blacklist-command.ts +++ b/shared/server-commands/videos/blacklist-command.ts | |||
@@ -1,6 +1,5 @@ | |||
1 | 1 | ||
2 | import { HttpStatusCode, ResultList } from '@shared/models' | 2 | import { HttpStatusCode, ResultList, VideoBlacklist, VideoBlacklistType } from '@shared/models' |
3 | import { VideoBlacklist, VideoBlacklistType } from '../../models/videos' | ||
4 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 3 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
5 | 4 | ||
6 | export class BlacklistCommand extends AbstractCommand { | 5 | export class BlacklistCommand extends AbstractCommand { |
diff --git a/shared/server-commands/videos/captions-command.ts b/shared/server-commands/videos/captions-command.ts index a65ea99e3..62bf9c5e6 100644 --- a/shared/server-commands/videos/captions-command.ts +++ b/shared/server-commands/videos/captions-command.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { buildAbsoluteFixturePath } from '@shared/core-utils' | ||
1 | import { HttpStatusCode, ResultList, VideoCaption } from '@shared/models' | 2 | import { HttpStatusCode, ResultList, VideoCaption } from '@shared/models' |
2 | import { buildAbsoluteFixturePath } from '../miscs' | ||
3 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 3 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
4 | 4 | ||
5 | export class CaptionsCommand extends AbstractCommand { | 5 | export class CaptionsCommand extends AbstractCommand { |
diff --git a/shared/server-commands/videos/captions.ts b/shared/server-commands/videos/captions.ts deleted file mode 100644 index 35e722408..000000000 --- a/shared/server-commands/videos/captions.ts +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | import { expect } from 'chai' | ||
2 | import request from 'supertest' | ||
3 | import { HttpStatusCode } from '@shared/models' | ||
4 | |||
5 | async function testCaptionFile (url: string, captionPath: string, toTest: RegExp | string) { | ||
6 | const res = await request(url) | ||
7 | .get(captionPath) | ||
8 | .expect(HttpStatusCode.OK_200) | ||
9 | |||
10 | if (toTest instanceof RegExp) { | ||
11 | expect(res.text).to.match(toTest) | ||
12 | } else { | ||
13 | expect(res.text).to.contain(toTest) | ||
14 | } | ||
15 | } | ||
16 | |||
17 | // --------------------------------------------------------------------------- | ||
18 | |||
19 | export { | ||
20 | testCaptionFile | ||
21 | } | ||
diff --git a/shared/server-commands/videos/channels-command.ts b/shared/server-commands/videos/channels-command.ts index e406e570b..8ab124658 100644 --- a/shared/server-commands/videos/channels-command.ts +++ b/shared/server-commands/videos/channels-command.ts | |||
@@ -1,7 +1,13 @@ | |||
1 | import { pick } from '@shared/core-utils' | 1 | import { pick } from '@shared/core-utils' |
2 | import { ActorFollow, HttpStatusCode, ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models' | 2 | import { |
3 | import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' | 3 | ActorFollow, |
4 | import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' | 4 | HttpStatusCode, |
5 | ResultList, | ||
6 | VideoChannel, | ||
7 | VideoChannelCreate, | ||
8 | VideoChannelCreateResult, | ||
9 | VideoChannelUpdate | ||
10 | } from '@shared/models' | ||
5 | import { unwrapBody } from '../requests' | 11 | import { unwrapBody } from '../requests' |
6 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 12 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
7 | 13 | ||
diff --git a/shared/server-commands/videos/index.ts b/shared/server-commands/videos/index.ts index 26e663f46..68a188b21 100644 --- a/shared/server-commands/videos/index.ts +++ b/shared/server-commands/videos/index.ts | |||
@@ -1,6 +1,5 @@ | |||
1 | export * from './blacklist-command' | 1 | export * from './blacklist-command' |
2 | export * from './captions-command' | 2 | export * from './captions-command' |
3 | export * from './captions' | ||
4 | export * from './change-ownership-command' | 3 | export * from './change-ownership-command' |
5 | export * from './channels' | 4 | export * from './channels' |
6 | export * from './channels-command' | 5 | export * from './channels-command' |
@@ -10,10 +9,7 @@ export * from './imports-command' | |||
10 | export * from './live-command' | 9 | export * from './live-command' |
11 | export * from './live' | 10 | export * from './live' |
12 | export * from './playlists-command' | 11 | export * from './playlists-command' |
13 | export * from './playlists' | ||
14 | export * from './services-command' | 12 | export * from './services-command' |
15 | export * from './streaming-playlists-command' | 13 | export * from './streaming-playlists-command' |
16 | export * from './streaming-playlists' | ||
17 | export * from './comments-command' | 14 | export * from './comments-command' |
18 | export * from './videos-command' | 15 | export * from './videos-command' |
19 | export * from './videos' | ||
diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index 74f5d3089..f7816eca0 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts | |||
@@ -3,8 +3,8 @@ | |||
3 | import { readdir } from 'fs-extra' | 3 | import { readdir } from 'fs-extra' |
4 | import { omit } from 'lodash' | 4 | import { omit } from 'lodash' |
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { wait } from '@shared/core-utils' | ||
6 | import { HttpStatusCode, LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' | 7 | import { HttpStatusCode, LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' |
7 | import { wait } from '../miscs' | ||
8 | import { unwrapBody } from '../requests' | 8 | import { unwrapBody } from '../requests' |
9 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 9 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
10 | import { sendRTMPStream, testFfmpegStreamError } from './live' | 10 | import { sendRTMPStream, testFfmpegStreamError } from './live' |
diff --git a/shared/server-commands/videos/live.ts b/shared/server-commands/videos/live.ts index d3665bc90..7a7faa911 100644 --- a/shared/server-commands/videos/live.ts +++ b/shared/server-commands/videos/live.ts | |||
@@ -1,10 +1,5 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import ffmpeg, { FfmpegCommand } from 'fluent-ffmpeg' | 1 | import ffmpeg, { FfmpegCommand } from 'fluent-ffmpeg' |
5 | import { pathExists, readdir } from 'fs-extra' | 2 | import { buildAbsoluteFixturePath, wait } from '@shared/core-utils' |
6 | import { join } from 'path' | ||
7 | import { buildAbsoluteFixturePath, wait } from '../miscs' | ||
8 | import { PeerTubeServer } from '../server/server' | 3 | import { PeerTubeServer } from '../server/server' |
9 | 4 | ||
10 | function sendRTMPStream (options: { | 5 | function sendRTMPStream (options: { |
@@ -95,43 +90,11 @@ async function waitUntilLiveSavedOnAllServers (servers: PeerTubeServer[], videoI | |||
95 | } | 90 | } |
96 | } | 91 | } |
97 | 92 | ||
98 | async function checkLiveCleanupAfterSave (server: PeerTubeServer, videoUUID: string, resolutions: number[] = []) { | ||
99 | const basePath = server.servers.buildDirectory('streaming-playlists') | ||
100 | const hlsPath = join(basePath, 'hls', videoUUID) | ||
101 | |||
102 | if (resolutions.length === 0) { | ||
103 | const result = await pathExists(hlsPath) | ||
104 | expect(result).to.be.false | ||
105 | |||
106 | return | ||
107 | } | ||
108 | |||
109 | const files = await readdir(hlsPath) | ||
110 | |||
111 | // fragmented file and playlist per resolution + master playlist + segments sha256 json file | ||
112 | expect(files).to.have.lengthOf(resolutions.length * 2 + 2) | ||
113 | |||
114 | for (const resolution of resolutions) { | ||
115 | const fragmentedFile = files.find(f => f.endsWith(`-${resolution}-fragmented.mp4`)) | ||
116 | expect(fragmentedFile).to.exist | ||
117 | |||
118 | const playlistFile = files.find(f => f.endsWith(`${resolution}.m3u8`)) | ||
119 | expect(playlistFile).to.exist | ||
120 | } | ||
121 | |||
122 | const masterPlaylistFile = files.find(f => f.endsWith('-master.m3u8')) | ||
123 | expect(masterPlaylistFile).to.exist | ||
124 | |||
125 | const shaFile = files.find(f => f.endsWith('-segments-sha256.json')) | ||
126 | expect(shaFile).to.exist | ||
127 | } | ||
128 | |||
129 | export { | 93 | export { |
130 | sendRTMPStream, | 94 | sendRTMPStream, |
131 | waitFfmpegUntilError, | 95 | waitFfmpegUntilError, |
132 | testFfmpegStreamError, | 96 | testFfmpegStreamError, |
133 | stopFfmpeg, | 97 | stopFfmpeg, |
134 | waitUntilLivePublishedOnAllServers, | 98 | waitUntilLivePublishedOnAllServers, |
135 | waitUntilLiveSavedOnAllServers, | 99 | waitUntilLiveSavedOnAllServers |
136 | checkLiveCleanupAfterSave | ||
137 | } | 100 | } |
diff --git a/shared/server-commands/videos/playlists.ts b/shared/server-commands/videos/playlists.ts deleted file mode 100644 index 3dde52bb9..000000000 --- a/shared/server-commands/videos/playlists.ts +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | import { expect } from 'chai' | ||
2 | import { readdir } from 'fs-extra' | ||
3 | import { join } from 'path' | ||
4 | import { root } from '../miscs' | ||
5 | |||
6 | async function checkPlaylistFilesWereRemoved ( | ||
7 | playlistUUID: string, | ||
8 | internalServerNumber: number, | ||
9 | directories = [ 'thumbnails' ] | ||
10 | ) { | ||
11 | const testDirectory = 'test' + internalServerNumber | ||
12 | |||
13 | for (const directory of directories) { | ||
14 | const directoryPath = join(root(), testDirectory, directory) | ||
15 | |||
16 | const files = await readdir(directoryPath) | ||
17 | for (const file of files) { | ||
18 | expect(file).to.not.contain(playlistUUID) | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | |||
23 | export { | ||
24 | checkPlaylistFilesWereRemoved | ||
25 | } | ||
diff --git a/shared/server-commands/videos/streaming-playlists.ts b/shared/server-commands/videos/streaming-playlists.ts deleted file mode 100644 index 0451c0efe..000000000 --- a/shared/server-commands/videos/streaming-playlists.ts +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | import { expect } from 'chai' | ||
2 | import { basename } from 'path' | ||
3 | import { sha256 } from '@shared/core-utils/crypto' | ||
4 | import { removeFragmentedMP4Ext } from '@shared/core-utils' | ||
5 | import { HttpStatusCode, VideoStreamingPlaylist } from '@shared/models' | ||
6 | import { PeerTubeServer } from '../server' | ||
7 | |||
8 | async function checkSegmentHash (options: { | ||
9 | server: PeerTubeServer | ||
10 | baseUrlPlaylist: string | ||
11 | baseUrlSegment: string | ||
12 | resolution: number | ||
13 | hlsPlaylist: VideoStreamingPlaylist | ||
14 | }) { | ||
15 | const { server, baseUrlPlaylist, baseUrlSegment, resolution, hlsPlaylist } = options | ||
16 | const command = server.streamingPlaylists | ||
17 | |||
18 | const file = hlsPlaylist.files.find(f => f.resolution.id === resolution) | ||
19 | const videoName = basename(file.fileUrl) | ||
20 | |||
21 | const playlist = await command.get({ url: `${baseUrlPlaylist}/${removeFragmentedMP4Ext(videoName)}.m3u8` }) | ||
22 | |||
23 | const matches = /#EXT-X-BYTERANGE:(\d+)@(\d+)/.exec(playlist) | ||
24 | |||
25 | const length = parseInt(matches[1], 10) | ||
26 | const offset = parseInt(matches[2], 10) | ||
27 | const range = `${offset}-${offset + length - 1}` | ||
28 | |||
29 | const segmentBody = await command.getSegment({ | ||
30 | url: `${baseUrlSegment}/${videoName}`, | ||
31 | expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, | ||
32 | range: `bytes=${range}` | ||
33 | }) | ||
34 | |||
35 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | ||
36 | expect(sha256(segmentBody)).to.equal(shaBody[videoName][range]) | ||
37 | } | ||
38 | |||
39 | async function checkLiveSegmentHash (options: { | ||
40 | server: PeerTubeServer | ||
41 | baseUrlSegment: string | ||
42 | videoUUID: string | ||
43 | segmentName: string | ||
44 | hlsPlaylist: VideoStreamingPlaylist | ||
45 | }) { | ||
46 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options | ||
47 | const command = server.streamingPlaylists | ||
48 | |||
49 | const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) | ||
50 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | ||
51 | |||
52 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) | ||
53 | } | ||
54 | |||
55 | async function checkResolutionsInMasterPlaylist (options: { | ||
56 | server: PeerTubeServer | ||
57 | playlistUrl: string | ||
58 | resolutions: number[] | ||
59 | }) { | ||
60 | const { server, playlistUrl, resolutions } = options | ||
61 | |||
62 | const masterPlaylist = await server.streamingPlaylists.get({ url: playlistUrl }) | ||
63 | |||
64 | for (const resolution of resolutions) { | ||
65 | const reg = new RegExp( | ||
66 | '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' | ||
67 | ) | ||
68 | |||
69 | expect(masterPlaylist).to.match(reg) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | export { | ||
74 | checkSegmentHash, | ||
75 | checkLiveSegmentHash, | ||
76 | checkResolutionsInMasterPlaylist | ||
77 | } | ||
diff --git a/shared/server-commands/videos/videos-command.ts b/shared/server-commands/videos/videos-command.ts index 8ea828b40..ead57b9aa 100644 --- a/shared/server-commands/videos/videos-command.ts +++ b/shared/server-commands/videos/videos-command.ts | |||
@@ -5,8 +5,7 @@ import { createReadStream, stat } from 'fs-extra' | |||
5 | import got, { Response as GotResponse } from 'got' | 5 | import got, { Response as GotResponse } from 'got' |
6 | import { omit } from 'lodash' | 6 | import { omit } from 'lodash' |
7 | import validator from 'validator' | 7 | import validator from 'validator' |
8 | import { buildUUID } from '@shared/core-utils/uuid' | 8 | import { buildAbsoluteFixturePath, buildUUID, pick, wait } from '@shared/core-utils' |
9 | import { pick } from '@shared/core-utils' | ||
10 | import { | 9 | import { |
11 | HttpStatusCode, | 10 | HttpStatusCode, |
12 | ResultList, | 11 | ResultList, |
@@ -20,7 +19,6 @@ import { | |||
20 | VideosCommonQuery, | 19 | VideosCommonQuery, |
21 | VideoTranscodingCreate | 20 | VideoTranscodingCreate |
22 | } from '@shared/models' | 21 | } from '@shared/models' |
23 | import { buildAbsoluteFixturePath, wait } from '../miscs' | ||
24 | import { unwrapBody } from '../requests' | 22 | import { unwrapBody } from '../requests' |
25 | import { waitJobs } from '../server' | 23 | import { waitJobs } from '../server' |
26 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 24 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
diff --git a/shared/server-commands/videos/videos.ts b/shared/server-commands/videos/videos.ts deleted file mode 100644 index 2c3464aa8..000000000 --- a/shared/server-commands/videos/videos.ts +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { pathExists, readdir } from 'fs-extra' | ||
5 | import { basename, join } from 'path' | ||
6 | import { HttpStatusCode, VideoCaption, VideoDetails } from '@shared/models' | ||
7 | import { waitJobs } from '../server' | ||
8 | import { PeerTubeServer } from '../server/server' | ||
9 | import { VideoEdit } from './videos-command' | ||
10 | |||
11 | async function checkVideoFilesWereRemoved (options: { | ||
12 | server: PeerTubeServer | ||
13 | video: VideoDetails | ||
14 | captions?: VideoCaption[] | ||
15 | onlyVideoFiles?: boolean // default false | ||
16 | }) { | ||
17 | const { video, server, captions = [], onlyVideoFiles = false } = options | ||
18 | |||
19 | const webtorrentFiles = video.files || [] | ||
20 | const hlsFiles = video.streamingPlaylists[0]?.files || [] | ||
21 | |||
22 | const thumbnailName = basename(video.thumbnailPath) | ||
23 | const previewName = basename(video.previewPath) | ||
24 | |||
25 | const torrentNames = webtorrentFiles.concat(hlsFiles).map(f => basename(f.torrentUrl)) | ||
26 | |||
27 | const captionNames = captions.map(c => basename(c.captionPath)) | ||
28 | |||
29 | const webtorrentFilenames = webtorrentFiles.map(f => basename(f.fileUrl)) | ||
30 | const hlsFilenames = hlsFiles.map(f => basename(f.fileUrl)) | ||
31 | |||
32 | let directories: { [ directory: string ]: string[] } = { | ||
33 | videos: webtorrentFilenames, | ||
34 | redundancy: webtorrentFilenames, | ||
35 | [join('playlists', 'hls')]: hlsFilenames, | ||
36 | [join('redundancy', 'hls')]: hlsFilenames | ||
37 | } | ||
38 | |||
39 | if (onlyVideoFiles !== true) { | ||
40 | directories = { | ||
41 | ...directories, | ||
42 | |||
43 | thumbnails: [ thumbnailName ], | ||
44 | previews: [ previewName ], | ||
45 | torrents: torrentNames, | ||
46 | captions: captionNames | ||
47 | } | ||
48 | } | ||
49 | |||
50 | for (const directory of Object.keys(directories)) { | ||
51 | const directoryPath = server.servers.buildDirectory(directory) | ||
52 | |||
53 | const directoryExists = await pathExists(directoryPath) | ||
54 | if (directoryExists === false) continue | ||
55 | |||
56 | const existingFiles = await readdir(directoryPath) | ||
57 | for (const existingFile of existingFiles) { | ||
58 | for (const shouldNotExist of directories[directory]) { | ||
59 | expect(existingFile, `File ${existingFile} should not exist in ${directoryPath}`).to.not.contain(shouldNotExist) | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
65 | async function saveVideoInServers (servers: PeerTubeServer[], uuid: string) { | ||
66 | for (const server of servers) { | ||
67 | server.store.videoDetails = await server.videos.get({ id: uuid }) | ||
68 | } | ||
69 | } | ||
70 | |||
71 | function checkUploadVideoParam ( | ||
72 | server: PeerTubeServer, | ||
73 | token: string, | ||
74 | attributes: Partial<VideoEdit>, | ||
75 | expectedStatus = HttpStatusCode.OK_200, | ||
76 | mode: 'legacy' | 'resumable' = 'legacy' | ||
77 | ) { | ||
78 | return mode === 'legacy' | ||
79 | ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus }) | ||
80 | : server.videos.buildResumeUpload({ token, attributes, expectedStatus }) | ||
81 | } | ||
82 | |||
83 | // serverNumber starts from 1 | ||
84 | async function uploadRandomVideoOnServers ( | ||
85 | servers: PeerTubeServer[], | ||
86 | serverNumber: number, | ||
87 | additionalParams?: VideoEdit & { prefixName?: string } | ||
88 | ) { | ||
89 | const server = servers.find(s => s.serverNumber === serverNumber) | ||
90 | const res = await server.videos.randomUpload({ wait: false, additionalParams }) | ||
91 | |||
92 | await waitJobs(servers) | ||
93 | |||
94 | return res | ||
95 | } | ||
96 | |||
97 | // --------------------------------------------------------------------------- | ||
98 | |||
99 | export { | ||
100 | checkUploadVideoParam, | ||
101 | uploadRandomVideoOnServers, | ||
102 | checkVideoFilesWereRemoved, | ||
103 | saveVideoInServers | ||
104 | } | ||