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 | |
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')
-rw-r--r-- | server/controllers/activitypub/client.ts | 8 | ||||
-rw-r--r-- | server/controllers/activitypub/outbox.ts | 4 | ||||
-rw-r--r-- | server/controllers/api/users.ts | 7 | ||||
-rw-r--r-- | server/controllers/api/videos/index.ts | 47 |
4 files changed, 30 insertions, 36 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 1c780783c..ea8e25f68 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -123,11 +123,11 @@ async function accountFollowingController (req: express.Request, res: express.Re | |||
123 | async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) { | 123 | async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) { |
124 | const video: VideoModel = res.locals.video | 124 | const video: VideoModel = res.locals.video |
125 | 125 | ||
126 | const audience = await getAudience(video.VideoChannel.Account.Actor, undefined, video.privacy === VideoPrivacy.PUBLIC) | 126 | const audience = getAudience(video.VideoChannel.Account.Actor, video.privacy === VideoPrivacy.PUBLIC) |
127 | const videoObject = audiencify(video.toActivityPubObject(), audience) | 127 | const videoObject = audiencify(video.toActivityPubObject(), audience) |
128 | 128 | ||
129 | if (req.path.endsWith('/activity')) { | 129 | if (req.path.endsWith('/activity')) { |
130 | const data = await createActivityData(video.url, video.VideoChannel.Account.Actor, videoObject, undefined, audience) | 130 | const data = createActivityData(video.url, video.VideoChannel.Account.Actor, videoObject, audience) |
131 | return activityPubResponse(activityPubContextify(data), res) | 131 | return activityPubResponse(activityPubContextify(data), res) |
132 | } | 132 | } |
133 | 133 | ||
@@ -210,12 +210,12 @@ async function videoCommentController (req: express.Request, res: express.Respon | |||
210 | 210 | ||
211 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) | 211 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) |
212 | const isPublic = true // Comments are always public | 212 | const isPublic = true // Comments are always public |
213 | const audience = await getAudience(videoComment.Account.Actor, undefined, isPublic) | 213 | const audience = getAudience(videoComment.Account.Actor, isPublic) |
214 | 214 | ||
215 | const videoCommentObject = audiencify(videoComment.toActivityPubObject(threadParentComments), audience) | 215 | const videoCommentObject = audiencify(videoComment.toActivityPubObject(threadParentComments), audience) |
216 | 216 | ||
217 | if (req.path.endsWith('/activity')) { | 217 | if (req.path.endsWith('/activity')) { |
218 | const data = await createActivityData(videoComment.url, videoComment.Account.Actor, videoCommentObject, undefined, audience) | 218 | const data = createActivityData(videoComment.url, videoComment.Account.Actor, videoCommentObject, audience) |
219 | return activityPubResponse(activityPubContextify(data), res) | 219 | return activityPubResponse(activityPubContextify(data), res) |
220 | } | 220 | } |
221 | 221 | ||
diff --git a/server/controllers/activitypub/outbox.ts b/server/controllers/activitypub/outbox.ts index 2793ae267..ae7adcd4c 100644 --- a/server/controllers/activitypub/outbox.ts +++ b/server/controllers/activitypub/outbox.ts | |||
@@ -54,12 +54,12 @@ async function buildActivities (actor: ActorModel, start: number, count: number) | |||
54 | // This is a shared video | 54 | // This is a shared video |
55 | if (video.VideoShares !== undefined && video.VideoShares.length !== 0) { | 55 | if (video.VideoShares !== undefined && video.VideoShares.length !== 0) { |
56 | const videoShare = video.VideoShares[0] | 56 | const videoShare = video.VideoShares[0] |
57 | const announceActivity = await announceActivityData(videoShare.url, actor, video.url, undefined, createActivityAudience) | 57 | const announceActivity = announceActivityData(videoShare.url, actor, video.url, createActivityAudience) |
58 | 58 | ||
59 | activities.push(announceActivity) | 59 | activities.push(announceActivity) |
60 | } else { | 60 | } else { |
61 | const videoObject = video.toActivityPubObject() | 61 | const videoObject = video.toActivityPubObject() |
62 | const createActivity = await createActivityData(video.url, byActor, videoObject, undefined, createActivityAudience) | 62 | const createActivity = createActivityData(video.url, byActor, videoObject, createActivityAudience) |
63 | 63 | ||
64 | activities.push(createActivity) | 64 | activities.push(createActivity) |
65 | } | 65 | } |
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 8dff4b87c..2b40c44d9 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -166,7 +166,7 @@ export { | |||
166 | 166 | ||
167 | async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { | 167 | async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { |
168 | const user = res.locals.oauth.token.User as UserModel | 168 | const user = res.locals.oauth.token.User as UserModel |
169 | const resultList = await VideoModel.listAccountVideosForApi( | 169 | const resultList = await VideoModel.listUserVideosForApi( |
170 | user.Account.id, | 170 | user.Account.id, |
171 | req.query.start as number, | 171 | req.query.start as number, |
172 | req.query.count as number, | 172 | req.query.count as number, |
@@ -174,7 +174,8 @@ async function getUserVideos (req: express.Request, res: express.Response, next: | |||
174 | false // Display my NSFW videos | 174 | false // Display my NSFW videos |
175 | ) | 175 | ) |
176 | 176 | ||
177 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 177 | const additionalAttributes = { waitTranscoding: true, state: true } |
178 | return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes })) | ||
178 | } | 179 | } |
179 | 180 | ||
180 | async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { | 181 | async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
@@ -318,7 +319,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr | |||
318 | } | 319 | } |
319 | 320 | ||
320 | async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { | 321 | async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { |
321 | const avatarPhysicalFile = req.files['avatarfile'][0] | 322 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] |
322 | const user = res.locals.oauth.token.user | 323 | const user = res.locals.oauth.token.user |
323 | const actor = user.Account.Actor | 324 | const actor = user.Account.Actor |
324 | 325 | ||
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) |