Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Prevent numbers in scientific notation from being passed to ffmpeg #1131

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/options/inputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ module.exports = function(proto) {
throw new Error('No input specified');
}

if (typeof seek === 'number') {
seek = utils.formatNumberForCall(seek);
}

this._currentInput.options('-ss', seek);

return this;
Expand Down
6 changes: 6 additions & 0 deletions lib/options/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module.exports = function(proto) {
*/
proto.seekOutput =
proto.seek = function(seek) {
if (typeof seek === 'number') {
seek = utils.formatNumberForCall(seek);
}
this._currentOutput.options('-ss', seek);
return this;
};
Expand All @@ -106,6 +109,9 @@ module.exports = function(proto) {
proto.withDuration =
proto.setDuration =
proto.duration = function(duration) {
if (typeof duration === 'number') {
duration = utils.formatNumberForCall(duration);
}
this._currentOutput.options('-t', duration);
return this;
};
Expand Down
18 changes: 17 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ function parseProgressLine(line) {
return progress;
}

const numberFormatter = new Intl.NumberFormat('en-US', {
useGrouping: false,
// 10 digits to provide ample precision for high samplerate audio
maximumFractionDigits: 10,
});

var utils = module.exports = {
isWindows: isWindows,
Expand Down Expand Up @@ -374,7 +379,7 @@ var utils = module.exports = {
* - close() : prevents further append() calls and does a last call to callbacks
* - callback(cb) : calls cb for each line (incl. those already in the ring)
*
* @param {Numebr} maxLines maximum number of lines to store (<= 0 for unlimited)
* @param {Number} maxLines maximum number of lines to store (<= 0 for unlimited)
*/
linesRing: function(maxLines) {
var cbs = [];
Expand Down Expand Up @@ -451,5 +456,16 @@ var utils = module.exports = {
closed = true;
}
};
},

/**
* Convert number to decimal notation. Javascript floating point numbers are
* sometimes represented in scientific notation, and ffmpeg cannot handle
* that format.
* @param {Number} num number to format for call to ffmpeg
* @returns {String} string representation of number in decimal notation
*/
formatNumberForCall: function (num) {
return numberFormatter.format(num);
}
};
48 changes: 46 additions & 2 deletions test/args.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ describe('Command', function() {

if(args.indexOf('-loop') != -1 || args.indexOf('-loop_output') != -1){
args.indexOf('-t').should.above(-1);
args.indexOf(120).should.above(-1);
args.indexOf('120').should.above(-1);
done();
}
else{
Expand Down Expand Up @@ -607,6 +607,28 @@ describe('Command', function() {
done();
});
});

it('should apply start time converted from scientific notation (0)', function(done) {
new Ffmpeg({ source: this.testfile, logger: testhelper.logger })
.setStartTime(1e-15)
._test_getArgs(function(args, err) {
testhelper.logArgError(err);
assert.ok(!err);
args.indexOf('-ss').should.equal(args.indexOf('0') - 1);
done();
});
});

it('should apply start time converted from scientific notation (nonzero)', function(done) {
new Ffmpeg({ source: this.testfile, logger: testhelper.logger })
.setStartTime(1.234567e-9)
._test_getArgs(function(args, err) {
testhelper.logArgError(err);
assert.ok(!err);
args.indexOf('-ss').should.equal(args.indexOf('0.0000000012') - 1);
done();
});
});
});

describe('setDuration', function() {
Expand All @@ -618,7 +640,29 @@ describe('Command', function() {
assert.ok(!err);

args.indexOf('-t').should.above(-1);
args.indexOf(10).should.above(-1);
args.indexOf('10').should.above(-1);
done();
});
});

it('should apply duration converted from scientific notation (0)', function(done) {
new Ffmpeg({ source: this.testfile, logger: testhelper.logger })
.setDuration(1e-15)
._test_getArgs(function(args, err) {
testhelper.logArgError(err);
assert.ok(!err);
args.indexOf('-t').should.equal(args.indexOf('0') - 1);
done();
});
});

it('should apply duration converted from scientific notation (nonzero)', function(done) {
new Ffmpeg({ source: this.testfile, logger: testhelper.logger })
.setDuration(1.234567e-9)
._test_getArgs(function(args, err) {
testhelper.logArgError(err);
assert.ok(!err);
args.indexOf('-t').should.equal(args.indexOf('0.0000000012') - 1);
done();
});
});
Expand Down
22 changes: 22 additions & 0 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,26 @@ describe('Utilities', function() {
ring.get().should.equal('foo\nbar\nbazfoo\nbar');
});
});

describe('Format number for call', function() {
it('formats decimal notation number as string', function() {
utils.formatNumberForCall(0).should.equal('0');
utils.formatNumberForCall(1).should.equal('1');
utils.formatNumberForCall(1.5).should.equal('1.5');
utils.formatNumberForCall(-1.5).should.equal('-1.5');
});

it('truncates numbers to 10 decimal places', function() {
utils.formatNumberForCall(234222.2333333333334).should.equal('234222.2333333333');
utils.formatNumberForCall(234222.2337777777774).should.equal('234222.2337777778');
})

it('formats scientific notation number as decimal', function() {
utils.formatNumberForCall(1e2).should.equal('100');
utils.formatNumberForCall(1e-5).should.equal('0.00001');
utils.formatNumberForCall(-1e-5).should.equal('-0.00001');
utils.formatNumberForCall(5.684341886080802e-14).should.equal('0');
utils.formatNumberForCall(-5.684341886080802e-14).should.equal('-0');
});
})
});