X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Fvideo-transcoding.ts;h=8d786e0ef5ea5ba16e7f79e96557072dbc4af98b;hb=536598cfafab1c5e24e881db1c528489f804fb6b;hp=8e906a1eba60df6f755f047bd165f51c6de8c010;hpb=1600235a2f4e30c5d4e7d4342d1c299845decc60;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index 8e906a1eb..8d786e0ef 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts @@ -1,6 +1,6 @@ import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../initializers/constants' import { join } from 'path' -import { getVideoFileFPS, transcode, canDoQuickTranscode } from '../helpers/ffmpeg-utils' +import { canDoQuickTranscode, getVideoFileFPS, transcode, TranscodeOptions, TranscodeOptionsType } from '../helpers/ffmpeg-utils' import { ensureDir, move, remove, stat } from 'fs-extra' import { logger } from '../helpers/logger' import { VideoResolution } from '../../shared/models/videos' @@ -16,19 +16,22 @@ import { CONFIG } from '../initializers/config' */ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFileModel) { const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR const newExtname = '.mp4' const inputVideoFile = inputVideoFileArg ? inputVideoFileArg : video.getOriginalFile() const videoInputPath = join(videosDirectory, video.getVideoFilename(inputVideoFile)) - const videoTranscodedPath = join(videosDirectory, video.id + '-transcoded' + newExtname) + const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) - const doQuickTranscode = await(canDoQuickTranscode(videoInputPath)) + const transcodeType: TranscodeOptionsType = await canDoQuickTranscode(videoInputPath) + ? 'quick-transcode' + : 'video' - const transcodeOptions = { + const transcodeOptions: TranscodeOptions = { + type: transcodeType as any, // FIXME: typing issue inputPath: videoInputPath, outputPath: videoTranscodedPath, - resolution: inputVideoFile.resolution, - doQuickTranscode + resolution: inputVideoFile.resolution } // Could be very long! @@ -38,18 +41,11 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi await remove(videoInputPath) // Important to do this before getVideoFilename() to take in account the new file extension - inputVideoFile.set('extname', newExtname) + inputVideoFile.extname = newExtname const videoOutputPath = video.getVideoFilePath(inputVideoFile) - await move(videoTranscodedPath, videoOutputPath) - const stats = await stat(videoOutputPath) - const fps = await getVideoFileFPS(videoOutputPath) - - inputVideoFile.set('size', stats.size) - inputVideoFile.set('fps', fps) - await video.createTorrentAndSetInfoHash(inputVideoFile) - await inputVideoFile.save() + await onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) } catch (err) { // Auto destruction... video.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', { err })) @@ -63,6 +59,7 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi */ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoResolution, isPortrait: boolean) { const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR const extname = '.mp4' // We are sure it's x264 in mp4 because optimizeOriginalVideofile was already executed @@ -75,27 +72,49 @@ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoR videoId: video.id }) const videoOutputPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(newVideoFile)) + const videoTranscodedPath = join(transcodeDirectory, video.getVideoFilename(newVideoFile)) const transcodeOptions = { + type: 'video' as 'video', inputPath: videoInputPath, - outputPath: videoOutputPath, + outputPath: videoTranscodedPath, resolution, isPortraitMode: isPortrait } await transcode(transcodeOptions) - const stats = await stat(videoOutputPath) - const fps = await getVideoFileFPS(videoOutputPath) + return onVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath) +} + +async function mergeAudioVideofile (video: VideoModel, resolution: VideoResolution) { + const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR + const newExtname = '.mp4' + + const inputVideoFile = video.getOriginalFile() + + const audioInputPath = join(videosDirectory, video.getVideoFilename(video.getOriginalFile())) + const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) + + const transcodeOptions = { + type: 'merge-audio' as 'merge-audio', + inputPath: video.getPreview().getPath(), + outputPath: videoTranscodedPath, + audioPath: audioInputPath, + resolution + } + + await transcode(transcodeOptions) - newVideoFile.set('size', stats.size) - newVideoFile.set('fps', fps) + await remove(audioInputPath) - await video.createTorrentAndSetInfoHash(newVideoFile) + // Important to do this before getVideoFilename() to take in account the new file extension + inputVideoFile.extname = newExtname - await newVideoFile.save() + const videoOutputPath = video.getVideoFilePath(inputVideoFile) - video.VideoFiles.push(newVideoFile) + return onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) } async function generateHlsPlaylist (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { @@ -106,6 +125,7 @@ async function generateHlsPlaylist (video: VideoModel, resolution: VideoResoluti const outputPath = join(baseHlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution)) const transcodeOptions = { + type: 'hls' as 'hls', inputPath: videoInputPath, outputPath, resolution, @@ -134,8 +154,34 @@ async function generateHlsPlaylist (video: VideoModel, resolution: VideoResoluti }) } +// --------------------------------------------------------------------------- + export { generateHlsPlaylist, optimizeVideofile, - transcodeOriginalVideofile + transcodeOriginalVideofile, + mergeAudioVideofile +} + +// --------------------------------------------------------------------------- + +async function onVideoFileTranscoding (video: VideoModel, videoFile: VideoFileModel, transcodingPath: string, outputPath: string) { + const stats = await stat(transcodingPath) + const fps = await getVideoFileFPS(transcodingPath) + + await move(transcodingPath, outputPath) + + videoFile.set('size', stats.size) + videoFile.set('fps', fps) + + await video.createTorrentAndSetInfoHash(videoFile) + + const updatedVideoFile = await videoFile.save() + + // Add it if this is a new created file + if (video.VideoFiles.some(f => f.id === videoFile.id) === false) { + video.VideoFiles.push(updatedVideoFile) + } + + return video }