diff --git a/lib/audioconv.js b/lib/audioconv.js index f17467c..1b771f1 100644 --- a/lib/audioconv.js +++ b/lib/audioconv.js @@ -39,7 +39,8 @@ const { createDirIfNotExistSync, createLogFile, dropNullAndUndefined, - isNullOrUndefined + isNullOrUndefined, + isObject } = require('./utils'); /** @@ -193,7 +194,9 @@ function splitOptions(options) { * @return {module:audioconv~ResolvedConvertAudioOptions} The resolved options. * @since 1.0.0 */ -function resolveOptions(options, useDefault=true) { +function resolveOptions(options, useDefault=false) { + if (!isObject(options)) return defaultOptions; + return { inputOptions: ( Array.isArray(options?.inputOptions) @@ -457,12 +460,18 @@ async function convertAudio(inFile, options = defaultOptions) { || (Array.isArray(options.outputOptions) && options.outputOptions.length === 0) ) ) { - ffmpegChain - .audioBitrate(options.bitrate) - .audioCodec(options.codec) - .audioChannels(options.channels) - .audioFrequency(options.frequency) - .outputFormat(options.format); + // Add each option only if present and specified + // By using this logic, now user can convert an audio file with only specifying + // the output audio format + if (options.bitrate) ffmpegChain.audioBitrate(options.bitrate); + if (options.codec) ffmpegChain.audioCodec(options.codec); + if (options.channels) ffmpegChain.audioChannels(options.channels); + if (options.frequency) ffmpegChain.audioFrequency(options.frequency); + + // Mandatory for output format + // Note: Specifying the same output format as input may copy the input file + // with the same codec and format + ffmpegChain.outputFormat(options.format); } else { if (Array.isArray(options.inputOptions)) { ffmpegChain.inputOptions(options.inputOptions); diff --git a/test/unittest/audioconv.spec.mjs b/test/unittest/audioconv.spec.mjs index 5ab8624..fd53604 100644 --- a/test/unittest/audioconv.spec.mjs +++ b/test/unittest/audioconv.spec.mjs @@ -12,7 +12,7 @@ describe('module:audioconv', function () { ], resolveOptions: [ 'should return default options if given argument is nullable value', - 'should return nullable options if given argument is nullable value', + 'should return default options if given argument is not an object', 'should resolve the given configuration options' ] }; @@ -92,7 +92,7 @@ describe('module:audioconv', function () { }); it(testMessages.resolveOptions[0], function () { - const actualOptions = [null, undefined, {}].map((val) => { + const actualOptions = [null, undefined, false].map((val) => { return audioconv.resolveOptions(val , true); }); @@ -110,15 +110,16 @@ describe('module:audioconv', function () { }); it(testMessages.resolveOptions[1], function () { - const actualOptions = [null, undefined, {}].map((val) => { + const actualOptions = ['&', /y/, 16n].map((val) => { return audioconv.resolveOptions(val , false); }); actualOptions.forEach((actual) => { assert.notStrictEqual(actual, null); // Non-nullable assert.notStrictEqual(typeof actual, 'undefined'); - assert.notDeepStrictEqual(actual, expectedOptions[0]); - assert.deepStrictEqual(actual, expectedOptions[2]); + assert.deepStrictEqual(actual, expectedOptions[0]); + assert.notDeepStrictEqual(actual, expectedOptions[1]); + assert.notDeepStrictEqual(actual, expectedOptions[2]); }); [...actualOptions].reverse().forEach((actual1) => { actualOptions.forEach((actual2) => {