From 84ba82bcf156ae6b36ad7b9c113f21f77de335a6 Mon Sep 17 00:00:00 2001 From: Jeff R Date: Mon, 14 Feb 2022 23:26:04 -0500 Subject: [PATCH] Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js (#253) * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Updated to make use of mediaInfo file object and dropdowns. All external dependencies removed. * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Fixed typo * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js another small tweak * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Fixed id error. * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Removed eslint disable. * Fix lint errors * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Updated to make use of mediaInfo file object and dropdowns. All external dependencies removed. * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Fixed typo * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js another small tweak * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Fixed id error. * Update Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js Removed eslint disable. * Fix lint errors Co-authored-by: HaveAGitGat <43864057+HaveAGitGat@users.noreply.github.com> --- ...lugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js | 498 ++++++++---------- 1 file changed, 218 insertions(+), 280 deletions(-) diff --git a/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js b/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js index ec118d0..5ed216e 100644 --- a/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js +++ b/Community/Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only.js @@ -1,350 +1,288 @@ -/* eslint-disable */ -const details = () => { - return { - id: "Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only", - Stage: 'Pre-processing', - Name: "FFMPEG nvenc_H265 Video Only", - Type: "Video", - Stage: "Pre-processing", - Operation: "Transcode", - Description: `[Contains built-in filter] This plugin transcodes non-h265 files into h265 mkv using NVENC, - reducing resolution to 1920x1080 using nvenc. Audio/subtitles not affected. Bitrate is scaled based on input file quality. - == This plugin depends on mediainfo and mkvpropedit, which must be installed manually! - Check this gist for details: https://gist.github.com/jeff47/4ec428e329a485a102bab0398e6ac4be == `, - Version: "1.00", - Tags: "pre-processing,video only,ffmpeg,nvenc h265,h265", - -Inputs: [ - { - name: "compressionFactor", - type: 'string', - defaultValue:'0.07', - inputUI: { - type: 'text', - }, - tooltip: `== Compression Factor == \\n\\n - How much does HEVC compress raw video? I suggest something between 0.04-0.08. Remember that GPU encoding is not as - efficient as CPU encoding, so resulting file sizes will be larger.\\n\\n - 0.07 will result in a 1080p@29.92fps having a target bitrate of 5.4mbps. This is the default.\\n` +/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ +/* eslint-disable no-restricted-globals */ + +const details = () => ({ + id: 'Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only', + Stage: 'Pre-processing', + Name: 'FFMPEG nvenc_H265 Video Only', + Type: 'Video', + Operation: 'Transcode', + Description: ` +[Contains built-in filter] This plugin transcodes non-h265 files into h265 mkv using NVENC, +reducing resolution to 1920x1080 using nvenc. Audio/subtitles not affected. Bitrate is scaled based on +input file quality.`, + Version: '1.1', + Tags: 'pre-processing,video only,ffmpeg,nvenc h265,h265', + + Inputs: [ + { + name: 'compressionFactor', + type: 'string', + defaultValue: '0.07', + inputUI: { + type: 'text', + }, + tooltip: ` +== Compression Factor == \\n\\n +How much does HEVC compress raw video? I suggest something between 0.04-0.08. Remember that GPU encoding is +faster but not as space efficient as CPU encoding, so resulting file sizes will be larger than if you used CPU +encoding.\\n\\n +0.07 will result in a 1080p@29.92fps having a target bitrate of 5.4mbps. This is the default.\\n`, + }, + { + name: 'maxResolution', + type: 'string', + defaultValue: 'false', + inputUI: { + type: 'dropdown', + options: [ + 'false', + '8KUHD', + '4KUHD', + '1080p', + '720p', + '576p', + '480p', + ], }, - { - name: "maxResolution", - type: 'string', - defaultValue:'false', - inputUI: { - type: 'text', - }, - tooltip: `== Maximum Resolution ==\\n\\n + tooltip: `== Maximum Resolution ==\\n\\n Videos that exceed this resolution will be resized down to this resolution.\\n - Accepted options: 480p, 576p, 720p, 1080p, 4KUHD, 8KUHD. If false, no resizing will occur.\\n` + If false, no resizing will occur.\\n`, + }, + { + name: 'ffmpegPreset', + type: 'string', + defaultValue: 'medium', + inputUI: { + type: 'dropdown', + options: [ + 'veryslow', + 'slower', + 'slow', + 'medium', + 'fast', + 'faster', + 'veryfast', + 'superfast', + 'ultrafast', + ], }, - ], - - - }; -} - - -var MediaInfo = { - videoHeight: "", - videoWidth: "", - videoFPS:"", - videoBR: "", - videoBitDepth: "", - overallBR: "", - JSRProcessed: false, - JSRVersion: 0, - JSRProcessedTime: 0, + tooltip: `== FFmpeg Preset ==\\n\\n + Select the ffmpeg preset.\\n`, + }, + { + name: 'container', + type: 'string', + defaultValue: 'mp4', + inputUI: { + type: 'dropdown', + options: [ + 'mp4', + 'mkv', + ], + }, + tooltip: `== Container ==\\n\\n + mkv or mp4.\\n`, + }, + ], + +}); + +const MediaInfo = { + videoHeight: '', + videoWidth: '', + videoFPS: '', + videoBR: '', + videoBitDepth: '', + overallBR: '', }; // var MediaInfo // Easier for our functions if response has global scope. -var response = { - processFile: false, - preset: "", - container: ".mkv", - handBrakeMode: false, - FFmpegMode: true, - reQueueAfter: true, - infoLog: "", +const response = { + processFile: false, + preset: '', + container: '.mp4', + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: true, + infoLog: '', }; // var response -// Runs mkvpropedit --add-track-statistics on the file. -function updateTrackStats(file) { - response.infoLog += `☑Running mkvpropedit.\n`; - try { - const proc = require("child_process"); - proc.execFile('mkvpropedit', [ '--delete-track-statistics-tags', file._id], (error,stdout,stderr) => { - if (error) throw `mkvpropedit failed: ${error}\n`; - }); - proc.execFile('mkvpropedit', [ '--add-track-statistics-tags', file._id], (error,stdout,stderr) => { - if (error) throw `mkvpropedit failed: ${error}\n`; - }); - } catch (err) { - response.infoLog += `mkvpropedit failed: ${err}.\n`; - throw `mkvpropedit failed: ${err}.\n`; - }; // end try/catch - - return 0; -} // end updateTrackStats() - -// Runs mediainfo on the file, gets JSON output, finds the first video stream and returns the video bit rate and bit depth. +// Finds the first video stream and populates some useful variables function getMediaInfo(file) { - var objMedInfo = ""; - - response.infoLog += `☑Running mediainfo.\n`; - - try { - const proc = require('child_process') - objMedInfo = JSON.parse(proc.execFileSync('mediainfo', [file._id,'--output=JSON'])); - } catch (err) { - response.infoLog += `Mediainfo failed: ${err}.\n`; - throw `Mediainfo failed: ${err}.\n`; - }; // end try/catch - - var videoIdx = -1; - var videoInxFirst = -1; + let videoIdx = -1; - for (var i = 0; i < file.ffProbeData.streams.length; i++) { + for (let i = 0; i < file.ffProbeData.streams.length; i += 1) { + const strstreamType = file.ffProbeData.streams[i].codec_type.toLowerCase(); - strstreamType = file.ffProbeData.streams[i].codec_type.toLowerCase(); + // Looking For Video + // Check if stream is a video. + if (videoIdx === -1 && strstreamType === 'video') { + videoIdx = i; - //Looking For Video - // Check if stream is a video. - if (videoIdx == -1 && strstreamType == "video") { - videoIdx = i; - videoInxFirst = i; - - MediaInfo.videoHeight = Number(file.ffProbeData.streams[i].height); - MediaInfo.videoWidth = Number(file.ffProbeData.streams[i].width); - MediaInfo.videoFPS = Number(objMedInfo.media.track[i + 1].FrameRate); - MediaInfo.videoBR = Number(objMedInfo.media.track[i + 1].BitRate); - MediaInfo.videoBitDepth = Number(objMedInfo.media.track[i + 1].BitDepth); - } + MediaInfo.videoHeight = Number(file.ffProbeData.streams[i].height); + MediaInfo.videoWidth = Number(file.ffProbeData.streams[i].width); + MediaInfo.videoFPS = Number(file.mediaInfo.track[i + 1].FrameRate); + MediaInfo.videoBR = Number(file.mediaInfo.track[i + 1].BitRate); + MediaInfo.videoBitDepth = Number(file.mediaInfo.track[i + 1].BitDepth); + } } - MediaInfo.overallBR = objMedInfo.media.track[0].OverallBitRate; - - try { - MediaInfo.JSRVersion = Number(objMedInfo.media.track[0].extra.JSRVERSION); - } catch (err) { - MediaInfo.JSRVersion = ""; - } - - try { - MediaInfo.JSRProcessed = Boolean(objMedInfo.media.track[0].extra.JSRPROCESSED); - } catch (err) { - MediaInfo.JSRProcessed = ""; - } - - try { - MediaInfo.JSRProcessedTime = Number(objMedInfo.media.track[0].extra.JSRPROCESSEDTIME); - } catch (err) { - MediaInfo.JSRProcessedTime = ""; - } - - return; + MediaInfo.overallBR = file.mediaInfo.track[0].OverallBitRate; } // end getMediaInfo() // eslint-disable-next-line no-unused-vars const plugin = (file, librarySettings, inputs, otherArguments) => { - - const lib = require('../methods/lib')(); + const lib = require('../methods/lib')(); // eslint-disable-next-line no-unused-vars,no-param-reassign inputs = lib.loadDefaultValues(inputs, details); - if (file.fileMedium !== "video") { + if (file.fileMedium !== 'video') { response.processFile = false; - response.infoLog += "☒File is not a video.\n"; + response.infoLog += '☒File is not a video.\n'; return response; } // How much does HVEC compress the raw stream? - var compressionFactor = 0.07; - if ( ! isNaN(Number(inputs.compressionFactor)) ) { - compressionFactor = inputs.compressionFactor; + let compressionFactor = 0.07; + if (!isNaN(Number(inputs.compressionFactor))) { + compressionFactor = inputs.compressionFactor; } else { response.infoLog += `No compression factor selected, defaulting to ${compressionFactor}.\n`; } - - // Do we resize? - var resolutionOrder = [ "480p", "576p", "720p", "1080p", "4KUHD", "8KUHD" ]; + response.container = `.${inputs.container}`; + // Do we resize? + const resolutionOrder = ['480p', '576p', '720p', '1080p', '4KUHD', '8KUHD']; // Define the dimensions and the number of pixels (weightxheight) for each resolution. - var resolutions = { - "480p": { "dimensions": "640x480", "pixelCount": 307200 }, - "576p": { "dimensions": "720x576", "pixelCount": 414720 }, - "720p": { "dimensions": "1280x720", "pixelCount": 921600 }, - "1080p": { "dimensions": "1920x1080", "pixelCount": 2073600 }, - "4KUHD": { "dimensions": "3840x2160", "pixelCount": 8294400 }, - "8KUHD": { "dimensions": "7680x4320", "pixelCount": 33177600 } + const resolutions = { + '480p': { dimensions: '640x480', pixelCount: 307200 }, + '576p': { dimensions: '720x576', pixelCount: 414720 }, + '720p': { dimensions: '1280x720', pixelCount: 921600 }, + '1080p': { dimensions: '1920x1080', pixelCount: 2073600 }, + '4KUHD': { dimensions: '3840x2160', pixelCount: 8294400 }, + '8KUHD': { dimensions: '7680x4320', pixelCount: 33177600 }, }; - - var maxResolution = "8KUHD"; - if ( resolutionOrder.indexOf(inputs.maxResolution) > 0 ) { + let maxResolution = '8KUHD'; + if (resolutionOrder.indexOf(inputs.maxResolution) > 0) { maxResolution = inputs.maxResolution; } else { response.infoLog += `No valid resolution selected, defaulting to ${maxResolution}.\n`; } - - // -------------------------------- METADATA UPDATES -------------------------------- - // If there is no _STATISTICS_WRITING_DATE_UTC-eng field, then we need to run mkvpropedit and - // rerun mediainfo to load the stats. - if (file.ffProbeData.streams[0].tags === undefined || file.ffProbeData.streams[0].tags["_STATISTICS_WRITING_DATE_UTC-eng"] === undefined ) { - response.infoLog += "☑Track statistics are missing.\n"; - updateTrackStats(file); - getMediaInfo(file); - } else { - // mkvpropedit records the time the stats were written. Get it (specify it is in UTC) and add a 10 second buffer. - StatsWritingTime = Date.parse(`${file.ffProbeData.streams[0].tags["_STATISTICS_WRITING_DATE_UTC-eng"]} UTC`) + 10000; - - // If the file's mtime is more than 60 seconds later than StatsWritingTime, then we should rerun mkvpropedit! - if ( file.statSync.mtimeMs > StatsWritingTime ) { - response.infoLog += "☑Track statistics are out of date.\n"; - updateTrackStats(file); - getMediaInfo(file); - } else { - response.infoLog += "☑Track statistics are up to date.\n"; - getMediaInfo(file); - } - } - - if ( isNaN(MediaInfo.videoBR) || isNaN(MediaInfo.videoBitDepth) ) { - response.infoLog += "videoBR or videoBitDepth was NaN, something went wrong with mediainfo.\n"; - updateTrackStats(file); - getMediaInfo(file); - if ( isNaN(MediaInfo.videoBR) || isNaN(MediaInfo.videoBitDepth) ) { - response.infoLog += "videoBR or videoBitDepth still NaN, using default.\n"; - } - } - - // If the overall bitrate is less than the videoBR, then something is wacky. - if ( MediaInfo.videoBR > MediaInfo.overallBR ) { - response.infoLog += `videoBR (${MediaInfo.videoBR} was greater than overallBR (${MediaInfo.overallBR}), - which is impossible. Updating stats.\n`; - updateTrackStats(file); - getMediaInfo(file); - if ( MediaInfo.videoBR > MediaInfo.overallBR ) { - response.infoLog += `videoBR and overallBR still inconsistent, using default.\n`; - } - } - - - if ( file.forceProcessing !== true ) { - if ( MediaInfo.JSRProcessed !== undefined && MediaInfo.JSRProcessed == true) { - response.infoLog += `JSRPROCESSED metadata tag was true. This file was already transcoded by this plugin. Exiting...\n`; - response.processFile = false; - return response; - } -} + getMediaInfo(file); // Set decoding options here switch (file.ffProbeData.streams[0].codec_name) { - case "hevc": - response.preset = `-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v hevc_cuvid `; - break; - case "h264": - response.preset = `-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid `; - break; - case "vc1": - response.preset = `-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vc1_cuvid `; - break; - case "vp8": - response.preset = `-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vp8_cuvid `; - break; - case "vp9": - response.preset = `-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vp9_cuvid `; - break; - } //end switch(codec) - -// Resize high resolution videos to 1080p. -if ( resolutionOrder.indexOf(file.video_resolution) > resolutionOrder.indexOf(maxResolution) ) { - // File resolution exceeds limit, need to resize. - response.preset += ` -resize ${resolutions[maxResolution].dimensions} `; - response.infoLog += `Resizing to ${resolutions[maxResolution].dimensions}.\n`; - response.processFile = true; - var targetBitrate = Math.round((resolutions[maxResolution].pixelCount*MediaInfo.videoFPS)*compressionFactor); -} else { - // No resize needed. - var targetBitrate = Math.round((MediaInfo.videoWidth*MediaInfo.videoHeight*MediaInfo.videoFPS)*compressionFactor); -} + case 'hevc': + response.preset = '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v hevc_cuvid '; + break; + case 'h264': + response.preset = '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid '; + break; + case 'vc1': + response.preset = '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vc1_cuvid '; + break; + case 'vp8': + response.preset = '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vp8_cuvid '; + break; + case 'vp9': + response.preset = '-vsync 0 -hwaccel cuda -hwaccel_output_format cuda -c:v vp9_cuvid '; + break; + default: + break; + } // end switch(codec) + + let targetBitrate; + + // Resize high resolution videos to 1080p. + if (resolutionOrder.indexOf(file.video_resolution) > resolutionOrder.indexOf(maxResolution)) { + // File resolution exceeds limit, need to resize. + response.preset += ` -resize ${resolutions[maxResolution].dimensions} `; + response.infoLog += `Resizing to ${resolutions[maxResolution].dimensions}.\n`; + response.processFile = true; + targetBitrate = Math.round((resolutions[maxResolution].pixelCount * MediaInfo.videoFPS) * compressionFactor); + } else { + // No resize needed. + targetBitrate = Math.round((MediaInfo.videoWidth * MediaInfo.videoHeight * MediaInfo.videoFPS) * compressionFactor); + } -// Calculate bitrates -response.infoLog += `Video details: ${file.ffProbeData.streams[0].codec_name}-${file.video_resolution} + // Calculate bitrates + response.infoLog += `Video details: ${file.ffProbeData.streams[0].codec_name}-${file.video_resolution} ${MediaInfo.videoWidth}x${MediaInfo.videoHeight}x${MediaInfo.videoFPS}@8 bits.\n`; -var maxBitrate = Math.round(targetBitrate*1.3); -var minBitrate = Math.round(targetBitrate*0.7); -if ( isNaN(MediaInfo.videoBR) ) { - var bufsize = targetBitrate; -} else { - var bufsize = Math.round(MediaInfo.videoBR); -} + const maxBitrate = Math.round(targetBitrate * 1.3); + const minBitrate = Math.round(targetBitrate * 0.7); -response.preset += `,-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc -rc:v vbr_hq -preset medium -profile:v main10 -rc-lookahead 32 -spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 `; -response.infoLog += `Video bitrate is ${Math.round(MediaInfo.videoBR/1000)}Kbps, overall is ${Math.round(MediaInfo.overallBR/1000)}Kbps. `; -response.infoLog += `Calculated target is ${Math.round(targetBitrate/1000)}Kbps.\n`; + let bufsize; + if (isNaN(MediaInfo.videoBR)) { + bufsize = targetBitrate; + } else { + bufsize = Math.round(MediaInfo.videoBR); + } + response.preset += ',-map 0:v -map 0:a -map 0:s? -map -:d? -c copy -c:v:0 hevc_nvenc' + + ` -rc:v vbr_hq -preset ${inputs.ffmpegPreset} -profile:v main10 -rc-lookahead 32 ` + + '-spatial_aq:v 1 -aq-strength:v 8 -max_muxing_queue_size 4096 '; + response.infoLog += `Video bitrate is ${Math.round(MediaInfo.videoBR / 1000)}Kbps,` + + ` overall is ${Math.round(MediaInfo.overallBR / 1000)}Kbps. `; + response.infoLog += `Calculated target is ${Math.round(targetBitrate / 1000)}Kbps.\n`; // Adjust target bitrates by codec and bitrate switch (file.ffProbeData.streams[0].codec_name) { - case "hevc": - if ( isNaN(MediaInfo.videoBR) ) { + case 'hevc': + if (isNaN(MediaInfo.videoBR)) { response.processFile = true; targetBitrate = Math.min(MediaInfo.overallBR, targetBitrate); - response.preset +=` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; + response.preset += ` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; response.infoLog += `☒HEVC Bitrate for ${file.video_resolution} could not be determined, - using sensible default of ${Math.round(targetBitrate/1000)}Kbps.\n`; - } else if ( (MediaInfo.videoBR > targetBitrate*1.5) || file.forceProcessing === true ) { + using sensible default of ${Math.round(targetBitrate / 1000)}Kbps.\n`; + } else if ((MediaInfo.videoBR > targetBitrate * 1.5) || file.forceProcessing === true) { response.processFile = true; - response.preset +=` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; - response.infoLog += `☒HEVC Bitrate for ${file.video_resolution} exceeds ${Math.round(targetBitrate*1.5/1000)}Kbps, - downsampling to ${Math.round(targetBitrate/1000)}Kbps.\n`; + response.preset += ` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; + response.infoLog += `☒HEVC Bitrate for ${file.video_resolution}` + + ` exceeds ${Math.round((targetBitrate * 1.5) / 1000)}Kbps,` + + ` downsampling to ${Math.round(targetBitrate / 1000)}Kbps.\n`; } else { - response.infoLog += `☑HEVC Bitrate is within limits.\n` + response.infoLog += '☑HEVC Bitrate is within limits.\n'; } - break; // case "hevc" - case "h264": + break; // case "hevc" + case 'h264': response.processFile = true; + let new_bitrate; // We want the new bitrate to be 70% the h264 bitrate, but not higher than our target. - if ( isNaN(MediaInfo.videoBR) ) { - new_bitrate = Math.min(MediaInfo.overallBR*0.7,targetBitrate); + if (isNaN(MediaInfo.videoBR)) { + new_bitrate = Math.min(MediaInfo.overallBR * 0.7, targetBitrate); } else { - new_bitrate = Math.min(Math.round(MediaInfo.videoBR*0.7),targetBitrate); - // New bitrate should not be lower than our 60% of our target. - new_bitrate = Math.max( new_bitrate, Math.min(MediaInfo.videoBR, targetBitrate*0.6) ); + new_bitrate = Math.min(Math.round(MediaInfo.videoBR * 0.7), targetBitrate); + // New bitrate should not be lower than our 60% of our target. + new_bitrate = Math.max(new_bitrate, Math.min(MediaInfo.videoBR, targetBitrate * 0.6)); } - response.preset +=` -b:v ${new_bitrate} -maxrate ${Math.round(new_bitrate*1.3)} -minrate ${Math.round(new_bitrate*0.7)} -bufsize ${bufsize}`; - response.infoLog += `☒H264 Resolution is ${file.video_resolution}, bitrate was ${Math.round(MediaInfo.videoBR/1000)}Kbps. - HEVC target bitrate will be ${Math.round(new_bitrate/1000)}Kbps.\n`; - break; // case "h264" + response.preset += ` -b:v ${new_bitrate} -maxrate ${Math.round(new_bitrate * 1.3)}` + + `-minrate ${Math.round(new_bitrate * 0.7)} -bufsize ${bufsize}`; + response.infoLog += `☒H264 Resolution is ${file.video_resolution},` + + ` bitrate was ${Math.round(MediaInfo.videoBR / 1000)}Kbps.` + + ` HEVC target bitrate will be ${Math.round(new_bitrate / 1000)}Kbps.\n`; + break; // case "h264" default: response.processFile = true; - response.preset +=` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; - response.infoLog += `☒${file.ffProbeData.streams[0].codec_name} resolution is ${file.video_resolution}, - bitrate was ${Math.round(MediaInfo.videoBR/1000)}Kbps. HEVC target bitrate will be ${Math.round(targetBitrate/1000)}Kbps.\n`; - break; // default + response.preset += ` -b:v ${targetBitrate} -maxrate ${maxBitrate} -minrate ${minBitrate} -bufsize ${bufsize} `; + response.infoLog += `☒${file.ffProbeData.streams[0].codec_name} resolution is ${file.video_resolution},` + + ` bitrate was ${Math.round(MediaInfo.videoBR / 1000)}Kbps.` + + ` HEVC target bitrate will be ${Math.round(targetBitrate / 1000)}Kbps.\n`; + break; // default } // switch (file.ffProbeData.streams[0].codec_name) - - - if (response.processFile == true) { - response.preset += ` -map_metadata:g -1 -metadata JSRVERSION=1 -metadata JSRPROCESSED=true -metadata JSRPROCESSEDTIME=${Date.now()} `; + if (response.processFile === true) { + response.preset += ' -map_metadata:g -1'; response.FFmpegMode = true; - response.infoLog += `☒Transcoding to HEVC.`; - } else { - if (file.container != "mkv") { - response_preset = ',-c copy -map 0'; - response.processFile = true; - response.infoLog += `☒Remuxing to mkv.`; - } + response.infoLog += '☒Transcoding to HEVC.'; } - - return response; -} // end plugin() + return response; +}; // end plugin() module.exports.details = details; module.exports.plugin = plugin;