diff --git a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js index 2be8e86..dbf3f3a 100644 --- a/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js +++ b/FlowPlugins/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.js @@ -111,6 +111,22 @@ var details = function () { return ({ }, tooltip: 'Specify whether to use hardware encoding if available', }, + { + name: 'hardwareType', + type: 'string', + defaultValue: 'auto', + inputUI: { + type: 'dropdown', + options: [ + 'auto', + 'nvenc', + 'qsv', + 'vaapi', + 'videotoolbox', + ], + }, + tooltip: 'Specify codec of the output file', + }, { name: 'hardwareDecoding', type: 'boolean', @@ -148,7 +164,7 @@ var details = function () { return ({ exports.details = details; // eslint-disable-next-line @typescript-eslint/no-unused-vars var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function () { - var lib, hardwareDecoding, i, stream, targetCodec, ffmpegPreset, ffmpegQuality, forceEncoding, hardwarEncoding, encoderProperties; + var lib, hardwareDecoding, hardwareType, i, stream, targetCodec, ffmpegPreset, ffmpegQuality, forceEncoding, hardwarEncoding, encoderProperties; var _a, _b; return __generator(this, function (_c) { switch (_c.label) { @@ -157,6 +173,7 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign args.inputs = lib.loadDefaultValues(args.inputs, details); hardwareDecoding = args.inputs.hardwareDecoding === true; + hardwareType = String(args.inputs.hardwareType); args.variables.ffmpegCommand.hardwareDecoding = hardwareDecoding; i = 0; _c.label = 1; @@ -175,6 +192,7 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function return [4 /*yield*/, (0, hardwareUtils_1.getEncoder)({ targetCodec: targetCodec, hardwareEncoding: hardwarEncoding, + hardwareType: hardwareType, args: args, })]; case 2: diff --git a/FlowPlugins/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.js b/FlowPlugins/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.js index 8d30474..fbd3e37 100644 --- a/FlowPlugins/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.js +++ b/FlowPlugins/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.js @@ -94,6 +94,7 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function return [4 /*yield*/, (0, hardwareUtils_1.getEncoder)({ targetCodec: 'hevc', hardwareEncoding: true, + hardwareType: 'auto', args: args, })]; case 1: diff --git a/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js b/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js index 6b0efdd..1c987e7 100644 --- a/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js +++ b/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.js @@ -160,9 +160,9 @@ var encoderFilter = function (encoder, targetCodec) { return false; }; var getEncoder = function (_a) { - var targetCodec = _a.targetCodec, hardwareEncoding = _a.hardwareEncoding, args = _a.args; + var targetCodec = _a.targetCodec, hardwareEncoding = _a.hardwareEncoding, hardwareType = _a.hardwareType, args = _a.args; return __awaiter(void 0, void 0, void 0, function () { - var gpuEncoders, filteredGpuEncoders, _i, filteredGpuEncoders_1, gpuEncoder, _b, enabledDevices, res; + var gpuEncoders, filteredGpuEncoders, idx, _i, filteredGpuEncoders_1, gpuEncoder, _b, enabledDevices, res; return __generator(this, function (_c) { switch (_c.label) { case 0: @@ -290,6 +290,13 @@ var getEncoder = function (_a) { }, ]; filteredGpuEncoders = gpuEncoders.filter(function (device) { return encoderFilter(device.encoder, targetCodec); }); + if (hardwareEncoding && hardwareType !== 'auto') { + idx = filteredGpuEncoders.findIndex(function (device) { return device.encoder.includes(hardwareType); }); + if (idx === -1) { + throw new Error("Could not find encoder ".concat(targetCodec, " for hardware ").concat(hardwareType)); + } + return [2 /*return*/, __assign(__assign({}, filteredGpuEncoders[idx]), { isGpu: true, enabledDevices: [] })]; + } args.jobLog(JSON.stringify({ filteredGpuEncoders: filteredGpuEncoders })); _i = 0, filteredGpuEncoders_1 = filteredGpuEncoders; _c.label = 1; @@ -312,7 +319,7 @@ var getEncoder = function (_a) { _i++; return [3 /*break*/, 1]; case 4: - enabledDevices = gpuEncoders.filter(function (device) { return device.enabled === true; }); + enabledDevices = filteredGpuEncoders.filter(function (device) { return device.enabled === true; }); args.jobLog(JSON.stringify({ enabledDevices: enabledDevices })); if (enabledDevices.length > 0) { if (enabledDevices[0].encoder.includes('nvenc')) { diff --git a/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js b/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js index d3c0a49..88def6d 100644 --- a/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js +++ b/FlowPlugins/FlowHelpers/1.0.0/hardwareUtils.test.js @@ -44,6 +44,7 @@ var run = function () { return __awaiter(void 0, void 0, void 0, function () { case 0: return [4 /*yield*/, (0, hardwareUtils_1.getEncoder)({ targetCodec: 'h264', hardwareEncoding: true, + hardwareType: 'auto', // @ts-expect-error type args: { workerType: 'transcodegpu', diff --git a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts index 5cde50f..ddcb981 100644 --- a/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts +++ b/FlowPluginsTs/CommunityFlowPlugins/ffmpegCommand/ffmpegCommandSetVideoEncoder/1.0.0/index.ts @@ -79,6 +79,22 @@ const details = (): IpluginDetails => ({ }, tooltip: 'Specify whether to use hardware encoding if available', }, + { + name: 'hardwareType', + type: 'string', + defaultValue: 'auto', + inputUI: { + type: 'dropdown', + options: [ + 'auto', + 'nvenc', + 'qsv', + 'vaapi', + 'videotoolbox', + ], + }, + tooltip: 'Specify codec of the output file', + }, { name: 'hardwareDecoding', type: 'boolean', @@ -121,6 +137,7 @@ const plugin = async (args: IpluginInputArgs): Promise => { args.inputs = lib.loadDefaultValues(args.inputs, details); const hardwareDecoding = args.inputs.hardwareDecoding === true; + const hardwareType = String(args.inputs.hardwareType); args.variables.ffmpegCommand.hardwareDecoding = hardwareDecoding; for (let i = 0; i < args.variables.ffmpegCommand.streams.length; i += 1) { @@ -143,6 +160,7 @@ const plugin = async (args: IpluginInputArgs): Promise => { const encoderProperties = await getEncoder({ targetCodec, hardwareEncoding: hardwarEncoding, + hardwareType, args, }); diff --git a/FlowPluginsTs/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.ts b/FlowPluginsTs/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.ts index 577937a..e562064 100644 --- a/FlowPluginsTs/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.ts +++ b/FlowPluginsTs/CommunityFlowPlugins/tools/checkNodeHardwareEncoder/1.0.0/index.ts @@ -69,6 +69,7 @@ const plugin = async (args: IpluginInputArgs): Promise => { const encoderProperties = await getEncoder({ targetCodec: 'hevc', hardwareEncoding: true, + hardwareType: 'auto', args, }); diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.test.ts b/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.test.ts index f1cfa1c..5f5a90b 100644 --- a/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.test.ts +++ b/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.test.ts @@ -4,6 +4,7 @@ const run = async () => { const encoderProperties = await getEncoder({ targetCodec: 'h264', hardwareEncoding: true, + hardwareType: 'auto', // @ts-expect-error type args: { workerType: 'transcodegpu', diff --git a/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.ts b/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.ts index c81ad55..36fc525 100644 --- a/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.ts +++ b/FlowPluginsTs/FlowHelpers/1.0.0/hardwareUtils.ts @@ -112,7 +112,7 @@ export const getBestNvencDevice = ({ return nvencDevice; }; -const encoderFilter = (encoder:string, targetCodec:string) => { +const encoderFilter = (encoder: string, targetCodec: string) => { if (targetCodec === 'hevc' && (encoder.includes('hevc') || encoder.includes('h265'))) { return true; } if (targetCodec === 'h264' && encoder.includes('h264')) { @@ -124,21 +124,25 @@ const encoderFilter = (encoder:string, targetCodec:string) => { return false; }; +export interface IgetEncoder { + encoder: string, + inputArgs: string[], + outputArgs: string[], + isGpu: boolean, + enabledDevices: IgpuEncoder[], +} + export const getEncoder = async ({ targetCodec, hardwareEncoding, + hardwareType, args, }: { targetCodec: string, hardwareEncoding: boolean, + hardwareType: string, args: IpluginInputArgs, -}): Promise<{ - encoder: string, - inputArgs: string[], - outputArgs: string[], - isGpu: boolean, - enabledDevices: IgpuEncoder[], -}> => { +}): Promise => { if ( args.workerType && args.workerType.includes('gpu') @@ -268,6 +272,20 @@ export const getEncoder = async ({ const filteredGpuEncoders = gpuEncoders.filter((device) => encoderFilter(device.encoder, targetCodec)); + if (hardwareEncoding && hardwareType !== 'auto') { + const idx = filteredGpuEncoders.findIndex((device) => device.encoder.includes(hardwareType)); + + if (idx === -1) { + throw new Error(`Could not find encoder ${targetCodec} for hardware ${hardwareType}`); + } + + return { + ...filteredGpuEncoders[idx], + isGpu: true, + enabledDevices: [], + }; + } + args.jobLog(JSON.stringify({ filteredGpuEncoders })); // eslint-disable-next-line no-restricted-syntax @@ -281,7 +299,7 @@ export const getEncoder = async ({ }); } - const enabledDevices = gpuEncoders.filter((device) => device.enabled === true); + const enabledDevices = filteredGpuEncoders.filter((device) => device.enabled === true); args.jobLog(JSON.stringify({ enabledDevices }));