v6.3.2
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEExEqtY4NnkSypPt1XWDphLYkBWb4FAmcEviwACgkQWDphLYkB Wb6V9QgAgtGTp9zRJREaA769WZP6P09ytaIxuI3SnbVQ2rCLsdpdALFWgZ6ZvteH XQ2cEuykr9BZ+cioVmt5PCrU3nStzYG5P6WziubtEIdJemh0bv6E3En0u5ddau1r UvVedZPkVx5E7tTsl++CvlLBwnWt1OMPRYCK0/6sX5LgGFrHd/tKfrXUbf0kwH5E +Tha+eVINf3Ks4OEU66igqotQA5P7CHI6ls9fCkZM5hRm7bdA0RmCbRHviuOyXlW xAUboQhndo8BHtVoBIMvXJYhbaJ8UCwAK4E8YXSvO65h+pbrkMDG7BjLMX11GcKN BQmp2wA0VupPHvSTZlT9/eQc6w+d7Q== =+ma2 -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQJLBAABCAA1FiEEGCBYi9NGimfngx9dVTwOu+tdXwgFAmcNTDcXHGdpdEBrb3Rv dmFsZXhhcmlhbi5jb20ACgkQVTwOu+tdXwgevA/+My9McwmndIHdmLMjKTush7lT LlDIAZtSMX+Om+i0KzRvyE9VXI5kN8QzBolUH8vgBgk4eVKoLUaTPJKFIp4SzQrX UzUxXTA1iSPA9Tjnj/akcrLFpIBtjQUOix0h5itMo1+g/KO2JAgeU0ATrjfK+hH0 nDWDVWjYd4qzLzPSRqUJfUxfwU6FL+KehwW8M2URLP65xjh+CK8gKnxbuJESfaIC 8AJj0rpWm1QvMNKwVxyR2K3eTJ5o7kSiM+DE6GQ30Q5ph+LnZz1J0PxH4yc7c5RU 1DAOxrFmnVcimZ6dZceE0tozs6SMfqXeNm49qoS2aAvUBWgJs0tafB4pmwv2/p0x N39XduMfeeziRv7Ak5LTckqmSUSrF+BkZaI9+GyQxgO6plzRDfyiI3B1NXbqylUk o8ZR3rsxzeGFWfpHYdcoN7a3PT99vZ3E04eOPEYrX6J5/y4+EYp+/eZOr/IYuH8v pYudS5KrYZoPwpGKB4Ndy0+E3Q49Iz7HaMXB9FkqxLSWBwdar4Tzm/gdt37pGUj8 2vCtO/dRxFdsmIm2LRsVMprn4MYaa7FQwB9y3zq3NIj7yV4BnNAdsYszf1XszZql U0dbBrkxE/9epdBIhPuBEo4KAUX284JClbX1iKecdqPNi9Xl4yVIgffztDqBb0r2 i7MuxFhAJbRM/wDqL+U= =t78K -----END PGP SIGNATURE----- Merge tag 'v6.3.2' into changes v6.3.2
This commit is contained in:
commit
d36c84e880
17 changed files with 110 additions and 30 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,5 +1,18 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v6.3.2
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
* Fix 403 error when downloading private/internal video
|
||||||
|
* Don't crash video federation and live replay generation on missing thumbnail/preview
|
||||||
|
* Fix advanced search input with multiple automatic search tokens
|
||||||
|
* Fix player "Copy URL" when the video is fullscreen
|
||||||
|
* Fix account videos search
|
||||||
|
* Add missing max transcoding fps config in admin
|
||||||
|
* Don't add mobile buttons if the player controls are disabled
|
||||||
|
|
||||||
|
|
||||||
## v6.3.1
|
## v6.3.1
|
||||||
|
|
||||||
### IMPORTANT NOTES
|
### IMPORTANT NOTES
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "peertube-client",
|
"name": "peertube-client",
|
||||||
"version": "6.3.1",
|
"version": "6.3.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"author": {
|
"author": {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
SERVICES_TWITTER_USERNAME_VALIDATOR,
|
SERVICES_TWITTER_USERNAME_VALIDATOR,
|
||||||
SIGNUP_LIMIT_VALIDATOR,
|
SIGNUP_LIMIT_VALIDATOR,
|
||||||
SIGNUP_MINIMUM_AGE_VALIDATOR,
|
SIGNUP_MINIMUM_AGE_VALIDATOR,
|
||||||
|
TRANSCODING_MAX_FPS_VALIDATOR,
|
||||||
TRANSCODING_THREADS_VALIDATOR
|
TRANSCODING_THREADS_VALIDATOR
|
||||||
} from '@app/shared/form-validators/custom-config-validators'
|
} from '@app/shared/form-validators/custom-config-validators'
|
||||||
import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
||||||
|
@ -30,6 +31,7 @@ import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.serv
|
||||||
import { CustomPageService } from '@app/shared/shared-main/custom-page/custom-page.service'
|
import { CustomPageService } from '@app/shared/shared-main/custom-page/custom-page.service'
|
||||||
import { NgbNav, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavLinkBase, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbNav, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavLinkBase, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { CustomConfig, CustomPage, HTMLServerConfig } from '@peertube/peertube-models'
|
import { CustomConfig, CustomPage, HTMLServerConfig } from '@peertube/peertube-models'
|
||||||
|
import merge from 'lodash-es/merge'
|
||||||
import omit from 'lodash-es/omit'
|
import omit from 'lodash-es/omit'
|
||||||
import { forkJoin } from 'rxjs'
|
import { forkJoin } from 'rxjs'
|
||||||
import { SelectOptionsItem } from 'src/types/select-options-item.model'
|
import { SelectOptionsItem } from 'src/types/select-options-item.model'
|
||||||
|
@ -40,7 +42,6 @@ import { EditHomepageComponent } from './edit-homepage.component'
|
||||||
import { EditInstanceInformationComponent } from './edit-instance-information.component'
|
import { EditInstanceInformationComponent } from './edit-instance-information.component'
|
||||||
import { EditLiveConfigurationComponent } from './edit-live-configuration.component'
|
import { EditLiveConfigurationComponent } from './edit-live-configuration.component'
|
||||||
import { EditVODTranscodingComponent } from './edit-vod-transcoding.component'
|
import { EditVODTranscodingComponent } from './edit-vod-transcoding.component'
|
||||||
import merge from 'lodash-es/merge'
|
|
||||||
|
|
||||||
type ComponentCustomConfig = CustomConfig & {
|
type ComponentCustomConfig = CustomConfig & {
|
||||||
instanceCustomHomepage: CustomPage
|
instanceCustomHomepage: CustomPage
|
||||||
|
@ -239,6 +240,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
||||||
},
|
},
|
||||||
remoteRunners: {
|
remoteRunners: {
|
||||||
enabled: null
|
enabled: null
|
||||||
|
},
|
||||||
|
fps: {
|
||||||
|
max: TRANSCODING_MAX_FPS_VALIDATOR
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
live: {
|
live: {
|
||||||
|
@ -260,6 +264,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
||||||
alwaysTranscodeOriginalResolution: null,
|
alwaysTranscodeOriginalResolution: null,
|
||||||
remoteRunners: {
|
remoteRunners: {
|
||||||
enabled: null
|
enabled: null
|
||||||
|
},
|
||||||
|
fps: {
|
||||||
|
max: TRANSCODING_MAX_FPS_VALIDATOR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<div class="form-group" [ngClass]="getDisabledLiveClass()">
|
<div class="form-group" [ngClass]="getDisabledLiveClass()">
|
||||||
<label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance</label>
|
<label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance</label>
|
||||||
|
|
||||||
<span class="ms-2 small muted">(-1 for "unlimited")</span>
|
<span i18n class="ms-2 small muted">(-1 for "unlimited")</span>
|
||||||
|
|
||||||
<div class="number-with-unit">
|
<div class="number-with-unit">
|
||||||
<input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" />
|
<input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" />
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
<div class="form-group" [ngClass]="getDisabledLiveClass()">
|
<div class="form-group" [ngClass]="getDisabledLiveClass()">
|
||||||
<label i18n for="liveMaxUserLives">Max simultaneous lives created per user</label>
|
<label i18n for="liveMaxUserLives">Max simultaneous lives created per user</label>
|
||||||
<span class="ms-2 small muted">(-1 for "unlimited")</span>
|
<span i18n class="ms-2 small muted">(-1 for "unlimited")</span>
|
||||||
|
|
||||||
<div class="number-with-unit">
|
<div class="number-with-unit">
|
||||||
<input type="number" name="liveMaxUserLives" formControlName="maxUserLives" />
|
<input type="number" name="liveMaxUserLives" formControlName="maxUserLives" />
|
||||||
|
@ -116,6 +116,19 @@
|
||||||
|
|
||||||
<div [ngClass]="getDisabledLiveTranscodingClass()">
|
<div [ngClass]="getDisabledLiveTranscodingClass()">
|
||||||
|
|
||||||
|
<div class="form-group" formGroupName="fps">
|
||||||
|
<label i18n for="liveTranscodingFPSMax">Max live FPS</label>
|
||||||
|
|
||||||
|
<span i18n class="ms-2 small muted">Cap transcoded live FPS. Max resolution stream still keeps the original FPS.</span>
|
||||||
|
|
||||||
|
<div class="number-with-unit">
|
||||||
|
<input type="number" name="liveTranscodingFPSMax" formControlName="max" />
|
||||||
|
<span>FPS</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="formErrors.live.transcoding.fps.max" class="form-error" role="alert">{{ formErrors.live.transcoding.fps.max }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="ms-2 mt-3">
|
<div class="ms-2 mt-3">
|
||||||
<h4 i18n>Live resolutions to generate</h4>
|
<h4 i18n>Live resolutions to generate</h4>
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,19 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<div class="form-group" formGroupName="fps" [ngClass]="getTranscodingDisabledClass()">
|
||||||
|
<label i18n for="transcodingFPSMax">Max video FPS</label>
|
||||||
|
|
||||||
|
<span i18n class="ms-2 small muted">Cap transcoded video FPS. Max resolution file still keeps the original FPS.</span>
|
||||||
|
|
||||||
|
<div class="number-with-unit">
|
||||||
|
<input type="number" name="transcodingFPSMax" formControlName="max" />
|
||||||
|
<span>FPS</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="formErrors.transcoding.fps.max" class="form-error" role="alert">{{ formErrors.transcoding.fps.max }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group" [ngClass]="getTranscodingDisabledClass()">
|
<div class="form-group" [ngClass]="getTranscodingDisabledClass()">
|
||||||
<div class="mb-2 fw-bold" i18n>Resolutions to generate</div>
|
<div class="mb-2 fw-bold" i18n>Resolutions to generate</div>
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,14 @@ export const TRANSCODING_THREADS_VALIDATOR: BuildFormValidator = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const TRANSCODING_MAX_FPS_VALIDATOR: BuildFormValidator = {
|
||||||
|
VALIDATORS: [ Validators.required, Validators.min(1) ],
|
||||||
|
MESSAGES: {
|
||||||
|
required: $localize`Transcoding max FPS is required.`,
|
||||||
|
min: $localize`Transcoding max FPS must be greater or equal to 1.`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const MAX_LIVE_DURATION_VALIDATOR: BuildFormValidator = {
|
export const MAX_LIVE_DURATION_VALIDATOR: BuildFormValidator = {
|
||||||
VALIDATORS: [ Validators.required, Validators.min(-1) ],
|
VALIDATORS: [ Validators.required, Validators.min(-1) ],
|
||||||
MESSAGES: {
|
MESSAGES: {
|
||||||
|
|
|
@ -155,25 +155,30 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private addFilterToSearch (search: string, newFilter: AdvancedInputFilterChild) {
|
private addFilterToSearch (search: string, newFilter: AdvancedInputFilterChild) {
|
||||||
const prefix = newFilter.value.split(':').shift()
|
const filterTokens = this.restService.tokenizeString(newFilter.value)
|
||||||
|
let searchTokens = this.restService.tokenizeString(search)
|
||||||
|
|
||||||
// Tokenize search and remove a potential existing filter
|
for (const filterToken of filterTokens) {
|
||||||
const tokens = this.restService.tokenizeString(search)
|
const prefix = filterToken.split(':').shift()
|
||||||
.filter(t => !t.startsWith(prefix))
|
|
||||||
|
|
||||||
tokens.push(newFilter.value)
|
// Tokenize search and remove a potential existing filter
|
||||||
|
searchTokens = searchTokens.filter(t => !t.startsWith(prefix))
|
||||||
|
searchTokens.push(filterToken)
|
||||||
|
}
|
||||||
|
|
||||||
return tokens.join(' ')
|
return searchTokens.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseFilters (search: string) {
|
private parseFilters (search: string) {
|
||||||
const tokens = this.restService.tokenizeString(search)
|
const searchTokens = this.restService.tokenizeString(search)
|
||||||
|
|
||||||
this.enabledFilters = new Set()
|
this.enabledFilters = new Set()
|
||||||
|
|
||||||
for (const group of this.filters) {
|
for (const group of this.filters) {
|
||||||
for (const filter of group.children) {
|
for (const filter of group.children) {
|
||||||
if (tokens.includes(filter.value)) {
|
const filterTokens = this.restService.tokenizeString(filter.value)
|
||||||
|
|
||||||
|
if (filterTokens.every(filterToken => searchTokens.includes(filterToken))) {
|
||||||
this.enabledFilters.add(filter.value)
|
this.enabledFilters.add(filter.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,14 +384,17 @@ export class VideoService {
|
||||||
generateDownloadUrl (options: {
|
generateDownloadUrl (options: {
|
||||||
video: Video
|
video: Video
|
||||||
files: VideoFile[]
|
files: VideoFile[]
|
||||||
|
videoFileToken?: string
|
||||||
}) {
|
}) {
|
||||||
const { video, files } = options
|
const { video, files, videoFileToken } = options
|
||||||
|
|
||||||
if (files.length === 0) throw new Error('Cannot generate download URL without files')
|
if (files.length === 0) throw new Error('Cannot generate download URL without files')
|
||||||
|
|
||||||
let url = `${VideoService.BASE_VIDEO_DOWNLOAD_URL}/${video.uuid}?`
|
let url = `${VideoService.BASE_VIDEO_DOWNLOAD_URL}/${video.uuid}?`
|
||||||
url += files.map(f => 'videoFileIds=' + f.id).join('&')
|
url += files.map(f => 'videoFileIds=' + f.id).join('&')
|
||||||
|
|
||||||
|
if (videoFileToken) url += `&videoFileToken=${videoFileToken}`
|
||||||
|
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
|
||||||
next: () => {
|
next: () => {
|
||||||
this.authService.refreshUserInformation()
|
this.authService.refreshUserInformation()
|
||||||
|
|
||||||
if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`, 'toto', 15000)
|
if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`)
|
||||||
},
|
},
|
||||||
|
|
||||||
error: err => this.notifier.error(err.message)
|
error: err => this.notifier.error(err.message)
|
||||||
|
|
|
@ -104,7 +104,7 @@ export class VideoGenerateDownloadComponent implements OnInit {
|
||||||
files.push(this.findAudioFileOnly())
|
files.push(this.findAudioFileOnly())
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.videoService.generateDownloadUrl({ video: this.video, files })
|
return this.videoService.generateDownloadUrl({ video: this.video, videoFileToken: this.videoFileToken, files })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -45,7 +45,8 @@ export class VideoFilters {
|
||||||
[ 'categoryOneOf', undefined ],
|
[ 'categoryOneOf', undefined ],
|
||||||
[ 'scope', 'federated' ],
|
[ 'scope', 'federated' ],
|
||||||
[ 'allVideos', false ],
|
[ 'allVideos', false ],
|
||||||
[ 'live', 'both' ]
|
[ 'live', 'both' ],
|
||||||
|
[ 'search', '' ]
|
||||||
])
|
])
|
||||||
|
|
||||||
private activeFilters: VideoFilterActive[] = []
|
private activeFilters: VideoFilterActive[] = []
|
||||||
|
|
|
@ -502,7 +502,7 @@ export class PeerTubePlayer {
|
||||||
{
|
{
|
||||||
label: player.localize('Copy the video URL'),
|
label: player.localize('Copy the video URL'),
|
||||||
listener: function () {
|
listener: function () {
|
||||||
copyToClipboard(buildVideoLink({ shortUUID }))
|
copyToClipboard(buildVideoLink({ shortUUID }), player.el() as HTMLElement)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -510,17 +510,17 @@ export class PeerTubePlayer {
|
||||||
listener: function () {
|
listener: function () {
|
||||||
const url = buildVideoLink({ shortUUID })
|
const url = buildVideoLink({ shortUUID })
|
||||||
|
|
||||||
copyToClipboard(decorateVideoLink({ url, startTime: player.currentTime() }))
|
copyToClipboard(decorateVideoLink({ url, startTime: player.currentTime() }), player.el() as HTMLElement)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'code',
|
icon: 'code',
|
||||||
label: player.localize('Copy embed code'),
|
label: player.localize('Copy embed code'),
|
||||||
listener: () => {
|
listener: () => {
|
||||||
copyToClipboard(buildVideoOrPlaylistEmbed({
|
copyToClipboard(
|
||||||
embedUrl: self.currentLoadOptions.embedUrl,
|
buildVideoOrPlaylistEmbed({ embedUrl: self.currentLoadOptions.embedUrl, embedTitle: self.currentLoadOptions.embedTitle }),
|
||||||
embedTitle: self.currentLoadOptions.embedTitle
|
player.el() as HTMLElement
|
||||||
}))
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,12 +36,15 @@ class PeerTubeMobilePlugin extends Plugin {
|
||||||
|
|
||||||
this.seekAmount = 0
|
this.seekAmount = 0
|
||||||
|
|
||||||
this.peerTubeMobileButtons = player.addChild('PeerTubeMobileButtons', { reportTouchActivity: false }) as PeerTubeMobileButtons
|
|
||||||
|
|
||||||
if (videojs.browser.IS_ANDROID && screen.orientation) {
|
if (videojs.browser.IS_ANDROID && screen.orientation) {
|
||||||
this.handleFullscreenRotation()
|
this.handleFullscreenRotation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't add buttons if the player doesn't have controls
|
||||||
|
if (!player.controls()) return
|
||||||
|
|
||||||
|
this.peerTubeMobileButtons = player.addChild('PeerTubeMobileButtons', { reportTouchActivity: false }) as PeerTubeMobileButtons
|
||||||
|
|
||||||
if (!this.player.options_.userActions) this.player.options_.userActions = {};
|
if (!this.player.options_.userActions) this.player.options_.userActions = {};
|
||||||
|
|
||||||
// FIXME: typings
|
// FIXME: typings
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
function copyToClipboard (text: string) {
|
function copyToClipboard (text: string, container?: HTMLElement) {
|
||||||
|
if (!container) container = document.body
|
||||||
|
|
||||||
const el = document.createElement('textarea')
|
const el = document.createElement('textarea')
|
||||||
el.value = text
|
el.value = text
|
||||||
el.setAttribute('readonly', '')
|
el.setAttribute('readonly', '')
|
||||||
el.style.position = 'absolute'
|
el.style.position = 'absolute'
|
||||||
el.style.left = '-9999px'
|
el.style.left = '-9999px'
|
||||||
document.body.appendChild(el)
|
container.appendChild(el)
|
||||||
el.select()
|
el.select()
|
||||||
document.execCommand('copy')
|
document.execCommand('copy')
|
||||||
document.body.removeChild(el)
|
container.removeChild(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
function wait (ms: number) {
|
function wait (ms: number) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "peertube",
|
"name": "peertube",
|
||||||
"description": "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.",
|
"description": "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.",
|
||||||
"version": "6.3.1",
|
"version": "6.3.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"licence": "AGPL-3.0",
|
"licence": "AGPL-3.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -178,7 +178,14 @@ async function saveReplayToExternalVideo (options: {
|
||||||
inputFileMutexReleaser()
|
inputFileMutexReleaser()
|
||||||
}
|
}
|
||||||
|
|
||||||
await copyOrRegenerateThumbnails({ liveVideo, replayVideo })
|
try {
|
||||||
|
await copyOrRegenerateThumbnails({ liveVideo, replayVideo })
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(
|
||||||
|
`Cannot copy/regenerate thumbnails of ended live ${liveVideo.uuid} to external video ${replayVideo.uuid}`,
|
||||||
|
lTags(liveVideo.uuid, replayVideo.uuid)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
await createStoryboardJob(replayVideo)
|
await createStoryboardJob(replayVideo)
|
||||||
await createTranscriptionTaskIfNeeded(replayVideo)
|
await createTranscriptionTaskIfNeeded(replayVideo)
|
||||||
|
@ -280,7 +287,11 @@ async function replaceLiveByReplay (options: {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate the thumbnail & preview?
|
// Regenerate the thumbnail & preview?
|
||||||
await regenerateMiniaturesIfNeeded(videoWithFiles, undefined)
|
try {
|
||||||
|
await regenerateMiniaturesIfNeeded(videoWithFiles, undefined)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(`Cannot regenerate thumbnails of ended live ${videoWithFiles.uuid}`, lTags(liveVideo.uuid))
|
||||||
|
}
|
||||||
|
|
||||||
// We consider this is a new video
|
// We consider this is a new video
|
||||||
await moveToNextState({ video: videoWithFiles, isNewVideo: true })
|
await moveToNextState({ video: videoWithFiles, isNewVideo: true })
|
||||||
|
|
|
@ -284,6 +284,7 @@ function buildTags (video: MVideoAP) {
|
||||||
|
|
||||||
function buildIcon (video: MVideoAP): ActivityIconObject[] {
|
function buildIcon (video: MVideoAP): ActivityIconObject[] {
|
||||||
return [ video.getMiniature(), video.getPreview() ]
|
return [ video.getMiniature(), video.getPreview() ]
|
||||||
|
.filter(i => !!i)
|
||||||
.map(i => i.toActivityPubObject(video))
|
.map(i => i.toActivityPubObject(video))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue