diff options
author | Chocobozzz <me@florianbigard.com> | 2018-06-12 20:04:58 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-06-12 20:37:51 +0200 |
commit | 2186386cca113506791583cb07d6ccacba7af4e0 (patch) | |
tree | 3c214c0b5fbd64332624267fa6e51fd4a9cf6474 /server/controllers/api/videos | |
parent | 6ccdf3a23ecec5ba2eeaf487fd1fafdc7606b4bf (diff) | |
download | PeerTube-2186386cca113506791583cb07d6ccacba7af4e0.tar.gz PeerTube-2186386cca113506791583cb07d6ccacba7af4e0.tar.zst PeerTube-2186386cca113506791583cb07d6ccacba7af4e0.zip |
Add concept of video state, and add ability to wait transcoding before
publishing a video
Diffstat (limited to 'server/controllers/api/videos')
-rw-r--r-- | server/controllers/api/videos/index.ts | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 7f5e74626..9d9b2b0e1 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { extname, join } from 'path' | 2 | import { extname, join } from 'path' |
3 | import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared' | 3 | import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared' |
4 | import { renamePromise } from '../../../helpers/core-utils' | 4 | import { renamePromise } from '../../../helpers/core-utils' |
5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
6 | import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils' | 6 | import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils' |
@@ -21,11 +21,11 @@ import { | |||
21 | } from '../../../initializers' | 21 | } from '../../../initializers' |
22 | import { | 22 | import { |
23 | changeVideoChannelShare, | 23 | changeVideoChannelShare, |
24 | federateVideoIfNeeded, | ||
24 | fetchRemoteVideoDescription, | 25 | fetchRemoteVideoDescription, |
25 | getVideoActivityPubUrl, | 26 | getVideoActivityPubUrl |
26 | shareVideoByServerAndChannel | ||
27 | } from '../../../lib/activitypub' | 27 | } from '../../../lib/activitypub' |
28 | import { sendCreateVideo, sendCreateView, sendUpdateVideo } from '../../../lib/activitypub/send' | 28 | import { sendCreateView } from '../../../lib/activitypub/send' |
29 | import { JobQueue } from '../../../lib/job-queue' | 29 | import { JobQueue } from '../../../lib/job-queue' |
30 | import { Redis } from '../../../lib/redis' | 30 | import { Redis } from '../../../lib/redis' |
31 | import { | 31 | import { |
@@ -51,7 +51,7 @@ import { videoCommentRouter } from './comment' | |||
51 | import { rateVideoRouter } from './rate' | 51 | import { rateVideoRouter } from './rate' |
52 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' | 52 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' |
53 | import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type' | 53 | import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type' |
54 | import { isNSFWHidden, createReqFiles } from '../../../helpers/express-utils' | 54 | import { createReqFiles, isNSFWHidden } from '../../../helpers/express-utils' |
55 | 55 | ||
56 | const videosRouter = express.Router() | 56 | const videosRouter = express.Router() |
57 | 57 | ||
@@ -185,8 +185,10 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi | |||
185 | category: videoInfo.category, | 185 | category: videoInfo.category, |
186 | licence: videoInfo.licence, | 186 | licence: videoInfo.licence, |
187 | language: videoInfo.language, | 187 | language: videoInfo.language, |
188 | commentsEnabled: videoInfo.commentsEnabled, | 188 | commentsEnabled: videoInfo.commentsEnabled || false, |
189 | nsfw: videoInfo.nsfw, | 189 | waitTranscoding: videoInfo.waitTranscoding || false, |
190 | state: CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED, | ||
191 | nsfw: videoInfo.nsfw || false, | ||
190 | description: videoInfo.description, | 192 | description: videoInfo.description, |
191 | support: videoInfo.support, | 193 | support: videoInfo.support, |
192 | privacy: videoInfo.privacy, | 194 | privacy: videoInfo.privacy, |
@@ -194,19 +196,20 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi | |||
194 | channelId: res.locals.videoChannel.id | 196 | channelId: res.locals.videoChannel.id |
195 | } | 197 | } |
196 | const video = new VideoModel(videoData) | 198 | const video = new VideoModel(videoData) |
197 | video.url = getVideoActivityPubUrl(video) | 199 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
198 | 200 | ||
201 | // Build the file object | ||
199 | const { videoFileResolution } = await getVideoFileResolution(videoPhysicalFile.path) | 202 | const { videoFileResolution } = await getVideoFileResolution(videoPhysicalFile.path) |
200 | |||
201 | const videoFileData = { | 203 | const videoFileData = { |
202 | extname: extname(videoPhysicalFile.filename), | 204 | extname: extname(videoPhysicalFile.filename), |
203 | resolution: videoFileResolution, | 205 | resolution: videoFileResolution, |
204 | size: videoPhysicalFile.size | 206 | size: videoPhysicalFile.size |
205 | } | 207 | } |
206 | const videoFile = new VideoFileModel(videoFileData) | 208 | const videoFile = new VideoFileModel(videoFileData) |
209 | |||
210 | // Move physical file | ||
207 | const videoDir = CONFIG.STORAGE.VIDEOS_DIR | 211 | const videoDir = CONFIG.STORAGE.VIDEOS_DIR |
208 | const destination = join(videoDir, video.getVideoFilename(videoFile)) | 212 | const destination = join(videoDir, video.getVideoFilename(videoFile)) |
209 | |||
210 | await renamePromise(videoPhysicalFile.path, destination) | 213 | await renamePromise(videoPhysicalFile.path, destination) |
211 | // This is important in case if there is another attempt in the retry process | 214 | // This is important in case if there is another attempt in the retry process |
212 | videoPhysicalFile.filename = video.getVideoFilename(videoFile) | 215 | videoPhysicalFile.filename = video.getVideoFilename(videoFile) |
@@ -230,6 +233,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi | |||
230 | await video.createPreview(videoFile) | 233 | await video.createPreview(videoFile) |
231 | } | 234 | } |
232 | 235 | ||
236 | // Create the torrent file | ||
233 | await video.createTorrentAndSetInfoHash(videoFile) | 237 | await video.createTorrentAndSetInfoHash(videoFile) |
234 | 238 | ||
235 | const videoCreated = await sequelizeTypescript.transaction(async t => { | 239 | const videoCreated = await sequelizeTypescript.transaction(async t => { |
@@ -251,20 +255,14 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi | |||
251 | video.Tags = tagInstances | 255 | video.Tags = tagInstances |
252 | } | 256 | } |
253 | 257 | ||
254 | // Let transcoding job send the video to friends because the video file extension might change | 258 | await federateVideoIfNeeded(video, true, t) |
255 | if (CONFIG.TRANSCODING.ENABLED === true) return videoCreated | ||
256 | // Don't send video to remote servers, it is private | ||
257 | if (video.privacy === VideoPrivacy.PRIVATE) return videoCreated | ||
258 | |||
259 | await sendCreateVideo(video, t) | ||
260 | await shareVideoByServerAndChannel(video, t) | ||
261 | 259 | ||
262 | logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) | 260 | logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) |
263 | 261 | ||
264 | return videoCreated | 262 | return videoCreated |
265 | }) | 263 | }) |
266 | 264 | ||
267 | if (CONFIG.TRANSCODING.ENABLED === true) { | 265 | if (video.state === VideoState.TO_TRANSCODE) { |
268 | // Put uuid because we don't have id auto incremented for now | 266 | // Put uuid because we don't have id auto incremented for now |
269 | const dataInput = { | 267 | const dataInput = { |
270 | videoUUID: videoCreated.uuid, | 268 | videoUUID: videoCreated.uuid, |
@@ -318,6 +316,7 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
318 | if (videoInfoToUpdate.licence !== undefined) videoInstance.set('licence', videoInfoToUpdate.licence) | 316 | if (videoInfoToUpdate.licence !== undefined) videoInstance.set('licence', videoInfoToUpdate.licence) |
319 | if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language) | 317 | if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language) |
320 | if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw) | 318 | if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw) |
319 | if (videoInfoToUpdate.waitTranscoding !== undefined) videoInstance.set('waitTranscoding', videoInfoToUpdate.waitTranscoding) | ||
321 | if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support) | 320 | if (videoInfoToUpdate.support !== undefined) videoInstance.set('support', videoInfoToUpdate.support) |
322 | if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description) | 321 | if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description) |
323 | if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled) | 322 | if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled) |
@@ -343,19 +342,13 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
343 | // Video channel update? | 342 | // Video channel update? |
344 | if (res.locals.videoChannel && videoInstanceUpdated.channelId !== res.locals.videoChannel.id) { | 343 | if (res.locals.videoChannel && videoInstanceUpdated.channelId !== res.locals.videoChannel.id) { |
345 | await videoInstanceUpdated.$set('VideoChannel', res.locals.videoChannel, { transaction: t }) | 344 | await videoInstanceUpdated.$set('VideoChannel', res.locals.videoChannel, { transaction: t }) |
346 | videoInstance.VideoChannel = res.locals.videoChannel | 345 | videoInstanceUpdated.VideoChannel = res.locals.videoChannel |
347 | 346 | ||
348 | if (wasPrivateVideo === false) await changeVideoChannelShare(videoInstanceUpdated, oldVideoChannel, t) | 347 | if (wasPrivateVideo === false) await changeVideoChannelShare(videoInstanceUpdated, oldVideoChannel, t) |
349 | } | 348 | } |
350 | 349 | ||
351 | // Now we'll update the video's meta data to our friends | 350 | const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE |
352 | if (wasPrivateVideo === false) await sendUpdateVideo(videoInstanceUpdated, t) | 351 | await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo) |
353 | |||
354 | // Video is not private anymore, send a create action to remote servers | ||
355 | if (wasPrivateVideo === true && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE) { | ||
356 | await sendCreateVideo(videoInstanceUpdated, t) | ||
357 | await shareVideoByServerAndChannel(videoInstanceUpdated, t) | ||
358 | } | ||
359 | }) | 352 | }) |
360 | 353 | ||
361 | logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid) | 354 | logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid) |