From 68d6c633fce2a2080df7a6d1f1a2dfba5ccffd9d Mon Sep 17 00:00:00 2001 From: Chad Hjelle Date: Mon, 25 May 2020 23:20:08 -0500 Subject: [PATCH 1/2] Create Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js --- .../Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js diff --git a/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js b/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js new file mode 100644 index 0000000..9bbdf45 --- /dev/null +++ b/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js @@ -0,0 +1,106 @@ +const vaapiPrefix = ` -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi `; + +module.exports.details = function details() { + return { + id: `Tdarr_Plugin_Mthr_VaapiHEVCTranscode`, + Stage: `Pre-processing`, + Name: `FFMPEG VAAPI HEVC Transcode`, + Type: `Video`, + Operation: `Transcode`, + Description: `Files not in HEVC will be transcoded into HEVC video using ffmpeg with libvaapi. ` + + `Intel QuickSync-enabled CPU required, recommended 8th generation or newer.\n ` + + `Output bitrate will be calculated based on input file size.\n\n`, + Version: `1.0`, + Link: `https://github.com/Mthrboard/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js`, + Tags: `pre-processing,ffmpeg,video only,h265,configurable`, + Inputs: [{ + name: `remuxOnly`, + tooltip: `Specify whether this plugin should only run on files with Remux in their names. ` + + `Valid options are true or false. Defaults to false. ` + + `\\nExample: ` + + `\\ntrue ` + + `\\nExample: ` + + `\\nfalse` + },{ + name: `minBitrate`, + tooltip: `Specify the minimum bitrate at which this plugin will run. Files with a current bitrate ` + + `lower than this cutoff will not be transcoded. Leave blank to disable. ` + + `\\nExample: ` + + `\\n4000` + }] + } +} + +module.exports.plugin = function plugin(file, librarySettings, inputs) { + var response = { + processFile: false, + preset: ``, + handBrakeMode: false, + FFmpegMode: true, + reQueueAfter: false, + infoLog: `` + }; + + var videoProcessingRequired = false; + var ffmpegParameters = ``; + var duration = 0; + var currentBitrate = 0; + var targetBitrate = 0; + var minimumBitrate = 0; + var maximumBitrate = 0; + + if (inputs.remuxOnly.toLowerCase() == `true` && !file.file.toLowerCase().includes(`remux`)) { + response.infoLog += `☒ RemuxOnly is enabled and file is not a remux. Unable to process.\n`; + return response; + } + + if (file.fileMedium !== `video`) { + response.infoLog += `☒ File is not a video. Unable to process.\n`; + return response; + } + + file.ffProbeData.streams.forEach(function(stream) { + if (stream.codec_type == `video`) { + + if (stream.codec_name !== `mjpeg` && stream.codec_name !== `hevc`) { + videoProcessingRequired = true; + + // Formula borrowed from Migz h265 transcode plugins + // Get duration in minutes, then work out currentBitrate using + // Bitrate = file size / (stream duration * .0075) + // Calculations were made based on the formula from this site: + // https://blog.frame.io/2017/03/06/calculate-video-bitrates/ + duration = (file.meta.Duration !== `undefined` ? file.meta.Duration : stream.duration) * 0.0166667; + currentBitrate = ~~(file.file_size / (duration * 0.0075)); + targetBitrate = ~~(currentBitrate / 2); + minimumBitrate = ~~(targetBitrate * 0.7); + maximumBitrate = ~~(targetBitrate * 1.3); + + if (targetBitrate == 0) { + response.infoLog += `☒ Target bitrate could not be calculated. Skipping this plugin.\n`; + return response; + } + + if (inputs.minBitrate !== `` && currentBitrate <= inputs.minBitrate) { + response.infoLog += `☒ Input file's bitrate ${currentBitrate} is lower than the minimum ` + + `bitrate threshold of ${inputs.minBitrate}. Skipping this plugin.\n`; + return response; + } + + response.infoLog += `☒ Video stream ${stream.index} is not HEVC, transcode required.\n `; + ffmpegParameters += ` -c:v:0 hevc_vaapi -b:v ${targetBitrate}k -minrate ${minimumBitrate}k ` + + `-maxrate ${maximumBitrate}k -bufsize 1M -max_muxing_queue_size 1024 `; + } + } + }); + + if (videoProcessingRequired) { + response.infoLog += `☑ Stream analysis complete, processing required.\n `; + response.preset = `${vaapiPrefix},-map 0:v -map 0:a -map 0:s? -map 0:d? -map 0:t? -c copy ${ffmpegParameters} `; + response.container = `${file.container}`; + response.processFile = true; + } else { + response.infoLog += `☑ Stream analysis complete, no processing required.\n`; + } + return response; +} From c251f8bdc2e6878ead441439a70e57b6041f19ea Mon Sep 17 00:00:00 2001 From: Chad Hjelle Date: Wed, 27 May 2020 15:49:51 -0500 Subject: [PATCH 2/2] Update Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js Changed link from my fork to the original repo for a pull request --- Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js b/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js index 9bbdf45..d45a787 100644 --- a/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js +++ b/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js @@ -11,7 +11,7 @@ module.exports.details = function details() { `Intel QuickSync-enabled CPU required, recommended 8th generation or newer.\n ` + `Output bitrate will be calculated based on input file size.\n\n`, Version: `1.0`, - Link: `https://github.com/Mthrboard/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js`, + Link: `https://github.com/HaveAGitGat/Tdarr_Plugins/blob/master/Community/Tdarr_Plugin_Mthr_VaapiHEVCTranscode.js`, Tags: `pre-processing,ffmpeg,video only,h265,configurable`, Inputs: [{ name: `remuxOnly`,