]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/sync-channel.ts
Add test for RTMP stream without audio
[github/Chocobozzz/PeerTube.git] / server / lib / sync-channel.ts
CommitLineData
2a491182
F
1import { logger } from '@server/helpers/logger'
2import { YoutubeDLWrapper } from '@server/helpers/youtube-dl'
3import { CONFIG } from '@server/initializers/config'
4import { buildYoutubeDLImport } from '@server/lib/video-import'
5import { UserModel } from '@server/models/user/user'
6import { VideoImportModel } from '@server/models/video/video-import'
e9fc9e03 7import { MChannel, MChannelAccountDefault, MChannelSync } from '@server/types/models'
2a491182
F
8import { VideoChannelSyncState, VideoPrivacy } from '@shared/models'
9import { CreateJobArgument, JobQueue } from './job-queue'
10import { ServerConfigManager } from './server-config-manager'
11
12export async function synchronizeChannel (options: {
13 channel: MChannelAccountDefault
14 externalChannelUrl: string
15 channelSync?: MChannelSync
16 videosCountLimit?: number
17 onlyAfter?: Date
18}) {
19 const { channel, externalChannelUrl, videosCountLimit, onlyAfter, channelSync } = options
20
a3b472a1
C
21 if (channelSync) {
22 channelSync.state = VideoChannelSyncState.PROCESSING
23 channelSync.lastSyncAt = new Date()
24 await channelSync.save()
25 }
26
2a491182
F
27 const user = await UserModel.loadByChannelActorId(channel.actorId)
28 const youtubeDL = new YoutubeDLWrapper(
29 externalChannelUrl,
30 ServerConfigManager.Instance.getEnabledResolutions('vod'),
31 CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
32 )
33
e9fc9e03 34 const targetUrls = await youtubeDL.getInfoForListImport({ latestVideosCount: videosCountLimit })
2a491182
F
35
36 logger.info(
37 'Fetched %d candidate URLs for sync channel %s.',
38 targetUrls.length, channel.Actor.preferredUsername, { targetUrls }
39 )
40
41 if (targetUrls.length === 0) {
42 if (channelSync) {
43 channelSync.state = VideoChannelSyncState.SYNCED
44 await channelSync.save()
45 }
46
47 return
48 }
49
50 const children: CreateJobArgument[] = []
51
52 for (const targetUrl of targetUrls) {
e9fc9e03 53 if (await skipImport(channel, targetUrl, onlyAfter)) continue
2a491182
F
54
55 const { job } = await buildYoutubeDLImport({
56 user,
57 channel,
58 targetUrl,
59 channelSync,
60 importDataOverride: {
61 privacy: VideoPrivacy.PUBLIC
62 }
63 })
64
65 children.push(job)
66 }
67
a3b472a1 68 // Will update the channel sync status
2a491182
F
69 const parent: CreateJobArgument = {
70 type: 'after-video-channel-import',
71 payload: {
72 channelSyncId: channelSync?.id
73 }
74 }
75
76 await JobQueue.Instance.createJobWithChildren(parent, children)
77}
e9fc9e03
C
78
79// ---------------------------------------------------------------------------
80
81async function skipImport (channel: MChannel, targetUrl: string, onlyAfter?: Date) {
82 if (await VideoImportModel.urlAlreadyImported(channel.id, targetUrl)) {
9a3a23a8 83 logger.debug('%s is already imported for channel %s, skipping video channel synchronization.', targetUrl, channel.name)
e9fc9e03
C
84 return true
85 }
86
87 if (onlyAfter) {
88 const youtubeDL = new YoutubeDLWrapper(
89 targetUrl,
90 ServerConfigManager.Instance.getEnabledResolutions('vod'),
91 CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION
92 )
93
94 const videoInfo = await youtubeDL.getInfoForDownload()
95
3204f4d1 96 const onlyAfterWithoutTime = new Date(onlyAfter)
9a3a23a8 97 onlyAfterWithoutTime.setHours(0, 0, 0, 0)
3204f4d1 98
9a3a23a8 99 if (videoInfo.originallyPublishedAtWithoutTime.getTime() < onlyAfterWithoutTime.getTime()) {
e9fc9e03
C
100 return true
101 }
102 }
103
104 return false
105}