diff options
author | Chocobozzz <me@florianbigard.com> | 2019-11-26 16:25:36 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-11-26 16:25:36 +0100 |
commit | 52201311e1973a12960466232d4dec861e8258ee (patch) | |
tree | 9203bfec042a3e5d46e67170433b079e31239e8a /server/helpers | |
parent | 08eb3dca8257ad121ad74b180dc19c75466e221d (diff) | |
download | PeerTube-52201311e1973a12960466232d4dec861e8258ee.tar.gz PeerTube-52201311e1973a12960466232d4dec861e8258ee.tar.zst PeerTube-52201311e1973a12960466232d4dec861e8258ee.zip |
Add codec information in HLS playlist
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index ff80991b2..1eea05d1e 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -32,7 +32,7 @@ function computeResolutionsToTranscode (videoFileHeight: number) { | |||
32 | return resolutionsEnabled | 32 | return resolutionsEnabled |
33 | } | 33 | } |
34 | 34 | ||
35 | async function getVideoFileSize (path: string) { | 35 | async function getVideoStreamSize (path: string) { |
36 | const videoStream = await getVideoStreamFromFile(path) | 36 | const videoStream = await getVideoStreamFromFile(path) |
37 | 37 | ||
38 | return videoStream === null | 38 | return videoStream === null |
@@ -40,8 +40,45 @@ async function getVideoFileSize (path: string) { | |||
40 | : { width: videoStream.width, height: videoStream.height } | 40 | : { width: videoStream.width, height: videoStream.height } |
41 | } | 41 | } |
42 | 42 | ||
43 | async function getVideoStreamCodec (path: string) { | ||
44 | const videoStream = await getVideoStreamFromFile(path) | ||
45 | |||
46 | if (!videoStream) return '' | ||
47 | |||
48 | const videoCodec = videoStream.codec_tag_string | ||
49 | |||
50 | const baseProfileMatrix = { | ||
51 | 'High': '6400', | ||
52 | 'Main': '4D40', | ||
53 | 'Baseline': '42E0' | ||
54 | } | ||
55 | |||
56 | let baseProfile = baseProfileMatrix[videoStream.profile] | ||
57 | if (!baseProfile) { | ||
58 | logger.warn('Cannot get video profile codec of %s.', path, { videoStream }) | ||
59 | baseProfile = baseProfileMatrix['High'] // Fallback | ||
60 | } | ||
61 | |||
62 | const level = videoStream.level.toString(16) | ||
63 | |||
64 | return `${videoCodec}.${baseProfile}${level}` | ||
65 | } | ||
66 | |||
67 | async function getAudioStreamCodec (path: string) { | ||
68 | const { audioStream } = await audio.get(path) | ||
69 | |||
70 | if (!audioStream) return '' | ||
71 | |||
72 | const audioCodec = audioStream.codec_name | ||
73 | if (audioCodec.codec_name === 'aac') return 'mp4a.40.2' | ||
74 | |||
75 | logger.warn('Cannot get audio codec of %s.', path, { audioStream }) | ||
76 | |||
77 | return 'mp4a.40.2' // Fallback | ||
78 | } | ||
79 | |||
43 | async function getVideoFileResolution (path: string) { | 80 | async function getVideoFileResolution (path: string) { |
44 | const size = await getVideoFileSize(path) | 81 | const size = await getVideoStreamSize(path) |
45 | 82 | ||
46 | return { | 83 | return { |
47 | videoFileResolution: Math.min(size.height, size.width), | 84 | videoFileResolution: Math.min(size.height, size.width), |
@@ -229,7 +266,9 @@ async function canDoQuickTranscode (path: string): Promise<boolean> { | |||
229 | // --------------------------------------------------------------------------- | 266 | // --------------------------------------------------------------------------- |
230 | 267 | ||
231 | export { | 268 | export { |
232 | getVideoFileSize, | 269 | getVideoStreamCodec, |
270 | getAudioStreamCodec, | ||
271 | getVideoStreamSize, | ||
233 | getVideoFileResolution, | 272 | getVideoFileResolution, |
234 | getDurationFromVideoFile, | 273 | getDurationFromVideoFile, |
235 | generateImageFromVideoFile, | 274 | generateImageFromVideoFile, |
@@ -448,8 +487,8 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut | |||
448 | let localCommand = command | 487 | let localCommand = command |
449 | .format('mp4') | 488 | .format('mp4') |
450 | .videoCodec('libx264') | 489 | .videoCodec('libx264') |
451 | .outputOption('-level 3.1') // 3.1 is the minimal ressource allocation for our highest supported resolution | 490 | .outputOption('-level 3.1') // 3.1 is the minimal resource allocation for our highest supported resolution |
452 | .outputOption('-b_strategy 1') // NOTE: b-strategy 1 - heuristic algorythm, 16 is optimal B-frames for it | 491 | .outputOption('-b_strategy 1') // NOTE: b-strategy 1 - heuristic algorithm, 16 is optimal B-frames for it |
453 | .outputOption('-bf 16') // NOTE: Why 16: https://github.com/Chocobozzz/PeerTube/pull/774. b-strategy 2 -> B-frames<16 | 492 | .outputOption('-bf 16') // NOTE: Why 16: https://github.com/Chocobozzz/PeerTube/pull/774. b-strategy 2 -> B-frames<16 |
454 | .outputOption('-pix_fmt yuv420p') // allows import of source material with incompatible pixel formats (e.g. MJPEG video) | 493 | .outputOption('-pix_fmt yuv420p') // allows import of source material with incompatible pixel formats (e.g. MJPEG video) |
455 | .outputOption('-map_metadata -1') // strip all metadata | 494 | .outputOption('-map_metadata -1') // strip all metadata |