<h3 align="right">Communities that help each other</h3>
<p align="right">
-In addition to visitors using WebTorrent to share the load among them, instances can help each other by caching one another's videos. This way even small instances have a way to show content to a wider audience, as they will be shouldered by friend instances (more about that in our <a href="https://docs.joinpeertube.org/contribute/architecture#redundancy-between-instances">redundancy guide</a>).
+In addition to visitors using P2P with WebRTC to share the load among them, instances can help each other by caching one another's videos. This way even small instances have a way to show content to a wider audience, as they will be shouldered by friend instances (more about that in our <a href="https://docs.joinpeertube.org/contribute/architecture#redundancy-between-instances">redundancy guide</a>).
</p>
<p align="right">
Content creators can get help from their viewers in the simplest way possible: a support button showing a message linking to their donation accounts or really anything else. No more pay-per-view and advertisements that hurt visitors and alter creativity (more about that in our <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/FAQ.md">FAQ</a>).
return loginPage.loginOnPeerTube2()
})
- it('Should play an internal webtorrent video', async () => {
- await go(FIXTURE_URLS.INTERNAL_WEBTORRENT_VIDEO)
+ it('Should play an internal web video video', async () => {
+ await go(FIXTURE_URLS.INTERNAL_WEB_VIDEO)
await videoWatchPage.waitWatchVideoName(internalVideoName)
await checkCorrectlyPlay(playerPage)
await checkCorrectlyPlay(playerPage)
})
- it('Should play an internal WebTorrent video in embed', async () => {
- await go(FIXTURE_URLS.INTERNAL_EMBED_WEBTORRENT_VIDEO)
+ it('Should play an internal Web Video in embed', async () => {
+ await go(FIXTURE_URLS.INTERNAL_EMBED_WEB_VIDEO)
await videoWatchPage.waitEmbedForDisplayed()
await checkCorrectlyPlay(playerPage)
let videoNameToExcept = videoName
if (isMobileDevice() || isSafari()) {
- await go(FIXTURE_URLS.WEBTORRENT_VIDEO)
+ await go(FIXTURE_URLS.WEB_VIDEO)
videoNameToExcept = 'E2E tests'
} else {
await videoListPage.clickOnVideo(videoName)
await videoWatchPage.waitUntilVideoName(video2Name, 40 * 1000)
})
- it('Should watch the webtorrent playlist in the embed', async () => {
+ it('Should watch the WEB VIDEO playlist in the embed', async () => {
if (isUploadUnsupported()) return
const accessToken = await browser.execute(`return window.localStorage.getItem('access_token');`)
const FIXTURE_URLS = {
- INTERNAL_WEBTORRENT_VIDEO: 'https://peertube2.cpy.re/w/pwfz7NizSdPD4mJcbbmNwa?mode=webtorrent&start=0',
+ INTERNAL_WEB_VIDEO: 'https://peertube2.cpy.re/w/pwfz7NizSdPD4mJcbbmNwa?mode=web-video&start=0',
INTERNAL_HLS_VIDEO: 'https://peertube2.cpy.re/w/pwfz7NizSdPD4mJcbbmNwa?start=0',
- INTERNAL_EMBED_WEBTORRENT_VIDEO: 'https://peertube2.cpy.re/videos/embed/pwfz7NizSdPD4mJcbbmNwa?mode=webtorrent&start=0',
+ INTERNAL_EMBED_WEB_VIDEO: 'https://peertube2.cpy.re/videos/embed/pwfz7NizSdPD4mJcbbmNwa?mode=web-video&start=0',
INTERNAL_EMBED_HLS_VIDEO: 'https://peertube2.cpy.re/videos/embed/pwfz7NizSdPD4mJcbbmNwa?start=0',
INTERNAL_HLS_ONLY_VIDEO: 'https://peertube2.cpy.re/w/tKQmHcqdYZRdCszLUiWM3V?start=0',
INTERNAL_EMBED_HLS_ONLY_VIDEO: 'https://peertube2.cpy.re/videos/embed/tKQmHcqdYZRdCszLUiWM3V?start=0',
- WEBTORRENT_VIDEO: 'https://peertube2.cpy.re/w/122d093a-1ede-43bd-bd34-59d2931ffc5e',
+ WEB_VIDEO: 'https://peertube2.cpy.re/w/122d093a-1ede-43bd-bd34-59d2931ffc5e',
HLS_EMBED: 'https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50',
HLS_PLAYLIST_EMBED: 'https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a',
specFileRetries: 0,
capabilities: [
- {
- 'browserName': 'chrome',
- 'acceptInsecureCerts': true,
- 'goog:chromeOptions': {
- args: [ '--disable-gpu', windowSizeArg ],
- prefs
- }
- },
+ // {
+ // 'browserName': 'chrome',
+ // 'acceptInsecureCerts': true,
+ // 'goog:chromeOptions': {
+ // args: [ '--disable-gpu', windowSizeArg ],
+ // prefs
+ // }
+ // },
{
'browserName': 'firefox',
'moz:firefoxOptions': {
binary: '/usr/bin/firefox-developer-edition',
- args: [ '--headless', windowSizeArg ],
+ // args: [ '--headless', windowSizeArg ],
prefs
}
<div class="form-group" [ngClass]="getTranscodingDisabledClass()">
<my-peertube-checkbox
inputName="transcodingWebTorrentEnabled" formControlName="enabled"
- i18n-labelText labelText="WebTorrent enabled"
+ i18n-labelText labelText="Web Videos enabled"
>
<ng-template ptTemplate="help">
<ng-container>
<ng-container i18n>
<strong>Requires ffmpeg >= 4.1</strong>
- <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with plain WebTorrent:</p>
+ <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with Web Videos:</p>
<ul>
<li>Resolution change is smoother</li>
<li>Faster playback especially with long videos</li>
<li>More stable playback (less bugs/infinite loading)</li>
</ul>
- <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p>
+ <p>If you also enabled Web Videos support, it will multiply videos storage by 2</p>
</ng-container>
</ng-template>
</my-peertube-checkbox>
title: $localize`Video files`,
children: [
{
- value: 'webtorrent:true isLocal:true',
- label: $localize`With WebTorrent`
+ value: 'webVideos:true isLocal:true',
+ label: $localize`With Web Videos`
},
{
- value: 'webtorrent:false isLocal:true',
- label: $localize`Without WebTorrent`
+ value: 'webVideos:false isLocal:true',
+ label: $localize`Without Web Videos`
},
{
value: 'hls:true isLocal:true',
prefix: 'hls:',
isBoolean: true
},
- hasWebtorrentFiles: {
- prefix: 'webtorrent:',
+ hasWebVideoFiles: {
+ prefix: 'webVideos:',
isBoolean: true
},
isLive: {
</td>
<td>
- <span *ngIf="isHLS(video)" class="pt-badge badge-blue">HLS</span>
- <span *ngIf="isWebTorrent(video)" class="pt-badge badge-blue">WebTorrent ({{ video.files.length }})</span>
+ <span *ngIf="hasHLS(video)" class="pt-badge badge-blue">HLS</span>
+ <span *ngIf="hasWebVideos(video)" class="pt-badge badge-blue">Web Videos ({{ video.files.length }})</span>
<span i18n *ngIf="video.isLive" class="pt-badge badge-blue">Live</span>
<span i18n *ngIf="hasObjectStorage(video)" class="pt-badge badge-purple">Object storage</span>
<tr>
<td class="video-info expand-cell" myAutoColspan>
<div>
- <div *ngIf="isWebTorrent(video)">
- WebTorrent:
+ <div *ngIf="hasWebVideos(video)">
+ Web Videos:
<ul>
<li *ngFor="let file of video.files">
<my-global-icon
*ngIf="canRemoveOneFile(video)"
i18n-ngbTooltip ngbTooltip="Delete this file" iconName="delete" role="button"
- (click)="removeVideoFile(video, file, 'webtorrent')"
+ (click)="removeVideoFile(video, file, 'web-videos')"
></my-global-icon>
</li>
</ul>
</div>
- <div *ngIf="isHLS(video)">
+ <div *ngIf="hasHLS(video)">
HLS:
<ul>
iconName: 'cog'
},
{
- label: $localize`Run WebTorrent transcoding`,
- handler: videos => this.runTranscoding(videos, 'webtorrent'),
+ label: $localize`Run Web Video transcoding`,
+ handler: videos => this.runTranscoding(videos, 'web-video'),
isDisplayed: videos => videos.every(v => v.canRunTranscoding(this.authUser)),
iconName: 'cog'
},
iconName: 'delete'
},
{
- label: $localize`Delete WebTorrent files`,
- handler: videos => this.removeVideoFiles(videos, 'webtorrent'),
+ label: $localize`Delete Web Video files`,
+ handler: videos => this.removeVideoFiles(videos, 'web-videos'),
isDisplayed: videos => videos.every(v => v.canRemoveFiles(this.authUser)),
iconName: 'delete'
}
return video.state.id === VideoState.TO_IMPORT
}
- isHLS (video: Video) {
+ hasHLS (video: Video) {
const p = video.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
if (!p) return false
return p.files.length !== 0
}
- isWebTorrent (video: Video) {
+ hasWebVideos (video: Video) {
return video.files.length !== 0
}
getFilesSize (video: Video) {
let files = video.files
- if (this.isHLS(video)) {
+ if (this.hasHLS(video)) {
files = files.concat(video.streamingPlaylists[0].files)
}
return files.reduce((p, f) => p += f.size, 0)
}
- async removeVideoFile (video: Video, file: VideoFile, type: 'hls' | 'webtorrent') {
+ async removeVideoFile (video: Video, file: VideoFile, type: 'hls' | 'web-videos') {
const message = $localize`Are you sure you want to delete this ${file.resolution.label} file?`
const res = await this.confirmService.confirm(message, $localize`Delete file`)
if (res === false) return
})
}
- private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') {
+ private async removeVideoFiles (videos: Video[], type: 'hls' | 'web-videos') {
let message: string
if (type === 'hls') {
} else {
// eslint-disable-next-line max-len
message = formatICU(
- $localize`Are you sure you want to delete WebTorrent files of {count, plural, =1 {1 video} other {{count} videos}}?`,
+ $localize`Are you sure you want to delete Web Video files of {count, plural, =1 {1 video} other {{count} videos}}?`,
{ count: videos.length }
)
}
})
}
- private runTranscoding (videos: Video[], type: 'hls' | 'webtorrent') {
+ private runTranscoding (videos: Video[], type: 'hls' | 'web-video') {
this.videoService.runTranscoding(videos.map(v => v.id), type)
.subscribe({
next: () => {
autoPlayNextVideoPlaylist: boolean
p2pEnabled: boolean
- // FIXME: deprecated in 4.1
- webTorrentEnabled: never
videosHistoryEnabled: boolean
videoLanguages: string[]
user && user.hasRight(UserRight.MANAGE_VIDEO_FILES) &&
this.state.id !== VideoState.TO_TRANSCODE &&
this.hasHLS() &&
- this.hasWebTorrent()
+ this.hasWebVideos()
}
canRunTranscoding (user: AuthUser) {
return this.streamingPlaylists?.some(p => p.type === VideoStreamingPlaylistType.HLS)
}
- hasWebTorrent () {
+ hasWebVideos () {
return this.files && this.files.length !== 0
}
)
}
- removeVideoFiles (videoIds: (number | string)[], type: 'hls' | 'webtorrent') {
+ removeVideoFiles (videoIds: (number | string)[], type: 'hls' | 'web-videos') {
return from(videoIds)
.pipe(
concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id + '/' + type)),
)
}
- removeFile (videoId: number | string, fileId: number, type: 'hls' | 'webtorrent') {
+ removeFile (videoId: number | string, fileId: number, type: 'hls' | 'web-videos') {
return this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + videoId + '/' + type + '/' + fileId)
.pipe(catchError(err => this.restExtractor.handleError(err)))
}
- runTranscoding (videoIds: (number | string)[], type: 'hls' | 'webtorrent') {
+ runTranscoding (videoIds: (number | string)[], type: 'hls' | 'web-video') {
const body: VideoTranscodingCreate = { transcodingType: type }
return from(videoIds)
})
}
- async removeVideoFiles (video: Video, type: 'hls' | 'webtorrent') {
+ async removeVideoFiles (video: Video, type: 'hls' | 'web-videos') {
const confirmMessage = $localize`Do you really want to remove "${this.video.name}" files?`
const res = await this.confirmService.confirm(confirmMessage, $localize`Remove "${this.video.name}" files`)
})
}
- runTranscoding (video: Video, type: 'hls' | 'webtorrent') {
+ runTranscoding (video: Video, type: 'hls' | 'web-video') {
this.videoService.runTranscoding([ video.id ], type)
.subscribe({
next: () => {
iconName: 'cog'
},
{
- label: $localize`Run WebTorrent transcoding`,
- handler: ({ video }) => this.runTranscoding(video, 'webtorrent'),
+ label: $localize`Run Web Video transcoding`,
+ handler: ({ video }) => this.runTranscoding(video, 'web-video'),
isDisplayed: () => this.displayOptions.transcoding && this.canRunTranscoding(),
iconName: 'cog'
},
iconName: 'delete'
},
{
- label: $localize`Delete WebTorrent files`,
- handler: ({ video }) => this.removeVideoFiles(video, 'webtorrent'),
+ label: $localize`Delete Web Video files`,
+ handler: ({ video }) => this.removeVideoFiles(video, 'web-videos'),
isDisplayed: () => this.displayOptions.removeFiles && this.canRemoveVideoFiles(),
iconName: 'delete'
}
# Useful when you want to use a CDN/external proxy
base_url: '' # Example: 'https://mirror.example.com'
- # Same settings but for webtorrent videos
+ # Same settings but for web videos
videos:
bucket_name: 'videos'
prefix: ''
# Transcode and keep original resolution, even if it's above your maximum enabled resolution
always_transcode_original_resolution: true
- # Generate videos in a WebTorrent format (what we do since the first PeerTube release)
+ # Generate videos in a web compatible format
# If you also enabled the hls format, it will multiply videos storage by 2
# If disabled, breaks federation with PeerTube instances < 2.1
webtorrent:
enabled: false
# /!\ Requires ffmpeg >= 4.1
- # Generate HLS playlists and fragmented MP4 files. Better playback than with WebTorrent:
+ # Generate HLS playlists and fragmented MP4 files. Better playback than with Web Videos:
# * Resolution change is smoother
# * Faster playback in particular with long videos
# * More stable playback (less bugs/infinite loading)
- # If you also enabled the webtorrent format, it will multiply videos storage by 2
+ # If you also enabled the web videos format, it will multiply videos storage by 2
hls:
enabled: true
# Useful when you want to use a CDN/external proxy
base_url: '' # Example: 'https://mirror.example.com'
- # Same settings but for webtorrent videos
+ # Same settings but for web videos
videos:
bucket_name: 'videos'
prefix: ''
# Transcode and keep original resolution, even if it's above your maximum enabled resolution
always_transcode_original_resolution: true
- # Generate videos in a WebTorrent format (what we do since the first PeerTube release)
+ # Generate videos in a web compatible format
# If you also enabled the hls format, it will multiply videos storage by 2
# If disabled, breaks federation with PeerTube instances < 2.1
webtorrent:
enabled: false
# /!\ Requires ffmpeg >= 4.1
- # Generate HLS playlists and fragmented MP4 files. Better playback than with WebTorrent:
+ # Generate HLS playlists and fragmented MP4 files. Better playback than with Web Videos:
# * Resolution change is smoother
# * Faster playback in particular with long videos
# * More stable playback (less bugs/infinite loading)
- # If you also enabled the webtorrent format, it will multiply videos storage by 2
+ # If you also enabled the web videos format, it will multiply videos storage by 2
hls:
enabled: true
# If enabled, users can create transcoding tasks as they wish
enabled: false
-
# Enable remote runners to transcode studio tasks
# If enabled, your instance won't transcode the videos itself
# At least 1 remote runner must be configured to transcode your videos
console.log('Detecting files to remove, it could take a while...')
toDelete = toDelete.concat(
- await pruneDirectory(DIRECTORIES.VIDEOS.PUBLIC, doesWebTorrentFileExist()),
- await pruneDirectory(DIRECTORIES.VIDEOS.PRIVATE, doesWebTorrentFileExist()),
+ await pruneDirectory(DIRECTORIES.VIDEOS.PUBLIC, doesWebVideoFileExist()),
+ await pruneDirectory(DIRECTORIES.VIDEOS.PRIVATE, doesWebVideoFileExist()),
await pruneDirectory(DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE, doesHLSPlaylistExist()),
await pruneDirectory(DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC, doesHLSPlaylistExist()),
return toDelete
}
-function doesWebTorrentFileExist () {
+function doesWebVideoFileExist () {
return (filePath: string) => {
// Don't delete private directory
if (filePath === DIRECTORIES.VIDEOS.PRIVATE) return true
- return VideoFileModel.doesOwnedWebTorrentVideoFileExist(basename(filePath))
+ return VideoFileModel.doesOwnedWebVideoFileExist(basename(filePath))
}
}
import express from 'express'
import { logger, loggerTagsFactory } from '@server/helpers/logger'
-import { proxifyHLS, proxifyWebTorrentFile } from '@server/lib/object-storage'
+import { proxifyHLS, proxifyWebVideoFile } from '@server/lib/object-storage'
import { VideoPathManager } from '@server/lib/video-path-manager'
import { getStudioTaskFilePath } from '@server/lib/video-studio'
import { apiRateLimiter, asyncMiddleware } from '@server/middlewares'
}
// Web video
- return proxifyWebTorrentFile({
+ return proxifyWebVideoFile({
req,
res,
filename: file.filename
'noInstanceConfigWarningModal',
'noAccountSetupWarningModal',
'noWelcomeModal',
- 'emailPublic'
+ 'emailPublic',
+ 'p2pEnabled'
]
for (const key of keysToUpdate) {
if (body[key] !== undefined) user.set(key, body[key])
}
- if (body.p2pEnabled !== undefined) {
- user.set('p2pEnabled', body.p2pEnabled)
- } else if (body.webTorrentEnabled !== undefined) { // FIXME: deprecated in 4.1
- user.set('p2pEnabled', body.webTorrentEnabled)
- }
-
if (body.email !== undefined) {
if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
user.pendingEmail = body.email
import toInt from 'validator/lib/toInt'
import { logger, loggerTagsFactory } from '@server/helpers/logger'
import { federateVideoIfNeeded } from '@server/lib/activitypub/videos'
-import { removeAllWebTorrentFiles, removeHLSFile, removeHLSPlaylist, removeWebTorrentFile } from '@server/lib/video-file'
+import { updatePlaylistAfterFileChange } from '@server/lib/hls'
+import { removeAllWebVideoFiles, removeHLSFile, removeHLSPlaylist, removeWebVideoFile } from '@server/lib/video-file'
import { VideoFileModel } from '@server/models/video/video-file'
import { HttpStatusCode, UserRight } from '@shared/models'
import {
videoFileMetadataGetValidator,
videoFilesDeleteHLSFileValidator,
videoFilesDeleteHLSValidator,
- videoFilesDeleteWebTorrentFileValidator,
- videoFilesDeleteWebTorrentValidator,
+ videoFilesDeleteWebVideoFileValidator,
+ videoFilesDeleteWebVideoValidator,
videosGetValidator
} from '../../../middlewares'
-import { updatePlaylistAfterFileChange } from '@server/lib/hls'
const lTags = loggerTagsFactory('api', 'video')
const filesRouter = express.Router()
asyncMiddleware(removeHLSFileController)
)
-filesRouter.delete('/:id/webtorrent',
+filesRouter.delete(
+ [ '/:id/webtorrent', '/:id/web-videos' ], // TODO: remove webtorrent in V7
authenticate,
ensureUserHasRight(UserRight.MANAGE_VIDEO_FILES),
- asyncMiddleware(videoFilesDeleteWebTorrentValidator),
- asyncMiddleware(removeAllWebTorrentFilesController)
+ asyncMiddleware(videoFilesDeleteWebVideoValidator),
+ asyncMiddleware(removeAllWebVideoFilesController)
)
-filesRouter.delete('/:id/webtorrent/:videoFileId',
+filesRouter.delete(
+ [ '/:id/webtorrent/:videoFileId', '/:id/web-videos/:videoFileId' ], // TODO: remove webtorrent in V7
authenticate,
ensureUserHasRight(UserRight.MANAGE_VIDEO_FILES),
- asyncMiddleware(videoFilesDeleteWebTorrentFileValidator),
- asyncMiddleware(removeWebTorrentFileController)
+ asyncMiddleware(videoFilesDeleteWebVideoFileValidator),
+ asyncMiddleware(removeWebVideoFileController)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-async function removeAllWebTorrentFilesController (req: express.Request, res: express.Response) {
+async function removeAllWebVideoFilesController (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
- logger.info('Deleting WebTorrent files of %s.', video.url, lTags(video.uuid))
+ logger.info('Deleting Web Video files of %s.', video.url, lTags(video.uuid))
- await removeAllWebTorrentFiles(video)
+ await removeAllWebVideoFiles(video)
await federateVideoIfNeeded(video, false, undefined)
return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
}
-async function removeWebTorrentFileController (req: express.Request, res: express.Response) {
+async function removeWebVideoFileController (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
const videoFileId = +req.params.videoFileId
- logger.info('Deleting WebTorrent file %d of %s.', videoFileId, video.url, lTags(video.uuid))
+ logger.info('Deleting Web Video file %d of %s.', videoFileId, video.url, lTags(video.uuid))
- await removeWebTorrentFile(video, videoFileId)
+ await removeWebVideoFile(video, videoFileId)
await federateVideoIfNeeded(video, false, undefined)
return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
import cors from 'cors'
import express from 'express'
import { OBJECT_STORAGE_PROXY_PATHS } from '@server/initializers/constants'
-import { proxifyHLS, proxifyWebTorrentFile } from '@server/lib/object-storage'
+import { proxifyHLS, proxifyWebVideoFile } from '@server/lib/object-storage'
import {
asyncMiddleware,
ensureCanAccessPrivateVideoHLSFiles,
- ensureCanAccessVideoPrivateWebTorrentFiles,
+ ensureCanAccessVideoPrivateWebVideoFiles,
ensurePrivateObjectStorageProxyIsEnabled,
optionalAuthenticate
} from '@server/middlewares'
objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.PRIVATE_WEBSEED + ':filename',
ensurePrivateObjectStorageProxyIsEnabled,
optionalAuthenticate,
- asyncMiddleware(ensureCanAccessVideoPrivateWebTorrentFiles),
- asyncMiddleware(proxifyWebTorrentController)
+ asyncMiddleware(ensureCanAccessVideoPrivateWebVideoFiles),
+ asyncMiddleware(proxifyWebVideoController)
)
objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS + ':videoUUID/:filename',
objectStorageProxyRouter
}
-function proxifyWebTorrentController (req: express.Request, res: express.Response) {
+function proxifyWebVideoController (req: express.Request, res: express.Response) {
const filename = req.params.filename
- return proxifyWebTorrentFile({ req, res, filename })
+ return proxifyWebVideoFile({ req, res, filename })
}
function proxifyHLSController (req: express.Request, res: express.Response) {
import {
asyncMiddleware,
ensureCanAccessPrivateVideoHLSFiles,
- ensureCanAccessVideoPrivateWebTorrentFiles,
+ ensureCanAccessVideoPrivateWebVideoFiles,
handleStaticError,
optionalAuthenticate
} from '@server/middlewares'
staticRouter.use(cors())
// ---------------------------------------------------------------------------
-// WebTorrent/Classic videos
+// Web videos/Classic videos
// ---------------------------------------------------------------------------
-const privateWebTorrentStaticMiddlewares = CONFIG.STATIC_FILES.PRIVATE_FILES_REQUIRE_AUTH === true
- ? [ optionalAuthenticate, asyncMiddleware(ensureCanAccessVideoPrivateWebTorrentFiles) ]
+const privateWebVideoStaticMiddlewares = CONFIG.STATIC_FILES.PRIVATE_FILES_REQUIRE_AUTH === true
+ ? [ optionalAuthenticate, asyncMiddleware(ensureCanAccessVideoPrivateWebVideoFiles) ]
: []
staticRouter.use(
STATIC_PATHS.PRIVATE_WEBSEED,
- ...privateWebTorrentStaticMiddlewares,
+ ...privateWebVideoStaticMiddlewares,
express.static(DIRECTORIES.VIDEOS.PRIVATE, { fallthrough: false }),
handleStaticError
)
function isValidPlayerMode (value: any) {
- return value === 'webtorrent' || value === 'p2p-media-loader'
+ // TODO: remove webtorrent in v7
+ return value === 'webtorrent' || value === 'web-video' || value === 'p2p-media-loader'
}
// ---------------------------------------------------------------------------
function isValidCreateTranscodingType (value: any) {
return exists(value) &&
- (value === 'hls' || value === 'webtorrent')
+ (value === 'hls' || value === 'webtorrent' || value === 'web-video') // TODO: remove webtorrent in v7
}
// ---------------------------------------------------------------------------
'include',
'skipCount',
'hasHLSFiles',
- 'hasWebtorrentFiles',
+ 'hasWebtorrentFiles', // TODO: Remove in v7
+ 'hasWebVideoFiles',
'search',
'excludeAlreadyWatched'
])
function checkTranscodingConfig () {
if (CONFIG.TRANSCODING.ENABLED) {
if (CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false && CONFIG.TRANSCODING.HLS.ENABLED === false) {
- throw new Error('You need to enable at least WebTorrent transcoding or HLS transcoding.')
+ throw new Error('You need to enable at least Web Video transcoding or HLS transcoding.')
}
if (CONFIG.TRANSCODING.CONCURRENCY <= 0) {
video.VideoLive = videoLive
}
- protected async setWebTorrentFiles (video: MVideoFullLight, t: Transaction) {
+ protected async setWebVideoFiles (video: MVideoFullLight, t: Transaction) {
const videoFileAttributes = getFileAttributesFromUrl(video, this.videoObject.url)
const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a))
await this.setThumbnail(videoCreated, t)
await this.setPreview(videoCreated, t)
- await this.setWebTorrentFiles(videoCreated, t)
+ await this.setWebVideoFiles(videoCreated, t)
await this.setStreamingPlaylists(videoCreated, t)
await this.setTags(videoCreated, t)
await this.setTrackers(videoCreated, t)
if (thumbnailModel) await videoUpdated.addAndSaveThumbnail(thumbnailModel)
await runInReadCommittedTransaction(async t => {
- await this.setWebTorrentFiles(videoUpdated, t)
+ await this.setWebVideoFiles(videoUpdated, t)
await this.setStreamingPlaylists(videoUpdated, t)
})
import { logger, loggerTagsFactory } from '@server/helpers/logger'
import { updateTorrentMetadata } from '@server/helpers/webtorrent'
import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants'
-import { storeHLSFileFromFilename, storeWebTorrentFile } from '@server/lib/object-storage'
+import { storeHLSFileFromFilename, storeWebVideoFile } from '@server/lib/object-storage'
import { getHLSDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths'
import { VideoPathManager } from '@server/lib/video-path-manager'
import { moveToFailedMoveToObjectStorageState, moveToNextState } from '@server/lib/video-state'
try {
if (video.VideoFiles) {
- logger.debug('Moving %d webtorrent files for video %s.', video.VideoFiles.length, video.uuid, lTags)
+ logger.debug('Moving %d web video files for video %s.', video.VideoFiles.length, video.uuid, lTags)
- await moveWebTorrentFiles(video)
+ await moveWebVideoFiles(video)
}
if (video.VideoStreamingPlaylists) {
// ---------------------------------------------------------------------------
-async function moveWebTorrentFiles (video: MVideoWithAllFiles) {
+async function moveWebVideoFiles (video: MVideoWithAllFiles) {
for (const file of video.VideoFiles) {
if (file.storage !== VideoStorage.FILE_SYSTEM) continue
- const fileUrl = await storeWebTorrentFile(video, file)
+ const fileUrl = await storeWebVideoFile(video, file)
const oldPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, file)
await onFileMoved({ videoOrPlaylist: video, file, fileUrl, oldPath })
import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
import { CONFIG } from '@server/initializers/config'
import { federateVideoIfNeeded } from '@server/lib/activitypub/videos'
-import { generateWebTorrentVideoFilename } from '@server/lib/paths'
+import { generateWebVideoFilename } from '@server/lib/paths'
import { buildMoveToObjectStorageJob } from '@server/lib/video'
import { VideoPathManager } from '@server/lib/video-path-manager'
import { VideoModel } from '@server/models/video/video'
if (currentVideoFile) {
// Remove old file and old torrent
- await video.removeWebTorrentFile(currentVideoFile)
+ await video.removeWebVideoFile(currentVideoFile)
// Remove the old video file from the array
video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile)
const newVideoFile = new VideoFileModel({
resolution,
extname: fileExt,
- filename: generateWebTorrentVideoFilename(resolution, fileExt),
+ filename: generateWebVideoFilename(resolution, fileExt),
storage: VideoStorage.FILE_SYSTEM,
size,
fps,
import { YoutubeDLWrapper } from '@server/helpers/youtube-dl'
import { CONFIG } from '@server/initializers/config'
import { isPostImportVideoAccepted } from '@server/lib/moderation'
-import { generateWebTorrentVideoFilename } from '@server/lib/paths'
+import { generateWebVideoFilename } from '@server/lib/paths'
import { Hooks } from '@server/lib/plugins/hooks'
import { ServerConfigManager } from '@server/lib/server-config-manager'
import { createOptimizeOrMergeAudioJobs } from '@server/lib/transcoding/create-transcoding-job'
extname: fileExt,
resolution,
size: stats.size,
- filename: generateWebTorrentVideoFilename(resolution, fileExt),
+ filename: generateWebVideoFilename(resolution, fileExt),
fps,
videoId: videoImport.videoId
}
import { Job } from 'bullmq'
import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding'
import { generateHlsPlaylistResolution } from '@server/lib/transcoding/hls-transcoding'
-import { mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewWebTorrentResolution } from '@server/lib/transcoding/web-transcoding'
-import { removeAllWebTorrentFiles } from '@server/lib/video-file'
+import { mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewWebVideoResolution } from '@server/lib/transcoding/web-transcoding'
+import { removeAllWebVideoFiles } from '@server/lib/video-file'
import { VideoPathManager } from '@server/lib/video-path-manager'
import { moveToFailedTranscodingState } from '@server/lib/video-state'
import { UserModel } from '@server/models/user/user'
import {
HLSTranscodingPayload,
MergeAudioTranscodingPayload,
- NewWebTorrentResolutionTranscodingPayload,
+ NewWebVideoResolutionTranscodingPayload,
OptimizeTranscodingPayload,
VideoTranscodingPayload
} from '@shared/models'
const handlers: { [ id in VideoTranscodingPayload['type'] ]: HandlerFunction } = {
'new-resolution-to-hls': handleHLSJob,
- 'new-resolution-to-webtorrent': handleNewWebTorrentResolutionJob,
- 'merge-audio-to-webtorrent': handleWebTorrentMergeAudioJob,
- 'optimize-to-webtorrent': handleWebTorrentOptimizeJob
+ 'new-resolution-to-web-video': handleNewWebVideoResolutionJob,
+ 'merge-audio-to-web-video': handleWebVideoMergeAudioJob,
+ 'optimize-to-web-video': handleWebVideoOptimizeJob
}
const lTags = loggerTagsFactory('transcoding')
// Job handlers
// ---------------------------------------------------------------------------
-async function handleWebTorrentMergeAudioJob (job: Job, payload: MergeAudioTranscodingPayload, video: MVideoFullLight, user: MUserId) {
+async function handleWebVideoMergeAudioJob (job: Job, payload: MergeAudioTranscodingPayload, video: MVideoFullLight, user: MUserId) {
logger.info('Handling merge audio transcoding job for %s.', video.uuid, lTags(video.uuid), { payload })
await mergeAudioVideofile({ video, resolution: payload.resolution, fps: payload.fps, job })
await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video })
}
-async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodingPayload, video: MVideoFullLight, user: MUserId) {
+async function handleWebVideoOptimizeJob (job: Job, payload: OptimizeTranscodingPayload, video: MVideoFullLight, user: MUserId) {
logger.info('Handling optimize transcoding job for %s.', video.uuid, lTags(video.uuid), { payload })
await optimizeOriginalVideofile({ video, inputVideoFile: video.getMaxQualityFile(), quickTranscode: payload.quickTranscode, job })
// ---------------------------------------------------------------------------
-async function handleNewWebTorrentResolutionJob (job: Job, payload: NewWebTorrentResolutionTranscodingPayload, video: MVideoFullLight) {
- logger.info('Handling WebTorrent transcoding job for %s.', video.uuid, lTags(video.uuid), { payload })
+async function handleNewWebVideoResolutionJob (job: Job, payload: NewWebVideoResolutionTranscodingPayload, video: MVideoFullLight) {
+ logger.info('Handling Web Video transcoding job for %s.', video.uuid, lTags(video.uuid), { payload })
- await transcodeNewWebTorrentResolution({ video, resolution: payload.resolution, fps: payload.fps, job })
+ await transcodeNewWebVideoResolution({ video, resolution: payload.resolution, fps: payload.fps, job })
- logger.info('WebTorrent transcoding job for %s ended.', video.uuid, lTags(video.uuid), { payload })
+ logger.info('Web Video transcoding job for %s ended.', video.uuid, lTags(video.uuid), { payload })
await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video })
}
video = await VideoModel.loadFull(videoArg.uuid)
const videoFileInput = payload.copyCodecs
- ? video.getWebTorrentFile(payload.resolution)
+ ? video.getWebVideoFile(payload.resolution)
: video.getMaxQualityFile()
const videoOrStreamingPlaylist = videoFileInput.getVideoOrStreamingPlaylist()
logger.info('HLS transcoding job for %s ended.', video.uuid, lTags(video.uuid), { payload })
- if (payload.deleteWebTorrentFiles === true) {
- logger.info('Removing WebTorrent files of %s now we have a HLS version of it.', video.uuid, lTags(video.uuid))
+ if (payload.deleteWebVideoFiles === true) {
+ logger.info('Removing Web Video files of %s now we have a HLS version of it.', video.uuid, lTags(video.uuid))
- await removeAllWebTorrentFiles(video)
+ await removeAllWebVideoFiles(video)
}
await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video })
return join(playlist.getStringType(), playlist.Video.uuid)
}
-function generateWebTorrentObjectStorageKey (filename: string) {
+function generateWebVideoObjectStorageKey (filename: string) {
return filename
}
export {
generateHLSObjectStorageKey,
generateHLSObjectBaseStorageKey,
- generateWebTorrentObjectStorageKey
+ generateWebVideoObjectStorageKey
}
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
import { CONFIG } from '@server/initializers/config'
import { MStreamingPlaylistVideo, MVideoFile } from '@server/types/models'
-import { generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys'
+import { generateHLSObjectStorageKey, generateWebVideoObjectStorageKey } from './keys'
import { buildKey, getClient } from './shared'
-import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from './urls'
+import { getHLSPublicFileUrl, getWebVideoPublicFileUrl } from './urls'
export async function generateWebVideoPresignedUrl (options: {
file: MVideoFile
}) {
const { file, downloadFilename } = options
- const key = generateWebTorrentObjectStorageKey(file.filename)
+ const key = generateWebVideoObjectStorageKey(file.filename)
const command = new GetObjectCommand({
Bucket: CONFIG.OBJECT_STORAGE.VIDEOS.BUCKET_NAME,
const url = await getSignedUrl(getClient(), command, { expiresIn: 3600 * 24 })
- return getWebTorrentPublicFileUrl(url)
+ return getWebVideoPublicFileUrl(url)
}
export async function generateHLSFilePresignedUrl (options: {
import { MStreamingPlaylist, MVideo } from '@server/types/models'
import { HttpStatusCode } from '@shared/models'
import { injectQueryToPlaylistUrls } from '../hls'
-import { getHLSFileReadStream, getWebTorrentFileReadStream } from './videos'
+import { getHLSFileReadStream, getWebVideoFileReadStream } from './videos'
-export async function proxifyWebTorrentFile (options: {
+export async function proxifyWebVideoFile (options: {
req: express.Request
res: express.Response
filename: string
}) {
const { req, res, filename } = options
- logger.debug('Proxifying WebTorrent file %s from object storage.', filename)
+ logger.debug('Proxifying Web Video file %s from object storage.', filename)
try {
- const { response: s3Response, stream } = await getWebTorrentFileReadStream({
+ const { response: s3Response, stream } = await getWebVideoFileReadStream({
filename,
rangeHeader: req.header('range')
})
// ---------------------------------------------------------------------------
-function getWebTorrentPublicFileUrl (fileUrl: string) {
+function getWebVideoPublicFileUrl (fileUrl: string) {
const baseUrl = CONFIG.OBJECT_STORAGE.VIDEOS.BASE_URL
if (!baseUrl) return fileUrl
return WEBSERVER.URL + OBJECT_STORAGE_PROXY_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS + video.uuid + `/${filename}`
}
-function getWebTorrentPrivateFileUrl (filename: string) {
+function getWebVideoPrivateFileUrl (filename: string) {
return WEBSERVER.URL + OBJECT_STORAGE_PROXY_PATHS.PRIVATE_WEBSEED + filename
}
export {
getInternalUrl,
- getWebTorrentPublicFileUrl,
+ getWebVideoPublicFileUrl,
getHLSPublicFileUrl,
getHLSPrivateFileUrl,
- getWebTorrentPrivateFileUrl,
+ getWebVideoPrivateFileUrl,
replaceByBaseUrl
}
import { MStreamingPlaylistVideo, MVideo, MVideoFile } from '@server/types/models'
import { getHLSDirectory } from '../paths'
import { VideoPathManager } from '../video-path-manager'
-import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys'
+import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebVideoObjectStorageKey } from './keys'
import {
createObjectReadStream,
listKeysOfPrefix,
// ---------------------------------------------------------------------------
-function storeWebTorrentFile (video: MVideo, file: MVideoFile) {
+function storeWebVideoFile (video: MVideo, file: MVideoFile) {
return storeObject({
inputPath: VideoPathManager.Instance.getFSVideoFileOutputPath(video, file),
- objectStorageKey: generateWebTorrentObjectStorageKey(file.filename),
+ objectStorageKey: generateWebVideoObjectStorageKey(file.filename),
bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS,
isPrivate: video.hasPrivateStaticPath()
})
// ---------------------------------------------------------------------------
-async function updateWebTorrentFileACL (video: MVideo, file: MVideoFile) {
+async function updateWebVideoFileACL (video: MVideo, file: MVideoFile) {
await updateObjectACL({
- objectStorageKey: generateWebTorrentObjectStorageKey(file.filename),
+ objectStorageKey: generateWebVideoObjectStorageKey(file.filename),
bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS,
isPrivate: video.hasPrivateStaticPath()
})
// ---------------------------------------------------------------------------
-function removeWebTorrentObjectStorage (videoFile: MVideoFile) {
- return removeObject(generateWebTorrentObjectStorageKey(videoFile.filename), CONFIG.OBJECT_STORAGE.VIDEOS)
+function removeWebVideoObjectStorage (videoFile: MVideoFile) {
+ return removeObject(generateWebVideoObjectStorageKey(videoFile.filename), CONFIG.OBJECT_STORAGE.VIDEOS)
}
// ---------------------------------------------------------------------------
return destination
}
-async function makeWebTorrentFileAvailable (filename: string, destination: string) {
- const key = generateWebTorrentObjectStorageKey(filename)
+async function makeWebVideoFileAvailable (filename: string, destination: string) {
+ const key = generateWebVideoObjectStorageKey(filename)
- logger.info('Fetching WebTorrent file %s from object storage to %s.', key, destination, lTags())
+ logger.info('Fetching Web Video file %s from object storage to %s.', key, destination, lTags())
await makeAvailable({
key,
// ---------------------------------------------------------------------------
-function getWebTorrentFileReadStream (options: {
+function getWebVideoFileReadStream (options: {
filename: string
rangeHeader: string
}) {
const { filename, rangeHeader } = options
- const key = generateWebTorrentObjectStorageKey(filename)
+ const key = generateWebVideoObjectStorageKey(filename)
return createObjectReadStream({
key,
export {
listHLSFileKeysOf,
- storeWebTorrentFile,
+ storeWebVideoFile,
storeHLSFileFromFilename,
storeHLSFileFromPath,
storeHLSFileFromContent,
- updateWebTorrentFileACL,
+ updateWebVideoFileACL,
updateHLSFilesACL,
removeHLSObjectStorage,
removeHLSFileObjectStorageByPath,
removeHLSFileObjectStorageByFullKey,
- removeWebTorrentObjectStorage,
+ removeWebVideoObjectStorage,
- makeWebTorrentFileAvailable,
+ makeWebVideoFileAvailable,
makeHLSFileAvailable,
- getWebTorrentFileReadStream,
+ getWebVideoFileReadStream,
getHLSFileReadStream
}
// ################## Video file name ##################
-function generateWebTorrentVideoFilename (resolution: number, extname: string) {
+function generateWebVideoFilename (resolution: number, extname: string) {
return buildUUID() + '-' + resolution + extname
}
export {
generateHLSVideoFilename,
- generateWebTorrentVideoFilename,
+ generateWebVideoFilename,
generateTorrentFileName,
getFSTorrentFilePath,
const video = await VideoModel.loadFull(id)
if (!video) return undefined
- const webtorrentVideoFiles = (video.VideoFiles || []).map(f => ({
+ const webVideoFiles = (video.VideoFiles || []).map(f => ({
path: f.storage === VideoStorage.FILE_SYSTEM
? VideoPathManager.Instance.getFSVideoFileOutputPath(video, f)
: null,
}))
return {
- webtorrent: {
- videoFiles: webtorrentVideoFiles
+ webtorrent: { // TODO: remove in v7
+ videoFiles: webVideoFiles
+ },
+
+ webVideo: {
+ videoFiles: webVideoFiles
},
hls: {
import { dirname, join } from 'path'
import { logger, LoggerTagsFn } from '@server/helpers/logger'
import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding'
-import { onWebTorrentVideoFileTranscoding } from '@server/lib/transcoding/web-transcoding'
+import { onWebVideoFileTranscoding } from '@server/lib/transcoding/web-transcoding'
import { buildNewFile } from '@server/lib/video-file'
import { VideoModel } from '@server/models/video/video'
import { MVideoFullLight } from '@server/types/models'
const newVideoFilePath = join(dirname(videoFilePath), videoFile.filename)
await move(videoFilePath, newVideoFilePath)
- await onWebTorrentVideoFileTranscoding({
+ await onWebVideoFileTranscoding({
video,
videoFile,
videoOutputPath: newVideoFilePath
// We can remove the old audio file
const oldAudioFile = video.VideoFiles[0]
- await video.removeWebTorrentFile(oldAudioFile)
+ await video.removeWebVideoFile(oldAudioFile)
await oldAudioFile.destroy()
video.VideoFiles = []
import { getHlsResolutionPlaylistFilename } from '@server/lib/paths'
import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding'
import { onHLSVideoFileTranscoding } from '@server/lib/transcoding/hls-transcoding'
-import { buildNewFile, removeAllWebTorrentFiles } from '@server/lib/video-file'
+import { buildNewFile, removeAllWebVideoFiles } from '@server/lib/video-file'
import { VideoJobInfoModel } from '@server/models/video/video-job-info'
import { MVideo } from '@server/types/models'
import { MRunnerJob } from '@server/types/models/runners'
if (privatePayload.deleteWebVideoFiles === true) {
logger.info('Removing web video files of %s now we have a HLS version of it.', video.uuid, this.lTags(video.uuid))
- await removeAllWebTorrentFiles(video)
+ await removeAllWebVideoFiles(video)
}
logger.info('Runner VOD HLS job %s for %s ended.', runnerJob.uuid, video.uuid, this.lTags(runnerJob.uuid, video.uuid))
import { getOrCreateAPVideo } from '../activitypub/videos'
import { downloadPlaylistSegments } from '../hls'
import { removeVideoRedundancy } from '../redundancy'
-import { generateHLSRedundancyUrl, generateWebTorrentRedundancyUrl } from '../video-urls'
+import { generateHLSRedundancyUrl, generateWebVideoRedundancyUrl } from '../video-urls'
import { AbstractScheduler } from './abstract-scheduler'
const lTags = loggerTagsFactory('redundancy')
const createdModel: MVideoRedundancyFileVideo = await VideoRedundancyModel.create({
expiresOn,
url: getLocalVideoCacheFileActivityPubUrl(file),
- fileUrl: generateWebTorrentRedundancyUrl(file),
+ fileUrl: generateWebVideoRedundancyUrl(file),
strategy,
videoFileId: file.id,
actorId: serverActor.id
// ---------------------------------------------------------------------------
export function createTranscodingJobs (options: {
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
video: MVideoFullLight
resolutions: number[]
isNewVideo: boolean
}): Promise<any>
abstract createTranscodingJobs (options: {
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
video: MVideoFullLight
resolutions: number[]
isNewVideo: boolean
import {
HLSTranscodingPayload,
MergeAudioTranscodingPayload,
- NewWebTorrentResolutionTranscodingPayload,
+ NewWebVideoResolutionTranscodingPayload,
OptimizeTranscodingPayload,
VideoTranscodingPayload
} from '@shared/models'
const { video, videoFile, isNewVideo, user, videoFileAlreadyLocked } = options
let mergeOrOptimizePayload: MergeAudioTranscodingPayload | OptimizeTranscodingPayload
- let nextTranscodingSequentialJobPayloads: (NewWebTorrentResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
+ let nextTranscodingSequentialJobPayloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
const mutexReleaser = videoFileAlreadyLocked
? () => {}
if (CONFIG.TRANSCODING.HLS.ENABLED === true) {
nextTranscodingSequentialJobPayloads.push([
this.buildHLSJobPayload({
- deleteWebTorrentFiles: CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false,
+ deleteWebVideoFiles: CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false,
// We had some issues with a web video quick transcoded while producing a HLS version of it
copyCodecs: !quickTranscode,
// ---------------------------------------------------------------------------
async createTranscodingJobs (options: {
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
video: MVideoFullLight
resolutions: number[]
isNewVideo: boolean
return this.buildHLSJobPayload({ videoUUID: video.uuid, resolution, fps, isNewVideo })
}
- if (transcodingType === 'webtorrent') {
- return this.buildWebTorrentJobPayload({ videoUUID: video.uuid, resolution, fps, isNewVideo })
+ if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
+ return this.buildWebVideoJobPayload({ videoUUID: video.uuid, resolution, fps, isNewVideo })
}
throw new Error('Unknown transcoding type')
const parent = transcodingType === 'hls'
? this.buildHLSJobPayload({ videoUUID: video.uuid, resolution: maxResolution, fps, isNewVideo })
- : this.buildWebTorrentJobPayload({ videoUUID: video.uuid, resolution: maxResolution, fps, isNewVideo })
+ : this.buildWebVideoJobPayload({ videoUUID: video.uuid, resolution: maxResolution, fps, isNewVideo })
// Process the last resolution after the other ones to prevent concurrency issue
// Because low resolutions use the biggest one as ffmpeg input
private async createTranscodingJobsWithChildren (options: {
videoUUID: string
- parent: (HLSTranscodingPayload | NewWebTorrentResolutionTranscodingPayload)
- children: (HLSTranscodingPayload | NewWebTorrentResolutionTranscodingPayload)[]
+ parent: (HLSTranscodingPayload | NewWebVideoResolutionTranscodingPayload)
+ children: (HLSTranscodingPayload | NewWebVideoResolutionTranscodingPayload)[]
user: MUserId | null
}) {
const { videoUUID, parent, children, user } = options
options
)
- const sequentialPayloads: (NewWebTorrentResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
+ const sequentialPayloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
for (const resolution of resolutionsEnabled) {
const fps = computeOutputFPS({ inputFPS: inputVideoFPS, resolution })
if (CONFIG.TRANSCODING.WEBTORRENT.ENABLED) {
- const payloads: (NewWebTorrentResolutionTranscodingPayload | HLSTranscodingPayload)[] = [
- this.buildWebTorrentJobPayload({
+ const payloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[] = [
+ this.buildWebVideoJobPayload({
videoUUID: video.uuid,
resolution,
fps,
resolution: number
fps: number
isNewVideo: boolean
- deleteWebTorrentFiles?: boolean // default false
+ deleteWebVideoFiles?: boolean // default false
copyCodecs?: boolean // default false
}): HLSTranscodingPayload {
- const { videoUUID, resolution, fps, isNewVideo, deleteWebTorrentFiles = false, copyCodecs = false } = options
+ const { videoUUID, resolution, fps, isNewVideo, deleteWebVideoFiles = false, copyCodecs = false } = options
return {
type: 'new-resolution-to-hls',
fps,
copyCodecs,
isNewVideo,
- deleteWebTorrentFiles
+ deleteWebVideoFiles
}
}
- private buildWebTorrentJobPayload (options: {
+ private buildWebVideoJobPayload (options: {
videoUUID: string
resolution: number
fps: number
isNewVideo: boolean
- }): NewWebTorrentResolutionTranscodingPayload {
+ }): NewWebVideoResolutionTranscodingPayload {
const { videoUUID, resolution, fps, isNewVideo } = options
return {
- type: 'new-resolution-to-webtorrent',
+ type: 'new-resolution-to-web-video',
videoUUID,
isNewVideo,
resolution,
const { videoUUID, isNewVideo, hasChildren } = options
return {
- type: 'merge-audio-to-webtorrent',
+ type: 'merge-audio-to-web-video',
resolution: DEFAULT_AUDIO_RESOLUTION,
fps: VIDEO_TRANSCODING_FPS.AUDIO_MERGE,
videoUUID,
const { videoUUID, quickTranscode, isNewVideo, hasChildren } = options
return {
- type: 'optimize-to-webtorrent',
+ type: 'optimize-to-web-video',
videoUUID,
isNewVideo,
hasChildren,
// ---------------------------------------------------------------------------
async createTranscodingJobs (options: {
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
video: MVideoFullLight
resolutions: number[]
isNewVideo: boolean
continue
}
- if (transcodingType === 'webtorrent') {
+ if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
await new VODWebVideoTranscodingJobHandler().create({
video,
resolution,
import { CONFIG } from '../../initializers/config'
import { VideoFileModel } from '../../models/video/video-file'
import { JobQueue } from '../job-queue'
-import { generateWebTorrentVideoFilename } from '../paths'
+import { generateWebVideoFilename } from '../paths'
import { buildFileMetadata } from '../video-file'
import { VideoPathManager } from '../video-path-manager'
import { buildFFmpegVOD } from './shared'
// Important to do this before getVideoFilename() to take in account the new filename
inputVideoFile.resolution = resolution
inputVideoFile.extname = newExtname
- inputVideoFile.filename = generateWebTorrentVideoFilename(resolution, newExtname)
+ inputVideoFile.filename = generateWebVideoFilename(resolution, newExtname)
inputVideoFile.storage = VideoStorage.FILE_SYSTEM
- const { videoFile } = await onWebTorrentVideoFileTranscoding({
+ const { videoFile } = await onWebVideoFileTranscoding({
video,
videoFile: inputVideoFile,
videoOutputPath
}
}
-// Transcode the original video file to a lower resolution compatible with WebTorrent
-export async function transcodeNewWebTorrentResolution (options: {
+// Transcode the original video file to a lower resolution compatible with web browsers
+export async function transcodeNewWebVideoResolution (options: {
video: MVideoFullLight
resolution: VideoResolution
fps: number
const newVideoFile = new VideoFileModel({
resolution,
extname: newExtname,
- filename: generateWebTorrentVideoFilename(resolution, newExtname),
+ filename: generateWebVideoFilename(resolution, newExtname),
size: 0,
videoId: video.id
})
await buildFFmpegVOD(job).transcode(transcodeOptions)
- return onWebTorrentVideoFileTranscoding({ video, videoFile: newVideoFile, videoOutputPath })
+ return onWebVideoFileTranscoding({ video, videoFile: newVideoFile, videoOutputPath })
})
return result
// Important to do this before getVideoFilename() to take in account the new file extension
inputVideoFile.extname = newExtname
inputVideoFile.resolution = resolution
- inputVideoFile.filename = generateWebTorrentVideoFilename(inputVideoFile.resolution, newExtname)
+ inputVideoFile.filename = generateWebVideoFilename(inputVideoFile.resolution, newExtname)
// ffmpeg generated a new video file, so update the video duration
// See https://trac.ffmpeg.org/ticket/5456
video.duration = await getVideoStreamDuration(videoOutputPath)
await video.save()
- return onWebTorrentVideoFileTranscoding({
+ return onWebVideoFileTranscoding({
video,
videoFile: inputVideoFile,
videoOutputPath,
}
}
-export async function onWebTorrentVideoFileTranscoding (options: {
+export async function onWebVideoFileTranscoding (options: {
video: MVideoFullLight
videoFile: MVideoFile
videoOutputPath: string
await createTorrentAndSetInfoHash(video, videoFile)
- const oldFile = await VideoFileModel.loadWebTorrentFile({ videoId: video.id, fps: videoFile.fps, resolution: videoFile.resolution })
- if (oldFile) await video.removeWebTorrentFile(oldFile)
+ const oldFile = await VideoFileModel.loadWebVideoFile({ videoId: video.id, fps: videoFile.fps, resolution: videoFile.resolution })
+ if (oldFile) await video.removeWebVideoFile(oldFile)
await VideoFileModel.customUpsert(videoFile, 'video', undefined)
video.VideoFiles = await video.$get('VideoFiles')
import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS, isAudioFile } from '@shared/ffmpeg'
import { VideoFileMetadata, VideoResolution } from '@shared/models'
import { lTags } from './object-storage/shared'
-import { generateHLSVideoFilename, generateWebTorrentVideoFilename } from './paths'
+import { generateHLSVideoFilename, generateWebVideoFilename } from './paths'
import { VideoPathManager } from './video-path-manager'
async function buildNewFile (options: {
}
videoFile.filename = mode === 'web-video'
- ? generateWebTorrentVideoFilename(videoFile.resolution, videoFile.extname)
+ ? generateWebVideoFilename(videoFile.resolution, videoFile.extname)
: generateHLSVideoFilename(videoFile.resolution)
return videoFile
// ---------------------------------------------------------------------------
-async function removeAllWebTorrentFiles (video: MVideoWithAllFiles) {
+async function removeAllWebVideoFiles (video: MVideoWithAllFiles) {
const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
try {
for (const file of video.VideoFiles) {
- await video.removeWebTorrentFile(file)
+ await video.removeWebVideoFile(file)
await file.destroy()
}
return video
}
-async function removeWebTorrentFile (video: MVideoWithAllFiles, fileToDeleteId: number) {
+async function removeWebVideoFile (video: MVideoWithAllFiles, fileToDeleteId: number) {
const files = video.VideoFiles
if (files.length === 1) {
- return removeAllWebTorrentFiles(video)
+ return removeAllWebVideoFiles(video)
}
const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
try {
const toDelete = files.find(f => f.id === fileToDeleteId)
- await video.removeWebTorrentFile(toDelete)
+ await video.removeWebVideoFile(toDelete)
await toDelete.destroy()
video.VideoFiles = files.filter(f => f.id !== toDelete.id)
removeHLSPlaylist,
removeHLSFile,
- removeAllWebTorrentFiles,
- removeWebTorrentFile,
+ removeAllWebVideoFiles,
+ removeWebVideoFile,
buildFileMetadata
}
import { MStreamingPlaylistVideo, MVideo, MVideoFile, MVideoFileStreamingPlaylistVideo, MVideoFileVideo } from '@server/types/models'
import { buildUUID } from '@shared/extra-utils'
import { VideoStorage } from '@shared/models'
-import { makeHLSFileAvailable, makeWebTorrentFileAvailable } from './object-storage'
+import { makeHLSFileAvailable, makeWebVideoFileAvailable } from './object-storage'
import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from './paths'
import { isVideoInPrivateDirectory } from './video-privacy'
}
return this.makeAvailableFactory(
- () => makeWebTorrentFileAvailable(videoFile.filename, destination),
+ () => makeWebVideoFileAvailable(videoFile.filename, destination),
true,
cb
)
import { DIRECTORIES } from '@server/initializers/constants'
import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
import { VideoPrivacy, VideoStorage } from '@shared/models'
-import { updateHLSFilesACL, updateWebTorrentFileACL } from './object-storage'
+import { updateHLSFilesACL, updateWebVideoFileACL } from './object-storage'
const validPrivacySet = new Set([
VideoPrivacy.PRIVATE,
for (const file of video.VideoFiles) {
if (file.storage === VideoStorage.FILE_SYSTEM) {
- await moveWebTorrentFileOnFS(type, video, file)
+ await moveWebVideoFileOnFS(type, video, file)
} else {
- await updateWebTorrentFileACL(video, file)
+ await updateWebVideoFileACL(video, file)
}
}
}
}
-async function moveWebTorrentFileOnFS (type: MoveType, video: MVideo, file: MVideoFile) {
- const directories = getWebTorrentDirectories(type)
+async function moveWebVideoFileOnFS (type: MoveType, video: MVideo, file: MVideoFile) {
+ const directories = getWebVideoDirectories(type)
const source = join(directories.old, file.filename)
const destination = join(directories.new, file.filename)
try {
- logger.info('Moving WebTorrent files of %s after privacy change (%s -> %s).', video.uuid, source, destination)
+ logger.info('Moving web video files of %s after privacy change (%s -> %s).', video.uuid, source, destination)
await move(source, destination)
} catch (err) {
- logger.error('Cannot move webtorrent file %s to %s after privacy change', source, destination, { err })
+ logger.error('Cannot move web video file %s to %s after privacy change', source, destination, { err })
}
}
-function getWebTorrentDirectories (moveType: MoveType) {
+function getWebVideoDirectories (moveType: MoveType) {
if (moveType === 'private-to-public') {
return { old: DIRECTORIES.VIDEOS.PRIVATE, new: DIRECTORIES.VIDEOS.PUBLIC }
}
import { VideoStudioTranscodingJobHandler } from './runners'
import { createOptimizeOrMergeAudioJobs } from './transcoding/create-transcoding-job'
import { getTranscodingJobPriority } from './transcoding/transcoding-priority'
-import { buildNewFile, removeHLSPlaylist, removeWebTorrentFile } from './video-file'
+import { buildNewFile, removeHLSPlaylist, removeWebVideoFile } from './video-file'
import { VideoPathManager } from './video-path-manager'
const lTags = loggerTagsFactory('video-studio')
// Private
// ---------------------------------------------------------------------------
-async function removeAllFiles (video: MVideoWithAllFiles, webTorrentFileException: MVideoFile) {
+async function removeAllFiles (video: MVideoWithAllFiles, webVideoFileException: MVideoFile) {
await removeHLSPlaylist(video)
for (const file of video.VideoFiles) {
- if (file.id === webTorrentFileException.id) continue
+ if (file.id === webVideoFileException.id) continue
- await removeWebTorrentFile(video, file.id)
+ await removeWebVideoFile(video, file.id)
}
}
return WEBSERVER.URL + STATIC_PATHS.REDUNDANCY + playlist.getStringType() + '/' + video.uuid
}
-function generateWebTorrentRedundancyUrl (file: MVideoFile) {
+function generateWebVideoRedundancyUrl (file: MVideoFile) {
return WEBSERVER.URL + STATIC_PATHS.REDUNDANCY + file.filename
}
export {
getLocalVideoFileMetadataUrl,
- generateWebTorrentRedundancyUrl,
+ generateWebVideoRedundancyUrl,
generateHLSRedundancyUrl
}
ttl: LRU_CACHE.STATIC_VIDEO_FILES_RIGHTS_CHECK.TTL
})
-const ensureCanAccessVideoPrivateWebTorrentFiles = [
+const ensureCanAccessVideoPrivateWebVideoFiles = [
query('videoFileToken').optional().custom(exists),
isValidVideoPasswordHeader(),
return res.sendStatus(HttpStatusCode.FORBIDDEN_403)
}
- const result = await isWebTorrentAllowed(req, res)
+ const result = await isWebVideoAllowed(req, res)
staticFileTokenBypass.set(cacheKey, result)
]
export {
- ensureCanAccessVideoPrivateWebTorrentFiles,
+ ensureCanAccessVideoPrivateWebVideoFiles,
ensureCanAccessPrivateVideoHLSFiles
}
// ---------------------------------------------------------------------------
-async function isWebTorrentAllowed (req: express.Request, res: express.Response) {
+async function isWebVideoAllowed (req: express.Request, res: express.Response) {
const filename = basename(req.path)
const file = await VideoFileModel.loadWithVideoByFilename(filename)
import { HttpStatusCode } from '@shared/models'
import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
-const videoFilesDeleteWebTorrentValidator = [
+const videoFilesDeleteWebVideoValidator = [
isValidVideoIdParam('id'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (!checkLocalVideo(video, res)) return
- if (!video.hasWebTorrentFiles()) {
+ if (!video.hasWebVideoFiles()) {
return res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
- message: 'This video does not have WebTorrent files'
+ message: 'This video does not have Web Video files'
})
}
if (!video.getHLSPlaylist()) {
return res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
- message: 'Cannot delete WebTorrent files since this video does not have HLS playlist'
+ message: 'Cannot delete Web Video files since this video does not have HLS playlist'
})
}
}
]
-const videoFilesDeleteWebTorrentFileValidator = [
+const videoFilesDeleteWebVideoFileValidator = [
isValidVideoIdParam('id'),
param('videoFileId')
if (!files.find(f => f.id === +req.params.videoFileId)) {
return res.fail({
status: HttpStatusCode.NOT_FOUND_404,
- message: 'This video does not have this WebTorrent file id'
+ message: 'This video does not have this Web Video file id'
})
}
if (files.length === 1 && !video.getHLSPlaylist()) {
return res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
- message: 'Cannot delete WebTorrent files since this video does not have HLS playlist'
+ message: 'Cannot delete Web Video files since this video does not have HLS playlist'
})
}
})
}
- if (!video.hasWebTorrentFiles()) {
+ if (!video.hasWebVideoFiles()) {
return res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
- message: 'Cannot delete HLS playlist since this video does not have WebTorrent files'
+ message: 'Cannot delete HLS playlist since this video does not have Web Video files'
})
}
}
// Last file to delete
- if (hlsFiles.length === 1 && !video.hasWebTorrentFiles()) {
+ if (hlsFiles.length === 1 && !video.hasWebVideoFiles()) {
return res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
- message: 'Cannot delete last HLS playlist file since this video does not have WebTorrent files'
+ message: 'Cannot delete last HLS playlist file since this video does not have Web Video files'
})
}
]
export {
- videoFilesDeleteWebTorrentValidator,
- videoFilesDeleteWebTorrentFileValidator,
+ videoFilesDeleteWebVideoValidator,
+ videoFilesDeleteWebVideoFileValidator,
videoFilesDeleteHLSValidator,
videoFilesDeleteHLSFileValidator
.optional()
.customSanitizer(toBooleanOrNull)
.custom(isBooleanValid).withMessage('Should have a valid hasHLSFiles boolean'),
- query('hasWebtorrentFiles')
+ query('hasWebtorrentFiles') // TODO: remove in v7
.optional()
.customSanitizer(toBooleanOrNull)
.custom(isBooleanValid).withMessage('Should have a valid hasWebtorrentFiles boolean'),
+ query('hasWebVideoFiles')
+ .optional()
+ .customSanitizer(toBooleanOrNull)
+ .custom(isBooleanValid).withMessage('Should have a valid hasWebVideoFiles boolean'),
query('skipCount')
.optional()
.customSanitizer(toBooleanOrNull)
const logIdentifier = `${videoFile.Video.uuid}-${videoFile.resolution}`
logger.info('Removing duplicated video file %s.', logIdentifier)
- videoFile.Video.removeWebTorrentFile(videoFile, true)
+ videoFile.Video.removeWebVideoFile(videoFile, true)
.catch(err => logger.error('Cannot delete %s files.', logIdentifier, { err }))
}
'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' +
`WHERE "account"."userId" = ${options.whereUserId} ${andWhere}`
- const webtorrentFiles = 'SELECT "videoFile"."size" AS "size", "video"."id" AS "videoId" FROM "videoFile" ' +
+ const webVideoFiles = 'SELECT "videoFile"."size" AS "size", "video"."id" AS "videoId" FROM "videoFile" ' +
'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" AND "video"."isLive" IS FALSE ' +
videoChannelJoin
return 'SELECT COALESCE(SUM("size"), 0) AS "total" ' +
'FROM (' +
- `SELECT MAX("t1"."size") AS "size" FROM (${webtorrentFiles} UNION ${hlsFiles}) t1 ` +
+ `SELECT MAX("t1"."size") AS "size" FROM (${webVideoFiles} UNION ${hlsFiles}) t1 ` +
'GROUP BY "t1"."videoId"' +
') t2'
}
nsfwPolicy: this.nsfwPolicy,
- // FIXME: deprecated in 4.1
- webTorrentEnabled: this.p2pEnabled,
p2pEnabled: this.p2pEnabled,
videosHistoryEnabled: this.videosHistoryEnabled,
}
}
- protected includeWebtorrentFiles () {
+ protected includeWebVideoFiles () {
this.addJoin('LEFT JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"')
this.attributes = {
}
}
- protected includeWebTorrentRedundancies () {
+ protected includeWebVideoRedundancies () {
this.addJoin(
'LEFT OUTER JOIN "videoRedundancy" AS "VideoFiles->RedundancyVideos" ON ' +
'"VideoFiles"."id" = "VideoFiles->RedundancyVideos"."videoFileId"'
/**
*
- * Fetch files (webtorrent and streaming playlist) according to a video
+ * Fetch files (web videos and streaming playlist) according to a video
*
*/
super(sequelize, 'get')
}
- queryWebTorrentVideos (options: FileQueryOptions) {
- this.buildWebtorrentFilesQuery(options)
+ queryWebVideos (options: FileQueryOptions) {
+ this.buildWebVideoFilesQuery(options)
return this.runQuery(options)
}
return this.runQuery(options)
}
- private buildWebtorrentFilesQuery (options: FileQueryOptions) {
+ private buildWebVideoFilesQuery (options: FileQueryOptions) {
this.attributes = {
'"video"."id"': ''
}
- this.includeWebtorrentFiles()
+ this.includeWebVideoFiles()
if (options.includeRedundancy) {
- this.includeWebTorrentRedundancies()
+ this.includeWebVideoRedundancies()
}
this.whereId(options)
buildVideosFromRows (options: {
rows: SQLRow[]
include?: VideoInclude
- rowsWebTorrentFiles?: SQLRow[]
+ rowsWebVideoFiles?: SQLRow[]
rowsStreamingPlaylist?: SQLRow[]
}) {
- const { rows, rowsWebTorrentFiles, rowsStreamingPlaylist, include } = options
+ const { rows, rowsWebVideoFiles, rowsStreamingPlaylist, include } = options
this.reinit()
this.addActorAvatar(row, 'VideoChannel.Account.Actor', accountActor)
}
- if (!rowsWebTorrentFiles) {
- this.addWebTorrentFile(row, videoModel)
+ if (!rowsWebVideoFiles) {
+ this.addWebVideoFile(row, videoModel)
}
if (!rowsStreamingPlaylist) {
}
}
- this.grabSeparateWebTorrentFiles(rowsWebTorrentFiles)
+ this.grabSeparateWebVideoFiles(rowsWebVideoFiles)
this.grabSeparateStreamingPlaylistFiles(rowsStreamingPlaylist)
return this.videos
this.videos = []
}
- private grabSeparateWebTorrentFiles (rowsWebTorrentFiles?: SQLRow[]) {
- if (!rowsWebTorrentFiles) return
+ private grabSeparateWebVideoFiles (rowsWebVideoFiles?: SQLRow[]) {
+ if (!rowsWebVideoFiles) return
- for (const row of rowsWebTorrentFiles) {
+ for (const row of rowsWebVideoFiles) {
const id = row['VideoFiles.id']
if (!id) continue
const videoModel = this.videosMemo[row.id]
- this.addWebTorrentFile(row, videoModel)
+ this.addWebVideoFile(row, videoModel)
this.addRedundancy(row, 'VideoFiles', this.videoFileMemo[id])
}
}
this.thumbnailsDone.add(id)
}
- private addWebTorrentFile (row: SQLRow, videoModel: VideoModel) {
+ private addWebVideoFile (row: SQLRow, videoModel: VideoModel) {
const id = row['VideoFiles.id']
if (!id || this.videoFileMemo[id]) return
export class VideoModelGetQueryBuilder {
videoQueryBuilder: VideosModelGetQuerySubBuilder
- webtorrentFilesQueryBuilder: VideoFileQueryBuilder
+ webVideoFilesQueryBuilder: VideoFileQueryBuilder
streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
private readonly videoModelBuilder: VideoModelBuilder
constructor (protected readonly sequelize: Sequelize) {
this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
- this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
+ this.webVideoFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
this.videoModelBuilder = new VideoModelBuilder('get', new VideoTableAttributes('get'))
includeRedundancy: this.shouldIncludeRedundancies(options)
}
- const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
+ const [ videoRows, webVideoFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
this.videoQueryBuilder.queryVideos(options),
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
- ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions)
+ ? this.webVideoFilesQueryBuilder.queryWebVideos(fileQueryOptions)
: Promise.resolve(undefined),
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
const videos = this.videoModelBuilder.buildVideosFromRows({
rows: videoRows,
- rowsWebTorrentFiles: webtorrentFilesRows,
+ rowsWebVideoFiles: webVideoFilesRows,
rowsStreamingPlaylist: streamingPlaylistFilesRows
})
export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder {
protected attributes: { [key: string]: string }
- protected webtorrentFilesQuery: string
+ protected webVideoFilesQuery: string
protected streamingPlaylistFilesQuery: string
private static readonly trackersInclude = new Set<GetType>([ 'api' ])
hasFiles?: boolean
hasHLSFiles?: boolean
- hasWebtorrentFiles?: boolean
+
+ hasWebVideoFiles?: boolean
+ hasWebtorrentFiles?: boolean // TODO: Remove in v7
accountId?: number
videoChannelId?: number
}
if (exists(options.hasWebtorrentFiles)) {
- this.whereWebTorrentFileExists(options.hasWebtorrentFiles)
+ this.whereWebVideoFileExists(options.hasWebtorrentFiles)
+ } else if (exists(options.hasWebVideoFiles)) {
+ this.whereWebVideoFileExists(options.hasWebVideoFiles)
}
if (exists(options.hasHLSFiles)) {
}
private whereFileExists () {
- this.and.push(`(${this.buildWebTorrentFileExistsQuery(true)} OR ${this.buildHLSFileExistsQuery(true)})`)
+ this.and.push(`(${this.buildWebVideoFileExistsQuery(true)} OR ${this.buildHLSFileExistsQuery(true)})`)
}
- private whereWebTorrentFileExists (exists: boolean) {
- this.and.push(this.buildWebTorrentFileExistsQuery(exists))
+ private whereWebVideoFileExists (exists: boolean) {
+ this.and.push(this.buildWebVideoFileExistsQuery(exists))
}
private whereHLSFileExists (exists: boolean) {
this.and.push(this.buildHLSFileExistsQuery(exists))
}
- private buildWebTorrentFileExistsQuery (exists: boolean) {
+ private buildWebVideoFileExistsQuery (exists: boolean) {
const prefix = exists ? '' : 'NOT '
return prefix + 'EXISTS (SELECT 1 FROM "videoFile" WHERE "videoFile"."videoId" = "video"."id")'
private innerQuery: string
private innerSort: string
- webtorrentFilesQueryBuilder: VideoFileQueryBuilder
+ webVideoFilesQueryBuilder: VideoFileQueryBuilder
streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
private readonly videoModelBuilder: VideoModelBuilder
super(sequelize, 'list')
this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
- this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
+ this.webVideoFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
}
includeRedundancy: false
}
- const [ rowsWebTorrentFiles, rowsStreamingPlaylist ] = await Promise.all([
- this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions),
+ const [ rowsWebVideoFiles, rowsStreamingPlaylist ] = await Promise.all([
+ this.webVideoFilesQueryBuilder.queryWebVideos(fileQueryOptions),
this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
])
- return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include, rowsStreamingPlaylist, rowsWebTorrentFiles })
+ return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include, rowsStreamingPlaylist, rowsWebVideoFiles })
}
}
{
model: VideoModel.scope([
VideoScopeNames.WITH_THUMBNAILS,
- VideoScopeNames.WITH_WEBTORRENT_FILES,
+ VideoScopeNames.WITH_WEB_VIDEO_FILES,
VideoScopeNames.WITH_STREAMING_PLAYLISTS,
VideoScopeNames.WITH_ACCOUNT_DETAILS
]),
import {
getHLSPrivateFileUrl,
getHLSPublicFileUrl,
- getWebTorrentPrivateFileUrl,
- getWebTorrentPublicFileUrl
+ getWebVideoPrivateFileUrl,
+ getWebVideoPublicFileUrl
} from '@server/lib/object-storage'
import { getFSTorrentFilePath } from '@server/lib/paths'
import { isVideoInPrivateDirectory } from '@server/lib/video-privacy'
static async doesOwnedTorrentFileExist (filename: string) {
const query = 'SELECT 1 FROM "videoFile" ' +
- 'LEFT JOIN "video" "webtorrent" ON "webtorrent"."id" = "videoFile"."videoId" AND "webtorrent"."remote" IS FALSE ' +
+ 'LEFT JOIN "video" "webvideo" ON "webvideo"."id" = "videoFile"."videoId" AND "webvideo"."remote" IS FALSE ' +
'LEFT JOIN "videoStreamingPlaylist" ON "videoStreamingPlaylist"."id" = "videoFile"."videoStreamingPlaylistId" ' +
'LEFT JOIN "video" "hlsVideo" ON "hlsVideo"."id" = "videoStreamingPlaylist"."videoId" AND "hlsVideo"."remote" IS FALSE ' +
- 'WHERE "torrentFilename" = $filename AND ("hlsVideo"."id" IS NOT NULL OR "webtorrent"."id" IS NOT NULL) LIMIT 1'
+ 'WHERE "torrentFilename" = $filename AND ("hlsVideo"."id" IS NOT NULL OR "webvideo"."id" IS NOT NULL) LIMIT 1'
return doesExist(this.sequelize, query, { filename })
}
- static async doesOwnedWebTorrentVideoFileExist (filename: string) {
+ static async doesOwnedWebVideoFileExist (filename: string) {
const query = 'SELECT 1 FROM "videoFile" INNER JOIN "video" ON "video"."id" = "videoFile"."videoId" AND "video"."remote" IS FALSE ' +
`WHERE "filename" = $filename AND "storage" = ${VideoStorage.FILE_SYSTEM} LIMIT 1`
}
static getStats () {
- const webtorrentFilesQuery: FindOptions = {
+ const webVideoFilesQuery: FindOptions = {
include: [
{
attributes: [],
}
return Promise.all([
- VideoFileModel.aggregate('size', 'SUM', webtorrentFilesQuery),
+ VideoFileModel.aggregate('size', 'SUM', webVideoFilesQuery),
VideoFileModel.aggregate('size', 'SUM', hlsFilesQuery)
- ]).then(([ webtorrentResult, hlsResult ]) => ({
- totalLocalVideoFilesSize: parseAggregateResult(webtorrentResult) + parseAggregateResult(hlsResult)
+ ]).then(([ webVideoResult, hlsResult ]) => ({
+ totalLocalVideoFilesSize: parseAggregateResult(webVideoResult) + parseAggregateResult(hlsResult)
}))
}
const element = mode === 'streaming-playlist'
? await VideoFileModel.loadHLSFile({ ...baseFind, playlistId: videoFile.videoStreamingPlaylistId })
- : await VideoFileModel.loadWebTorrentFile({ ...baseFind, videoId: videoFile.videoId })
+ : await VideoFileModel.loadWebVideoFile({ ...baseFind, videoId: videoFile.videoId })
if (!element) return videoFile.save({ transaction })
return element.save({ transaction })
}
- static async loadWebTorrentFile (options: {
+ static async loadWebVideoFile (options: {
videoId: number
fps: number
resolution: number
return getHLSPrivateFileUrl(video, this.filename)
}
- return getWebTorrentPrivateFileUrl(this.filename)
+ return getWebVideoPrivateFileUrl(this.filename)
}
private getPublicObjectStorageUrl () {
return getHLSPublicFileUrl(this.fileUrl)
}
- return getWebTorrentPublicFileUrl(this.fileUrl)
+ return getWebVideoPublicFileUrl(this.fileUrl)
}
// ---------------------------------------------------------------------------
getFileStaticPath (video: MVideo) {
if (this.isHLS()) return this.getHLSFileStaticPath(video)
- return this.getWebTorrentFileStaticPath(video)
+ return this.getWebVideoFileStaticPath(video)
}
- private getWebTorrentFileStaticPath (video: MVideo) {
+ private getWebVideoFileStaticPath (video: MVideo) {
if (isVideoInPrivateDirectory(video.privacy)) {
return join(STATIC_PATHS.PRIVATE_WEBSEED, this.filename)
}
import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video'
import { InternalEventEmitter } from '@server/lib/internal-event-emitter'
import { LiveManager } from '@server/lib/live/live-manager'
-import { removeHLSFileObjectStorageByFilename, removeHLSObjectStorage, removeWebTorrentObjectStorage } from '@server/lib/object-storage'
+import { removeHLSFileObjectStorageByFilename, removeHLSObjectStorage, removeWebVideoObjectStorage } from '@server/lib/object-storage'
import { tracer } from '@server/lib/opentelemetry/tracing'
import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths'
import { Hooks } from '@server/lib/plugins/hooks'
FOR_API = 'FOR_API',
WITH_ACCOUNT_DETAILS = 'WITH_ACCOUNT_DETAILS',
WITH_TAGS = 'WITH_TAGS',
- WITH_WEBTORRENT_FILES = 'WITH_WEBTORRENT_FILES',
+ WITH_WEB_VIDEO_FILES = 'WITH_WEB_VIDEO_FILES',
WITH_SCHEDULED_UPDATE = 'WITH_SCHEDULED_UPDATE',
WITH_BLACKLISTED = 'WITH_BLACKLISTED',
WITH_STREAMING_PLAYLISTS = 'WITH_STREAMING_PLAYLISTS',
}
]
},
- [ScopeNames.WITH_WEBTORRENT_FILES]: (withRedundancies = false) => {
+ [ScopeNames.WITH_WEB_VIDEO_FILES]: (withRedundancies = false) => {
let subInclude: any[] = []
if (withRedundancies === true) {
// Remove physical files and torrents
instance.VideoFiles.forEach(file => {
- tasks.push(instance.removeWebTorrentFile(file))
+ tasks.push(instance.removeWebVideoFile(file))
})
// Remove playlists file
include?: VideoInclude
hasFiles?: boolean // default false
- hasWebtorrentFiles?: boolean
+
+ hasWebtorrentFiles?: boolean // TODO: remove in v7
+ hasWebVideoFiles?: boolean
+
hasHLSFiles?: boolean
categoryOneOf?: number[]
'historyOfUser',
'hasHLSFiles',
'hasWebtorrentFiles',
+ 'hasWebVideoFiles',
'search',
'excludeAlreadyWatched'
]),
user?: MUserAccountId
- hasWebtorrentFiles?: boolean
+ hasWebtorrentFiles?: boolean // TODO: remove in v7
+ hasWebVideoFiles?: boolean
+
hasHLSFiles?: boolean
search?: string
'durationMax',
'hasHLSFiles',
'hasWebtorrentFiles',
+ 'hasWebVideoFiles',
'uuids',
'search',
'displayOnlyForFollower',
return this.getQualityFileBy(minBy)
}
- getWebTorrentFile<T extends MVideoWithFile> (this: T, resolution: number): MVideoFileVideo {
+ getWebVideoFile<T extends MVideoWithFile> (this: T, resolution: number): MVideoFileVideo {
if (Array.isArray(this.VideoFiles) === false) return undefined
const file = this.VideoFiles.find(f => f.resolution === resolution)
return Object.assign(file, { Video: this })
}
- hasWebTorrentFiles () {
+ hasWebVideoFiles () {
return Array.isArray(this.VideoFiles) === true && this.VideoFiles.length !== 0
}
.concat(toAdd)
}
- removeWebTorrentFile (videoFile: MVideoFile, isRedundancy = false) {
+ removeWebVideoFile (videoFile: MVideoFile, isRedundancy = false) {
const filePath = isRedundancy
? VideoPathManager.Instance.getFSRedundancyVideoFilePath(this, videoFile)
: VideoPathManager.Instance.getFSVideoFileOutputPath(this, videoFile)
if (!isRedundancy) promises.push(videoFile.removeTorrent())
if (videoFile.storage === VideoStorage.OBJECT_STORAGE) {
- promises.push(removeWebTorrentObjectStorage(videoFile))
+ promises.push(removeWebVideoObjectStorage(videoFile))
}
return Promise.all(promises)
})
})
- it('Should fail with a disabled webtorrent & hls transcoding', async function () {
+ it('Should fail with a disabled web videos & hls transcoding', async function () {
const newUpdateParams = {
...updateParams,
it('Should not run transcoding of a unknown video', async function () {
await servers[0].videos.runTranscoding({ videoId: 404, transcodingType: 'hls', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
- await servers[0].videos.runTranscoding({ videoId: 404, transcodingType: 'webtorrent', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
+ await servers[0].videos.runTranscoding({ videoId: 404, transcodingType: 'web-video', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
})
it('Should not run transcoding of a remote video', async function () {
const expectedStatus = HttpStatusCode.BAD_REQUEST_400
await servers[0].videos.runTranscoding({ videoId: remoteId, transcodingType: 'hls', expectedStatus })
- await servers[0].videos.runTranscoding({ videoId: remoteId, transcodingType: 'webtorrent', expectedStatus })
+ await servers[0].videos.runTranscoding({ videoId: remoteId, transcodingType: 'web-video', expectedStatus })
})
it('Should not run transcoding by a non admin user', async function () {
const expectedStatus = HttpStatusCode.FORBIDDEN_403
await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'hls', token: userToken, expectedStatus })
- await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'webtorrent', token: moderatorToken, expectedStatus })
+ await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'web-video', token: moderatorToken, expectedStatus })
})
it('Should not run transcoding without transcoding type', async function () {
await servers[0].config.disableTranscoding()
await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'hls', expectedStatus })
- await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'webtorrent', expectedStatus })
+ await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'web-video', expectedStatus })
})
it('Should run transcoding', async function () {
await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'hls' })
await waitJobs(servers)
- await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'webtorrent' })
+ await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'web-video' })
await waitJobs(servers)
})
it('Should not run transcoding on a video that is already being transcoded', async function () {
- await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'webtorrent' })
+ await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'web-video' })
const expectedStatus = HttpStatusCode.CONFLICT_409
- await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'webtorrent', expectedStatus })
+ await servers[0].videos.runTranscoding({ videoId: validId, transcodingType: 'web-video', expectedStatus })
})
after(async function () {
})
describe('Deleting files', function () {
- let webtorrentId: string
+ let webVideoId: string
let hlsId: string
let remoteId: string
let validId2: string
let hlsFileId: number
- let webtorrentFileId: number
+ let webVideoFileId: number
let remoteHLSFileId: number
- let remoteWebtorrentFileId: number
+ let remoteWebVideoFileId: number
before(async function () {
this.timeout(300_000)
const video = await servers[1].videos.get({ id: uuid })
remoteId = video.uuid
remoteHLSFileId = video.streamingPlaylists[0].files[0].id
- remoteWebtorrentFileId = video.files[0].id
+ remoteWebVideoFileId = video.files[0].id
}
{
const video = await servers[0].videos.get({ id: uuid })
validId1 = video.uuid
hlsFileId = video.streamingPlaylists[0].files[0].id
- webtorrentFileId = video.files[0].id
+ webVideoFileId = video.files[0].id
}
{
{
await servers[0].config.enableTranscoding(false, true)
- const { uuid } = await servers[0].videos.quickUpload({ name: 'webtorrent' })
- webtorrentId = uuid
+ const { uuid } = await servers[0].videos.quickUpload({ name: 'web-video' })
+ webVideoId = uuid
}
await waitJobs(servers)
const expectedStatus = HttpStatusCode.NOT_FOUND_404
await servers[0].videos.removeHLSPlaylist({ videoId: 404, expectedStatus })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: 404, expectedStatus })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: 404, expectedStatus })
await servers[0].videos.removeHLSFile({ videoId: 404, fileId: hlsFileId, expectedStatus })
- await servers[0].videos.removeWebTorrentFile({ videoId: 404, fileId: webtorrentFileId, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: 404, fileId: webVideoFileId, expectedStatus })
})
it('Should not delete unknown files', async function () {
const expectedStatus = HttpStatusCode.NOT_FOUND_404
- await servers[0].videos.removeHLSFile({ videoId: validId1, fileId: webtorrentFileId, expectedStatus })
- await servers[0].videos.removeWebTorrentFile({ videoId: validId1, fileId: hlsFileId, expectedStatus })
+ await servers[0].videos.removeHLSFile({ videoId: validId1, fileId: webVideoFileId, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: validId1, fileId: hlsFileId, expectedStatus })
})
it('Should not delete files of a remote video', async function () {
const expectedStatus = HttpStatusCode.BAD_REQUEST_400
await servers[0].videos.removeHLSPlaylist({ videoId: remoteId, expectedStatus })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: remoteId, expectedStatus })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: remoteId, expectedStatus })
await servers[0].videos.removeHLSFile({ videoId: remoteId, fileId: remoteHLSFileId, expectedStatus })
- await servers[0].videos.removeWebTorrentFile({ videoId: remoteId, fileId: remoteWebtorrentFileId, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: remoteId, fileId: remoteWebVideoFileId, expectedStatus })
})
it('Should not delete files by a non admin user', async function () {
await servers[0].videos.removeHLSPlaylist({ videoId: validId1, token: userToken, expectedStatus })
await servers[0].videos.removeHLSPlaylist({ videoId: validId1, token: moderatorToken, expectedStatus })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: validId1, token: userToken, expectedStatus })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: validId1, token: moderatorToken, expectedStatus })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: validId1, token: userToken, expectedStatus })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: validId1, token: moderatorToken, expectedStatus })
await servers[0].videos.removeHLSFile({ videoId: validId1, fileId: hlsFileId, token: userToken, expectedStatus })
await servers[0].videos.removeHLSFile({ videoId: validId1, fileId: hlsFileId, token: moderatorToken, expectedStatus })
- await servers[0].videos.removeWebTorrentFile({ videoId: validId1, fileId: webtorrentFileId, token: userToken, expectedStatus })
- await servers[0].videos.removeWebTorrentFile({ videoId: validId1, fileId: webtorrentFileId, token: moderatorToken, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: validId1, fileId: webVideoFileId, token: userToken, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: validId1, fileId: webVideoFileId, token: moderatorToken, expectedStatus })
})
it('Should not delete files if the files are not available', async function () {
await servers[0].videos.removeHLSPlaylist({ videoId: hlsId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: webtorrentId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: webVideoId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
await servers[0].videos.removeHLSFile({ videoId: hlsId, fileId: 404, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
- await servers[0].videos.removeWebTorrentFile({ videoId: webtorrentId, fileId: 404, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
+ await servers[0].videos.removeWebVideoFile({ videoId: webVideoId, fileId: 404, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
})
it('Should not delete files if no both versions are available', async function () {
await servers[0].videos.removeHLSPlaylist({ videoId: hlsId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: webtorrentId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: webVideoId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
})
it('Should delete files if both versions are available', async function () {
await servers[0].videos.removeHLSFile({ videoId: validId1, fileId: hlsFileId })
- await servers[0].videos.removeWebTorrentFile({ videoId: validId1, fileId: webtorrentFileId })
+ await servers[0].videos.removeWebVideoFile({ videoId: validId1, fileId: webVideoFileId })
await servers[0].videos.removeHLSPlaylist({ videoId: validId1 })
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: validId2 })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: validId2 })
})
})
const video = await server.videos.getWithToken({ id: videoId })
return {
- webTorrentFile: video.files[0].fileUrl,
+ webVideoFile: video.files[0].fileUrl,
hlsFile: getHLS(video).files[0].fileUrl
}
}
it('Should not get files without appropriate OAuth token', async function () {
this.timeout(60000)
- const { webTorrentFile, hlsFile } = await getSampleFileUrls(privateVideoUUID)
+ const { webVideoFile, hlsFile } = await getSampleFileUrls(privateVideoUUID)
- await makeRawRequest({ url: webTorrentFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
- await makeRawRequest({ url: webTorrentFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
+ await makeRawRequest({ url: webVideoFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
+ await makeRawRequest({ url: webVideoFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
await makeRawRequest({ url: hlsFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({ url: hlsFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
it('Should not get files without appropriate password or appropriate OAuth token', async function () {
this.timeout(60000)
- const { webTorrentFile, hlsFile } = await getSampleFileUrls(passwordProtectedVideoUUID)
+ const { webVideoFile, hlsFile } = await getSampleFileUrls(passwordProtectedVideoUUID)
- await makeRawRequest({ url: webTorrentFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
+ await makeRawRequest({ url: webVideoFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({
- url: webTorrentFile,
+ url: webVideoFile,
token: null,
headers: incorrectPasswordHeader,
expectedStatus: HttpStatusCode.FORBIDDEN_403
})
- await makeRawRequest({ url: webTorrentFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
+ await makeRawRequest({ url: webVideoFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
await makeRawRequest({
- url: webTorrentFile,
+ url: webVideoFile,
token: null,
headers: correctPasswordHeader,
expectedStatus: HttpStatusCode.OK_200
const badVideoFileToken = await server.videoToken.getVideoFileToken({ token: userToken, videoId: userPrivateVideoUUID })
const goodVideoFileToken = await server.videoToken.getVideoFileToken({ videoId: privateVideoUUID })
- const { webTorrentFile, hlsFile } = await getSampleFileUrls(privateVideoUUID)
+ const { webVideoFile, hlsFile } = await getSampleFileUrls(privateVideoUUID)
- for (const url of [ webTorrentFile, hlsFile ]) {
+ for (const url of [ webVideoFile, hlsFile ]) {
await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
videoPassword: correctPassword
})
- const { webTorrentFile, hlsFile } = await getSampleFileUrls(passwordProtectedVideoUUID)
+ const { webVideoFile, hlsFile } = await getSampleFileUrls(passwordProtectedVideoUUID)
- for (const url of [ hlsFile, webTorrentFile ]) {
+ for (const url of [ hlsFile, webVideoFile ]) {
await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
it('Should not be able to access object storage proxy', async function () {
const privateVideo = await server.videos.getWithToken({ id: videoUUID })
- const webtorrentFilename = extractFilenameFromUrl(privateVideo.files[0].fileUrl)
+ const webVideoFilename = extractFilenameFromUrl(privateVideo.files[0].fileUrl)
const hlsFilename = extractFilenameFromUrl(getHLS(privateVideo).files[0].fileUrl)
await makeRawRequest({
- url: server.url + '/object-storage-proxy/webseed/private/' + webtorrentFilename,
+ url: server.url + '/object-storage-proxy/webseed/private/' + webVideoFilename,
token: server.accessToken,
expectedStatus: HttpStatusCode.BAD_REQUEST_400
})
playlistBucket: string
playlistPrefix?: string
- webtorrentBucket: string
- webtorrentPrefix?: string
+ webVideoBucket: string
+ webVideoPrefix?: string
}) {
const {
server,
originSQLCommand,
video,
playlistBucket,
- webtorrentBucket,
+ webVideoBucket,
baseMockUrl,
playlistPrefix,
- webtorrentPrefix
+ webVideoPrefix
} = options
let allFiles = video.files
for (const file of video.files) {
const baseUrl = baseMockUrl
- ? `${baseMockUrl}/${webtorrentBucket}/`
- : `http://${webtorrentBucket}.${ObjectStorageCommand.getMockEndpointHost()}/`
+ ? `${baseMockUrl}/${webVideoBucket}/`
+ : `http://${webVideoBucket}.${ObjectStorageCommand.getMockEndpointHost()}/`
- const prefix = webtorrentPrefix || ''
+ const prefix = webVideoPrefix || ''
const start = baseUrl + prefix
expectStartWith(file.fileUrl, start)
playlistBucket: string
playlistPrefix?: string
- webtorrentBucket: string
- webtorrentPrefix?: string
+ webVideoBucket: string
+ webVideoPrefix?: string
useMockBaseUrl?: boolean
}) {
: undefined
await objectStorage.createMockBucket(options.playlistBucket)
- await objectStorage.createMockBucket(options.webtorrentBucket)
+ await objectStorage.createMockBucket(options.webVideoBucket)
const config = {
object_storage: {
},
videos: {
- bucket_name: options.webtorrentBucket,
- prefix: options.webtorrentPrefix,
+ bucket_name: options.webVideoBucket,
+ prefix: options.webVideoPrefix,
base_url: baseMockUrl
- ? `${baseMockUrl}/${options.webtorrentBucket}`
+ ? `${baseMockUrl}/${options.webVideoBucket}`
: undefined
}
}
describe('Test simple object storage', function () {
runTestSuite({
playlistBucket: objectStorage.getMockBucketName('streaming-playlists'),
- webtorrentBucket: objectStorage.getMockBucketName('videos')
+ webVideoBucket: objectStorage.getMockBucketName('videos')
})
})
describe('Test object storage with prefix', function () {
runTestSuite({
playlistBucket: objectStorage.getMockBucketName('mybucket'),
- webtorrentBucket: objectStorage.getMockBucketName('mybucket'),
+ webVideoBucket: objectStorage.getMockBucketName('mybucket'),
playlistPrefix: 'streaming-playlists_',
- webtorrentPrefix: 'webtorrent_'
+ webVideoPrefix: 'webvideo_'
})
})
describe('Test object storage with prefix and base URL', function () {
runTestSuite({
playlistBucket: objectStorage.getMockBucketName('mybucket'),
- webtorrentBucket: objectStorage.getMockBucketName('mybucket'),
+ webVideoBucket: objectStorage.getMockBucketName('mybucket'),
playlistPrefix: 'streaming-playlists/',
- webtorrentPrefix: 'webtorrent/',
+ webVideoPrefix: 'webvideo/',
useMockBaseUrl: true
})
runTestSuite({
maxUploadPart,
playlistBucket: objectStorage.getMockBucketName('streaming-playlists'),
- webtorrentBucket: objectStorage.getMockBucketName('videos'),
+ webVideoBucket: objectStorage.getMockBucketName('videos'),
fixture
})
})
}
}
-async function createServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) {
+async function createServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebVideo = true) {
const strategies: any[] = []
if (strategy !== null) {
const config = {
transcoding: {
webtorrent: {
- enabled: withWebtorrent
+ enabled: withWebVideo
},
hls: {
enabled: true
}
async function ensureSameFilenames (videoUUID: string) {
- let webtorrentFilenames: string[]
+ let webVideoFilenames: string[]
let hlsFilenames: string[]
for (const server of servers) {
// Ensure we use the same filenames that the origin
- const localWebtorrentFilenames = video.files.map(f => basename(f.fileUrl)).sort()
+ const localWebVideoFilenames = video.files.map(f => basename(f.fileUrl)).sort()
const localHLSFilenames = video.streamingPlaylists[0].files.map(f => basename(f.fileUrl)).sort()
- if (webtorrentFilenames) expect(webtorrentFilenames).to.deep.equal(localWebtorrentFilenames)
- else webtorrentFilenames = localWebtorrentFilenames
+ if (webVideoFilenames) expect(webVideoFilenames).to.deep.equal(localWebVideoFilenames)
+ else webVideoFilenames = localWebVideoFilenames
if (hlsFilenames) expect(hlsFilenames).to.deep.equal(localHLSFilenames)
else hlsFilenames = localHLSFilenames
}
- return { webtorrentFilenames, hlsFilenames }
+ return { webVideoFilenames, hlsFilenames }
}
async function check1WebSeed (videoUUID?: string) {
}
}
- const { webtorrentFilenames } = await ensureSameFilenames(videoUUID)
+ const { webVideoFilenames } = await ensureSameFilenames(videoUUID)
const directories = [
servers[0].getDirectoryPath('redundancy'),
expect(files).to.have.length.at.least(4)
// Ensure we files exist on disk
- expect(files.find(f => webtorrentFilenames.includes(f))).to.exist
+ expect(files.find(f => webVideoFilenames.includes(f))).to.exist
}
}
describe('Test audio only video transcoding', function () {
let servers: PeerTubeServer[] = []
let videoUUID: string
- let webtorrentAudioFileUrl: string
+ let webVideoAudioFileUrl: string
let fragmentedAudioFileUrl: string
before(async function () {
}
if (server.serverNumber === 1) {
- webtorrentAudioFileUrl = video.files[2].fileUrl
+ webVideoAudioFileUrl = video.files[2].fileUrl
fragmentedAudioFileUrl = video.streamingPlaylists[0].files[2].fileUrl
}
}
it('0p transcoded video should not have video', async function () {
const paths = [
- servers[0].servers.buildWebTorrentFilePath(webtorrentAudioFileUrl),
+ servers[0].servers.buildWebVideoFilePath(webVideoAudioFileUrl),
servers[0].servers.buildFragmentedFilePath(videoUUID, fragmentedAudioFileUrl)
]
}
})
- it('Should generate WebTorrent', async function () {
+ it('Should generate Web Video', async function () {
this.timeout(60000)
await servers[0].videos.runTranscoding({
videoId: videoUUID,
- transcodingType: 'webtorrent'
+ transcodingType: 'web-video'
})
await waitJobs(servers)
}
})
- it('Should generate WebTorrent from HLS only video', async function () {
+ it('Should generate Web Video from HLS only video', async function () {
this.timeout(60000)
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: videoUUID })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: videoUUID })
await waitJobs(servers)
- await servers[0].videos.runTranscoding({ videoId: videoUUID, transcodingType: 'webtorrent' })
+ await servers[0].videos.runTranscoding({ videoId: videoUUID, transcodingType: 'web-video' })
await waitJobs(servers)
for (const server of servers) {
}
})
- it('Should only generate WebTorrent', async function () {
+ it('Should only generate Web Video', async function () {
this.timeout(60000)
await servers[0].videos.removeHLSPlaylist({ videoId: videoUUID })
await waitJobs(servers)
- await servers[0].videos.runTranscoding({ videoId: videoUUID, transcodingType: 'webtorrent' })
+ await servers[0].videos.runTranscoding({ videoId: videoUUID, transcodingType: 'web-video' })
await waitJobs(servers)
for (const server of servers) {
await doubleFollow(servers[0], servers[1])
})
- describe('With WebTorrent & HLS enabled', function () {
+ describe('With Web Video & HLS enabled', function () {
runTestSuite(false)
})
expect(videoDetails.files).to.have.lengthOf(5)
const file = videoDetails.files.find(f => f.resolution.id === 240)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const probe = await getAudioStream(path)
if (probe.audioStream) {
const videoDetails = await server.videos.get({ id: video.id })
const file = videoDetails.files.find(f => f.resolution.id === 240)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
expect(await hasAudioStream(path)).to.be.false
}
const fixtureVideoProbe = await getAudioStream(fixturePath)
const file = videoDetails.files.find(f => f.resolution.id === 240)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const videoProbe = await getAudioStream(path)
for (const resolution of [ 144, 240, 360, 480 ]) {
const file = videoDetails.files.find(f => f.resolution.id === resolution)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const fps = await getVideoStreamFPS(path)
expect(fps).to.be.below(31)
}
const file = videoDetails.files.find(f => f.resolution.id === 720)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const fps = await getVideoStreamFPS(path)
expect(fps).to.be.above(58).and.below(62)
{
const file = video.files.find(f => f.resolution.id === 240)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const fps = await getVideoStreamFPS(path)
expect(fps).to.be.equal(25)
}
{
const file = video.files.find(f => f.resolution.id === 720)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const fps = await getVideoStreamFPS(path)
expect(fps).to.be.equal(59)
}
for (const resolution of [ 240, 360, 480, 720, 1080 ]) {
const file = video.files.find(f => f.resolution.id === resolution)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const bitrate = await getVideoStreamBitrate(path)
const fps = await getVideoStreamFPS(path)
for (const r of resolutions) {
const file = video.files.find(f => f.resolution.id === r)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const bitrate = await getVideoStreamBitrate(path)
const inputBitrate = 60_000
{
const video = await servers[1].videos.get({ id: videoUUID })
const file = video.files.find(f => f.resolution.id === 240)
- const path = servers[1].servers.buildWebTorrentFilePath(file.fileUrl)
+ const path = servers[1].servers.buildWebVideoFilePath(file.fileUrl)
const probe = await ffprobePromise(path)
const metadata = new VideoFileMetadata(probe)
expect(transcodingJobs).to.have.lengthOf(16)
const hlsJobs = transcodingJobs.filter(j => j.data.type === 'new-resolution-to-hls')
- const webtorrentJobs = transcodingJobs.filter(j => j.data.type === 'new-resolution-to-webtorrent')
- const optimizeJobs = transcodingJobs.filter(j => j.data.type === 'optimize-to-webtorrent')
+ const webVideoJobs = transcodingJobs.filter(j => j.data.type === 'new-resolution-to-web-video')
+ const optimizeJobs = transcodingJobs.filter(j => j.data.type === 'optimize-to-web-video')
expect(hlsJobs).to.have.lengthOf(8)
- expect(webtorrentJobs).to.have.lengthOf(7)
+ expect(webVideoJobs).to.have.lengthOf(7)
expect(optimizeJobs).to.have.lengthOf(1)
- for (const j of optimizeJobs.concat(hlsJobs.concat(webtorrentJobs))) {
+ for (const j of optimizeJobs.concat(hlsJobs.concat(webVideoJobs))) {
expect(j.priority).to.be.greaterThan(100)
expect(j.priority).to.be.lessThan(150)
}
await doubleFollow(servers[0], servers[1])
})
- describe('With WebTorrent & HLS enabled', function () {
+ describe('With Web Video & HLS enabled', function () {
runTestSuite(false)
})
describe('HLS only studio edition', function () {
before(async function () {
- // Disable webtorrent
+ // Disable Web Videos
await servers[0].config.updateExistingSubConfig({
newConfig: {
transcoding: {
expect(oldFileUrls).to.not.include(f.fileUrl)
}
- for (const webtorrentFile of video.files) {
- expectStartWith(webtorrentFile.fileUrl, objectStorage.getMockWebVideosBaseUrl())
+ for (const webVideoFile of video.files) {
+ expectStartWith(webVideoFile.fileUrl, objectStorage.getMockWebVideosBaseUrl())
}
for (const hlsFile of video.streamingPlaylists[0].files) {
}
})
- it('Should disable webtorrent, enable HLS, and update my quota', async function () {
+ it('Should disable web videos, enable HLS, and update my quota', async function () {
this.timeout(160000)
{
})
it('Should be able to change the p2p attribute', async function () {
- {
- await server.users.updateMe({
- token: userToken,
- webTorrentEnabled: false
- })
-
- const user = await server.users.getMyInfo({ token: userToken })
- expect(user.p2pEnabled).to.be.false
- }
-
- {
- await server.users.updateMe({
- token: userToken,
- p2pEnabled: true
- })
+ await server.users.updateMe({
+ token: userToken,
+ p2pEnabled: true
+ })
- const user = await server.users.getMyInfo({ token: userToken })
- expect(user.p2pEnabled).to.be.true
- }
+ const user = await server.users.getMyInfo({ token: userToken })
+ expect(user.p2pEnabled).to.be.true
})
it('Should be able to change the email attribute', async function () {
await waitJobs(servers)
})
- it('Should delete webtorrent files', async function () {
+ it('Should delete web video files', async function () {
this.timeout(30_000)
- await servers[0].videos.removeAllWebTorrentFiles({ videoId: validId1 })
+ await servers[0].videos.removeAllWebVideoFiles({ videoId: validId1 })
await waitJobs(servers)
})
describe('When deleting a specific file', function () {
- let webtorrentId: string
+ let webVideoId: string
let hlsId: string
before(async function () {
this.timeout(120_000)
{
- const { uuid } = await servers[0].videos.quickUpload({ name: 'webtorrent' })
- webtorrentId = uuid
+ const { uuid } = await servers[0].videos.quickUpload({ name: 'web-video' })
+ webVideoId = uuid
}
{
await waitJobs(servers)
})
- it('Shoulde delete a webtorrent file', async function () {
+ it('Shoulde delete a web video file', async function () {
this.timeout(30_000)
- const video = await servers[0].videos.get({ id: webtorrentId })
+ const video = await servers[0].videos.get({ id: webVideoId })
const files = video.files
- await servers[0].videos.removeWebTorrentFile({ videoId: webtorrentId, fileId: files[0].id })
+ await servers[0].videos.removeWebVideoFile({ videoId: webVideoId, fileId: files[0].id })
await waitJobs(servers)
for (const server of servers) {
- const video = await server.videos.get({ id: webtorrentId })
+ const video = await server.videos.get({ id: webVideoId })
expect(video.files).to.have.lengthOf(files.length - 1)
expect(video.files.find(f => f.id === files[0].id)).to.not.exist
}
})
- it('Should delete all webtorrent files', async function () {
+ it('Should delete all web video files', async function () {
this.timeout(30_000)
- const video = await servers[0].videos.get({ id: webtorrentId })
+ const video = await servers[0].videos.get({ id: webVideoId })
const files = video.files
for (const file of files) {
- await servers[0].videos.removeWebTorrentFile({ videoId: webtorrentId, fileId: file.id })
+ await servers[0].videos.removeWebVideoFile({ videoId: webVideoId, fileId: file.id })
}
await waitJobs(servers)
for (const server of servers) {
- const video = await server.videos.get({ id: webtorrentId })
+ const video = await server.videos.get({ id: webVideoId })
expect(video.files).to.have.lengthOf(0)
}
it('Should not delete last file of a video', async function () {
this.timeout(60_000)
- const webtorrentOnly = await servers[0].videos.get({ id: hlsId })
- const hlsOnly = await servers[0].videos.get({ id: webtorrentId })
+ const webVideoOnly = await servers[0].videos.get({ id: hlsId })
+ const hlsOnly = await servers[0].videos.get({ id: webVideoId })
for (let i = 0; i < 4; i++) {
- await servers[0].videos.removeWebTorrentFile({ videoId: webtorrentOnly.id, fileId: webtorrentOnly.files[i].id })
+ await servers[0].videos.removeWebVideoFile({ videoId: webVideoOnly.id, fileId: webVideoOnly.files[i].id })
await servers[0].videos.removeHLSFile({ videoId: hlsOnly.id, fileId: hlsOnly.streamingPlaylists[0].files[i].id })
}
const expectedStatus = HttpStatusCode.BAD_REQUEST_400
- await servers[0].videos.removeWebTorrentFile({ videoId: webtorrentOnly.id, fileId: webtorrentOnly.files[4].id, expectedStatus })
+ await servers[0].videos.removeWebVideoFile({ videoId: webVideoOnly.id, fileId: webVideoOnly.files[4].id, expectedStatus })
await servers[0].videos.removeHLSFile({ videoId: hlsOnly.id, fileId: hlsOnly.streamingPlaylists[0].files[4].id, expectedStatus })
})
})
server: PeerTubeServer
path: string
isLocal?: boolean
- hasWebtorrentFiles?: boolean
+ hasWebVideoFiles?: boolean
hasHLSFiles?: boolean
include?: VideoInclude
privacyOneOf?: VideoPrivacy[]
'include',
'category',
'tagsAllOf',
- 'hasWebtorrentFiles',
+ 'hasWebVideoFiles',
'hasHLSFiles',
'privacyOneOf',
'excludeAlreadyWatched'
}
})
- it('Should filter by HLS or WebTorrent files', async function () {
+ it('Should filter by HLS or Web Video files', async function () {
this.timeout(360000)
const finderFactory = (name: string) => (videos: Video[]) => videos.some(v => v.name === name)
await servers[0].config.enableTranscoding(true, false)
- await servers[0].videos.upload({ attributes: { name: 'webtorrent video' } })
- const hasWebtorrent = finderFactory('webtorrent video')
+ await servers[0].videos.upload({ attributes: { name: 'web video video' } })
+ const hasWebVideo = finderFactory('web video video')
await waitJobs(servers)
await waitJobs(servers)
await servers[0].config.enableTranscoding(true, true)
- await servers[0].videos.upload({ attributes: { name: 'hls and webtorrent video' } })
- const hasBoth = finderFactory('hls and webtorrent video')
+ await servers[0].videos.upload({ attributes: { name: 'hls and web video video' } })
+ const hasBoth = finderFactory('hls and web video video')
await waitJobs(servers)
for (const path of paths) {
{
- const videos = await listVideos({ server: servers[0], path, hasWebtorrentFiles: true })
+ const videos = await listVideos({ server: servers[0], path, hasWebVideoFiles: true })
- expect(hasWebtorrent(videos)).to.be.true
+ expect(hasWebVideo(videos)).to.be.true
expect(hasHLS(videos)).to.be.false
expect(hasBoth(videos)).to.be.true
}
{
- const videos = await listVideos({ server: servers[0], path, hasWebtorrentFiles: false })
+ const videos = await listVideos({ server: servers[0], path, hasWebVideoFiles: false })
- expect(hasWebtorrent(videos)).to.be.false
+ expect(hasWebVideo(videos)).to.be.false
expect(hasHLS(videos)).to.be.true
expect(hasBoth(videos)).to.be.false
}
{
const videos = await listVideos({ server: servers[0], path, hasHLSFiles: true })
- expect(hasWebtorrent(videos)).to.be.false
+ expect(hasWebVideo(videos)).to.be.false
expect(hasHLS(videos)).to.be.true
expect(hasBoth(videos)).to.be.true
}
{
const videos = await listVideos({ server: servers[0], path, hasHLSFiles: false })
- expect(hasWebtorrent(videos)).to.be.true
+ expect(hasWebVideo(videos)).to.be.true
expect(hasHLS(videos)).to.be.false
expect(hasBoth(videos)).to.be.false
}
{
- const videos = await listVideos({ server: servers[0], path, hasHLSFiles: false, hasWebtorrentFiles: false })
+ const videos = await listVideos({ server: servers[0], path, hasHLSFiles: false, hasWebVideoFiles: false })
- expect(hasWebtorrent(videos)).to.be.false
+ expect(hasWebVideo(videos)).to.be.false
expect(hasHLS(videos)).to.be.false
expect(hasBoth(videos)).to.be.false
}
{
- const videos = await listVideos({ server: servers[0], path, hasHLSFiles: true, hasWebtorrentFiles: true })
+ const videos = await listVideos({ server: servers[0], path, hasHLSFiles: true, hasWebVideoFiles: true })
- expect(hasWebtorrent(videos)).to.be.false
+ expect(hasWebVideo(videos)).to.be.false
expect(hasHLS(videos)).to.be.false
expect(hasBoth(videos)).to.be.true
}
}
if (objectStorage) {
- for (const webtorrentFile of video.files) {
- expectStartWith(webtorrentFile.fileUrl, objectStorage.getMockWebVideosBaseUrl())
+ for (const webVideoFile of video.files) {
+ expectStartWith(webVideoFile.fileUrl, objectStorage.getMockWebVideosBaseUrl())
}
for (const hlsFile of video.streamingPlaylists[0].files) {
let peertubeRunner: PeerTubeRunnerProcess
function runSuite (options: {
- webtorrentEnabled: boolean
+ webVideoEnabled: boolean
hlsEnabled: boolean
objectStorage?: ObjectStorageCommand
}) {
- const { webtorrentEnabled, hlsEnabled, objectStorage } = options
+ const { webVideoEnabled, hlsEnabled, objectStorage } = options
- const objectStorageBaseUrlWebTorrent = objectStorage
+ const objectStorageBaseUrlWebVideo = objectStorage
? objectStorage.getMockWebVideosBaseUrl()
: undefined
await waitJobs(servers, { runnerJobs: true })
for (const server of servers) {
- if (webtorrentEnabled) {
+ if (webVideoEnabled) {
await completeWebVideoFilesCheck({
server,
originServer: servers[0],
fixture: 'video_short.mp4',
videoUUID: uuid,
- objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
+ objectStorageBaseUrl: objectStorageBaseUrlWebVideo,
files: [
{ resolution: 0 },
{ resolution: 144 },
if (hlsEnabled) {
await completeCheckHlsPlaylist({
- hlsOnly: !webtorrentEnabled,
+ hlsOnly: !webVideoEnabled,
servers,
videoUUID: uuid,
objectStorageBaseUrl: objectStorageBaseUrlHLS,
await waitJobs(servers, { runnerJobs: true })
for (const server of servers) {
- if (webtorrentEnabled) {
+ if (webVideoEnabled) {
await completeWebVideoFilesCheck({
server,
originServer: servers[0],
fixture: 'video_short.webm',
videoUUID: uuid,
- objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
+ objectStorageBaseUrl: objectStorageBaseUrlWebVideo,
files: [
{ resolution: 0 },
{ resolution: 144 },
if (hlsEnabled) {
await completeCheckHlsPlaylist({
- hlsOnly: !webtorrentEnabled,
+ hlsOnly: !webVideoEnabled,
servers,
videoUUID: uuid,
objectStorageBaseUrl: objectStorageBaseUrlHLS,
await waitJobs(servers, { runnerJobs: true })
for (const server of servers) {
- if (webtorrentEnabled) {
+ if (webVideoEnabled) {
await completeWebVideoFilesCheck({
server,
originServer: servers[0],
fixture: 'sample.ogg',
videoUUID: uuid,
- objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
+ objectStorageBaseUrl: objectStorageBaseUrlWebVideo,
files: [
{ resolution: 0 },
{ resolution: 144 },
if (hlsEnabled) {
await completeCheckHlsPlaylist({
- hlsOnly: !webtorrentEnabled,
+ hlsOnly: !webVideoEnabled,
servers,
videoUUID: uuid,
objectStorageBaseUrl: objectStorageBaseUrlHLS,
await waitJobs(servers, { runnerJobs: true })
- if (webtorrentEnabled) {
+ if (webVideoEnabled) {
await completeWebVideoFilesCheck({
server: servers[0],
originServer: servers[0],
fixture: 'video_short.mp4',
videoUUID: uuid,
- objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
+ objectStorageBaseUrl: objectStorageBaseUrlWebVideo,
files: [
{ resolution: 0 },
{ resolution: 144 },
if (hlsEnabled) {
await completeCheckHlsPlaylist({
- hlsOnly: !webtorrentEnabled,
+ hlsOnly: !webVideoEnabled,
servers: [ servers[0] ],
videoUUID: uuid,
objectStorageBaseUrl: objectStorageBaseUrlHLS,
await servers[0].config.enableTranscoding(true, true, true)
- await servers[0].videos.runTranscoding({ transcodingType: 'webtorrent', videoId: uuid })
+ await servers[0].videos.runTranscoding({ transcodingType: 'web-video', videoId: uuid })
await waitJobs(servers, { runnerJobs: true })
await completeWebVideoFilesCheck({
originServer: servers[0],
fixture: 'video_short.mp4',
videoUUID: uuid,
- objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
+ objectStorageBaseUrl: objectStorageBaseUrlWebVideo,
files: [
{ resolution: 0 },
{ resolution: 144 },
await servers[0].config.enableTranscoding(true, false, true)
})
- runSuite({ webtorrentEnabled: true, hlsEnabled: false })
+ runSuite({ webVideoEnabled: true, hlsEnabled: false })
})
describe('HLS videos only enabled', function () {
await servers[0].config.enableTranscoding(false, true, true)
})
- runSuite({ webtorrentEnabled: false, hlsEnabled: true })
+ runSuite({ webVideoEnabled: false, hlsEnabled: true })
})
describe('Web video & HLS enabled', function () {
await servers[0].config.enableTranscoding(true, true, true)
})
- runSuite({ webtorrentEnabled: true, hlsEnabled: true })
+ runSuite({ webVideoEnabled: true, hlsEnabled: true })
})
})
await servers[0].config.enableTranscoding(true, false, true)
})
- runSuite({ webtorrentEnabled: true, hlsEnabled: false, objectStorage })
+ runSuite({ webVideoEnabled: true, hlsEnabled: false, objectStorage })
})
describe('HLS videos only enabled', function () {
await servers[0].config.enableTranscoding(false, true, true)
})
- runSuite({ webtorrentEnabled: false, hlsEnabled: true, objectStorage })
+ runSuite({ webVideoEnabled: false, hlsEnabled: true, objectStorage })
})
describe('Web video & HLS enabled', function () {
await servers[0].config.enableTranscoding(true, true, true)
})
- runSuite({ webtorrentEnabled: true, hlsEnabled: true, objectStorage })
+ runSuite({ webVideoEnabled: true, hlsEnabled: true, objectStorage })
})
after(async function () {
// Video files check
{
- expect(body.webtorrent.videoFiles).to.be.an('array')
+ expect(body.webVideo.videoFiles).to.be.an('array')
expect(body.hls.videoFiles).to.be.an('array')
for (const resolution of [ 144, 240, 360, 480, 720 ]) {
- for (const files of [ body.webtorrent.videoFiles, body.hls.videoFiles ]) {
+ for (const files of [ body.webVideo.videoFiles, body.hls.videoFiles ]) {
const file = files.find(f => f.resolution === resolution)
expect(file).to.exist
}
}
- videoPath = body.webtorrent.videoFiles[0].path
+ videoPath = body.webVideo.videoFiles[0].path
}
// Thumbnails check
const video = await server.videos.get({ id: videoUUID })
- const path = server.servers.buildWebTorrentFilePath(video.files[0].fileUrl)
+ const path = server.servers.buildWebVideoFilePath(video.files[0].fileUrl)
const audioProbe = await getAudioStream(path)
expect(audioProbe.audioStream.codec_name).to.equal('opus')
}) {
const { video, server, captions = [], onlyVideoFiles = false } = options
- const webtorrentFiles = video.files || []
+ const webVideoFiles = video.files || []
const hlsFiles = video.streamingPlaylists[0]?.files || []
const thumbnailName = basename(video.thumbnailPath)
const previewName = basename(video.previewPath)
- const torrentNames = webtorrentFiles.concat(hlsFiles).map(f => basename(f.torrentUrl))
+ const torrentNames = webVideoFiles.concat(hlsFiles).map(f => basename(f.torrentUrl))
const captionNames = captions.map(c => basename(c.captionPath))
- const webtorrentFilenames = webtorrentFiles.map(f => basename(f.fileUrl))
+ const webVideoFilenames = webVideoFiles.map(f => basename(f.fileUrl))
const hlsFilenames = hlsFiles.map(f => basename(f.fileUrl))
let directories: { [ directory: string ]: string[] } = {
- videos: webtorrentFilenames,
- redundancy: webtorrentFilenames,
+ videos: webVideoFilenames,
+ redundancy: webVideoFilenames,
[join('playlists', 'hls')]: hlsFilenames,
[join('redundancy', 'hls')]: hlsFilenames
}
}) as any
for (const redundancy of data) {
- const webtorrentFiles = redundancy.redundancies.files
+ const webVideoFiles = redundancy.redundancies.files
const streamingPlaylists = redundancy.redundancies.streamingPlaylists
let totalSize = ''
if (target === 'remote-videos') {
- const tmp = webtorrentFiles.concat(streamingPlaylists)
+ const tmp = webVideoFiles.concat(streamingPlaylists)
.reduce((a, b) => a + b.size, 0)
totalSize = bytes(tmp)
}
const instances = uniqify(
- webtorrentFiles.concat(streamingPlaylists)
+ webVideoFiles.concat(streamingPlaylists)
.map(r => r.fileUrl)
.map(u => new URL(u).host)
)
redundancy.id.toString(),
redundancy.name,
redundancy.url,
- webtorrentFiles.length,
+ webVideoFiles.length,
streamingPlaylists.length,
instances.join('\n'),
totalSize
return !!file.videoStreamingPlaylistId
}
-export function isWebtorrentFile (file: any): file is MVideoFileVideo {
+export function isWebVideoFile (file: any): file is MVideoFileVideo {
return !!file.videoId
}
ffprobe: (path: string) => Promise<any>
getFiles: (id: number | string) => Promise<{
- webtorrent: {
+ webtorrent: { // TODO: remove in v7
+ videoFiles: {
+ path: string // Could be null if using remote storage
+ url: string
+ resolution: number
+ size: number
+ fps: number
+ }[]
+ }
+
+ webVideo: {
videoFiles: {
path: string // Could be null if using remote storage
url: string
tagsAllOf?: string[]
hasHLSFiles?: boolean
- hasWebtorrentFiles?: boolean
+
+ hasWebtorrentFiles?: boolean // TODO: remove in v7
+ hasWebVideoFiles?: boolean
skipCount?: boolean
fps: number
copyCodecs: boolean
- deleteWebTorrentFiles: boolean
+ deleteWebVideoFiles: boolean
}
-export interface NewWebTorrentResolutionTranscodingPayload extends BaseTranscodingPayload {
- type: 'new-resolution-to-webtorrent'
+export interface NewWebVideoResolutionTranscodingPayload extends BaseTranscodingPayload {
+ type: 'new-resolution-to-web-video'
resolution: VideoResolution
fps: number
}
export interface MergeAudioTranscodingPayload extends BaseTranscodingPayload {
- type: 'merge-audio-to-webtorrent'
+ type: 'merge-audio-to-web-video'
resolution: VideoResolution
fps: number
}
export interface OptimizeTranscodingPayload extends BaseTranscodingPayload {
- type: 'optimize-to-webtorrent'
+ type: 'optimize-to-web-video'
quickTranscode: boolean
export type VideoTranscodingPayload =
HLSTranscodingPayload
- | NewWebTorrentResolutionTranscodingPayload
+ | NewWebVideoResolutionTranscodingPayload
| OptimizeTranscodingPayload
| MergeAudioTranscodingPayload
description?: string
nsfwPolicy?: NSFWPolicyType
- // FIXME: deprecated in favour of p2pEnabled in 4.1
- webTorrentEnabled?: boolean
p2pEnabled?: boolean
autoPlayVideo?: boolean
autoPlayNextVideo: boolean
autoPlayNextVideoPlaylist: boolean
- // @deprecated in favour of p2pEnabled
- webTorrentEnabled: boolean
p2pEnabled: boolean
videosHistoryEnabled: boolean
export interface VideoTranscodingCreate {
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
}
}
// TODO: convert args to object
- enableTranscoding (webtorrent = true, hls = true, with0p = false) {
+ enableTranscoding (webVideo = true, hls = true, with0p = false) {
return this.updateExistingSubConfig({
newConfig: {
transcoding: {
resolutions: ConfigCommand.getCustomConfigResolutions(true, with0p),
webtorrent: {
- enabled: webtorrent
+ enabled: webVideo
},
hls: {
enabled: hls
}
// TODO: convert args to object
- enableMinimumTranscoding (webtorrent = true, hls = true) {
+ enableMinimumTranscoding (webVideo = true, hls = true) {
return this.updateExistingSubConfig({
newConfig: {
transcoding: {
},
webtorrent: {
- enabled: webtorrent
+ enabled: webVideo
},
hls: {
enabled: hls
return join(root(), 'test' + this.server.internalServerNumber, directory)
}
- buildWebTorrentFilePath (fileUrl: string) {
+ buildWebVideoFilePath (fileUrl: string) {
return this.buildDirectory(join('videos', basename(fileUrl)))
}
})
}
- removeAllWebTorrentFiles (options: OverrideCommandOptions & {
+ removeAllWebVideoFiles (options: OverrideCommandOptions & {
videoId: number | string
}) {
- const path = '/api/v1/videos/' + options.videoId + '/webtorrent'
+ const path = '/api/v1/videos/' + options.videoId + '/web-videos'
return this.deleteRequest({
...options,
})
}
- removeWebTorrentFile (options: OverrideCommandOptions & {
+ removeWebVideoFile (options: OverrideCommandOptions & {
videoId: number | string
fileId: number
}) {
- const path = '/api/v1/videos/' + options.videoId + '/webtorrent/' + options.fileId
+ const path = '/api/v1/videos/' + options.videoId + '/web-videos/' + options.fileId
return this.deleteRequest({
...options,
runTranscoding (options: OverrideCommandOptions & {
videoId: number | string
- transcodingType: 'hls' | 'webtorrent'
+ transcodingType: 'hls' | 'webtorrent' | 'web-video'
}) {
const path = '/api/v1/videos/' + options.videoId + '/transcoding'
Force a specific player engine.
-Value must be a valid mode (`webtorrent` or `p2p-media-loader`).
+Value must be a valid mode (`web-video` or `p2p-media-loader`).
### api
get:
tags:
- Static Video Files
- summary: Get public WebTorrent video file
+ summary: Get public Web Video file
parameters:
- $ref: '#/components/parameters/staticFilename'
responses:
get:
tags:
- Static Video Files
- summary: Get private WebTorrent video file
+ summary: Get private Web Video video file
parameters:
- $ref: '#/components/parameters/staticFilename'
- $ref: '#/components/parameters/videoFileToken'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
responses:
'200':
description: successful operation
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
responses:
'200':
description: successful operation
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
description: >
Arises when:
- the emailer is disabled and the instance is open to registrations
- - webtorrent and hls are disabled with transcoding enabled - you need at least one enabled
+ - web videos and hls are disabled with transcoding enabled - you need at least one enabled
delete:
summary: Delete instance runtime configuration
operationId: delCustomConfig
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
type: object
properties:
passwords:
- $ref: '#/components/schemas/AddVideoPasswords'
+ $ref: '#/components/schemas/AddVideoPasswords'
responses:
'204':
description: successful operation
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
description: successful operation
'404':
description: video does not exist
- '/api/v1/videos/{id}/webtorrent':
+ '/api/v1/videos/{id}/web-videos':
delete:
- summary: Delete video WebTorrent files
+ summary: Delete video Web Video files
security:
- OAuth2:
- admin
tags:
- Video Files
- operationId: delVideoWebTorrent
+ operationId: delVideoWebVideos
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
type: string
enum:
- hls
- - webtorrent
+ - web-video
required:
- transcodingType
responses:
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/uuids'
- $ref: '#/components/parameters/hasHLSFiles'
- - $ref: '#/components/parameters/hasWebtorrentFiles'
+ - $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
schema:
type: boolean
description: '**PeerTube >= 4.0** Display only videos that have HLS files'
- hasWebtorrentFiles:
- name: hasWebtorrentFiles
+ hasWebVideoFiles:
+ name: hasWebVideoFiles
in: query
required: false
schema:
type: boolean
- description: '**PeerTube >= 4.0** Display only videos that have WebTorrent files'
+ description: '**PeerTube >= 4.0** Display only videos that have Web Video files'
privacyOneOf:
name: privacyOneOf
in: query
items:
$ref: '#/components/schemas/VideoFile'
description: |
- WebTorrent/raw video files. If WebTorrent is disabled on the server:
+ Web compatible video files. If Web Video is disabled on the server:
- field will be empty
- video files will be found in `streamingPlaylists[].files` field
type: boolean
webtorrent:
type: object
- description: WebTorrent-specific settings
+ description: Web Video specific settings
properties:
enabled:
type: boolean
hls:
type: object
- description: HLS-specific settings
+ description: HLS specific settings
properties:
enabled:
type: boolean
type: string
enum:
- 'p2p-media-loader'
- - 'webtorrent'
+ - 'web-video'
resolution:
type: number
description: Current player video resolution
password:
type: string
minLength: 2
- videoId:
+ videoId:
$ref: '#/components/schemas/id'
VideoPasswordList:
properties:
### create-import-video-file-job.js
-You can use this script to import a video file to replace an already uploaded file or to add a new webtorrent resolution to a video. PeerTube needs to be running.
+You can use this script to import a video file to replace an already uploaded file or to add a new web compatible resolution to a video. PeerTube needs to be running.
You can then create a transcoding job using the web interface if you need to optimize your file or create an HLS version of it.
```bash