diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-03-10 14:39:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-10 14:39:40 +0100 |
commit | 8319d6ae72d4da6de51bd3d4b5c68040fc8dc3b4 (patch) | |
tree | 1f87041b2cd76222844960602cdc9f52fe206c7b /server/lib | |
parent | edb868655e52f934a71141175cf9dc6cb4753e11 (diff) | |
download | PeerTube-8319d6ae72d4da6de51bd3d4b5c68040fc8dc3b4.tar.gz PeerTube-8319d6ae72d4da6de51bd3d4b5c68040fc8dc3b4.tar.zst PeerTube-8319d6ae72d4da6de51bd3d4b5c68040fc8dc3b4.zip |
Add video file metadata to download modal, via ffprobe (#2411)
* Add video file metadata via ffprobe
* Federate video file metadata
* Add tests for file metadata generation
* Complete tests for videoFile metadata federation
* Lint migration and video-file for metadata
* Objectify metadata from getter in ffmpeg-utils
* Add metadataUrl to all videoFiles
* Simplify metadata API middleware
* Load playlist in videoFile when requesting metadata
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/videos.ts | 16 | ||||
-rw-r--r-- | server/lib/video-transcoding.ts | 8 |
2 files changed, 23 insertions, 1 deletions
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index bce1666be..30de4714c 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -10,7 +10,8 @@ import { | |||
10 | ActivityTagObject, | 10 | ActivityTagObject, |
11 | ActivityUrlObject, | 11 | ActivityUrlObject, |
12 | ActivityVideoUrlObject, | 12 | ActivityVideoUrlObject, |
13 | VideoState | 13 | VideoState, |
14 | ActivityVideoFileMetadataObject | ||
14 | } from '../../../shared/index' | 15 | } from '../../../shared/index' |
15 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' | 16 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' |
16 | import { VideoPrivacy } from '../../../shared/models/videos' | 17 | import { VideoPrivacy } from '../../../shared/models/videos' |
@@ -526,6 +527,10 @@ function isAPHashTagObject (url: any): url is ActivityHashTagObject { | |||
526 | return url && url.type === 'Hashtag' | 527 | return url && url.type === 'Hashtag' |
527 | } | 528 | } |
528 | 529 | ||
530 | function isAPVideoFileMetadataObject (url: any): url is ActivityVideoFileMetadataObject { | ||
531 | return url && url.type === 'Link' && url.mediaType === 'application/json' && url.hasAttribute('rel') && url.rel.includes('metadata') | ||
532 | } | ||
533 | |||
529 | async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAccountLight, waitThumbnail = false) { | 534 | async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAccountLight, waitThumbnail = false) { |
530 | logger.debug('Adding remote video %s.', videoObject.id) | 535 | logger.debug('Adding remote video %s.', videoObject.id) |
531 | 536 | ||
@@ -694,6 +699,14 @@ function videoFileActivityUrlToDBAttributes ( | |||
694 | throw new Error('Cannot parse magnet URI ' + magnet.href) | 699 | throw new Error('Cannot parse magnet URI ' + magnet.href) |
695 | } | 700 | } |
696 | 701 | ||
702 | // Fetch associated metadata url, if any | ||
703 | const metadata = urls.filter(isAPVideoFileMetadataObject) | ||
704 | .find(u => | ||
705 | u.height === fileUrl.height && | ||
706 | u.fps === fileUrl.fps && | ||
707 | u.rel.includes(fileUrl.mediaType) | ||
708 | ) | ||
709 | |||
697 | const mediaType = fileUrl.mediaType | 710 | const mediaType = fileUrl.mediaType |
698 | const attribute = { | 711 | const attribute = { |
699 | extname: MIMETYPES.VIDEO.MIMETYPE_EXT[mediaType], | 712 | extname: MIMETYPES.VIDEO.MIMETYPE_EXT[mediaType], |
@@ -701,6 +714,7 @@ function videoFileActivityUrlToDBAttributes ( | |||
701 | resolution: fileUrl.height, | 714 | resolution: fileUrl.height, |
702 | size: fileUrl.size, | 715 | size: fileUrl.size, |
703 | fps: fileUrl.fps || -1, | 716 | fps: fileUrl.fps || -1, |
717 | metadataUrl: metadata?.href, | ||
704 | 718 | ||
705 | // This is a video file owned by a video or by a streaming playlist | 719 | // This is a video file owned by a video or by a streaming playlist |
706 | videoId: (videoOrPlaylist as MStreamingPlaylist).playlistUrl ? null : videoOrPlaylist.id, | 720 | videoId: (videoOrPlaylist as MStreamingPlaylist).playlistUrl ? null : videoOrPlaylist.id, |
diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index 0d5b3ae39..444b0d954 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts | |||
@@ -2,6 +2,7 @@ import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSER | |||
2 | import { basename, extname as extnameUtil, join } from 'path' | 2 | import { basename, extname as extnameUtil, join } from 'path' |
3 | import { | 3 | import { |
4 | canDoQuickTranscode, | 4 | canDoQuickTranscode, |
5 | getMetadataFromFile, | ||
5 | getDurationFromVideoFile, | 6 | getDurationFromVideoFile, |
6 | getVideoFileFPS, | 7 | getVideoFileFPS, |
7 | transcode, | 8 | transcode, |
@@ -19,6 +20,7 @@ import { CONFIG } from '../initializers/config' | |||
19 | import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoWithAllFiles, MVideoWithFile } from '@server/typings/models' | 20 | import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoWithAllFiles, MVideoWithFile } from '@server/typings/models' |
20 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 21 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
21 | import { generateVideoStreamingPlaylistName, getVideoFilename, getVideoFilePath } from './video-paths' | 22 | import { generateVideoStreamingPlaylistName, getVideoFilename, getVideoFilePath } from './video-paths' |
23 | import { extractVideo } from './videos' | ||
22 | 24 | ||
23 | /** | 25 | /** |
24 | * Optimize the original video file and replace it. The resolution is not changed. | 26 | * Optimize the original video file and replace it. The resolution is not changed. |
@@ -202,6 +204,7 @@ async function generateHlsPlaylist (video: MVideoWithFile, resolution: VideoReso | |||
202 | 204 | ||
203 | newVideoFile.size = stats.size | 205 | newVideoFile.size = stats.size |
204 | newVideoFile.fps = await getVideoFileFPS(videoFilePath) | 206 | newVideoFile.fps = await getVideoFileFPS(videoFilePath) |
207 | newVideoFile.metadata = await getMetadataFromFile(videoFilePath) | ||
205 | 208 | ||
206 | await createTorrentAndSetInfoHash(videoStreamingPlaylist, newVideoFile) | 209 | await createTorrentAndSetInfoHash(videoStreamingPlaylist, newVideoFile) |
207 | 210 | ||
@@ -230,11 +233,16 @@ export { | |||
230 | async function onVideoFileTranscoding (video: MVideoWithFile, videoFile: MVideoFile, transcodingPath: string, outputPath: string) { | 233 | async function onVideoFileTranscoding (video: MVideoWithFile, videoFile: MVideoFile, transcodingPath: string, outputPath: string) { |
231 | const stats = await stat(transcodingPath) | 234 | const stats = await stat(transcodingPath) |
232 | const fps = await getVideoFileFPS(transcodingPath) | 235 | const fps = await getVideoFileFPS(transcodingPath) |
236 | const metadata = await getMetadataFromFile(transcodingPath) | ||
233 | 237 | ||
234 | await move(transcodingPath, outputPath) | 238 | await move(transcodingPath, outputPath) |
235 | 239 | ||
240 | const extractedVideo = extractVideo(video) | ||
241 | |||
236 | videoFile.size = stats.size | 242 | videoFile.size = stats.size |
237 | videoFile.fps = fps | 243 | videoFile.fps = fps |
244 | videoFile.metadata = metadata | ||
245 | videoFile.metadataUrl = extractedVideo.getVideoFileMetadataUrl(videoFile, extractedVideo.getBaseUrls().baseUrlHttp) | ||
238 | 246 | ||
239 | await createTorrentAndSetInfoHash(video, videoFile) | 247 | await createTorrentAndSetInfoHash(video, videoFile) |
240 | 248 | ||