Skip to content

Instantly share code, notes, and snippets.

@njoyard
Created April 25, 2014 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save njoyard/11304191 to your computer and use it in GitHub Desktop.
Save njoyard/11304191 to your computer and use it in GitHub Desktop.
fluent-ffmpeg size/padding attempt 1
function getScalePadFilters(width, height, aspect, color) {
/*
let a be the input aspect ratio, A be the requested aspect ratio
if a > A, padding is done on top and bottom
if a < A, padding is done on left and right
*/
return [
/*
In both cases, we first have to scale the input to match the requested size
scale=
ow=if(gt(a, A), width, height*a),
oh=if(lt(a, A), height, width/a)
*/
'scale=' +
'ow=if(gt(a,' + aspect + '),' + width + ',' + height + '*a),' +
'oh=if(lt(a,' + aspect + '),' + height + ',' + width + '/a)',
/*
Then we pad the scaled input to match the target size
pad=
w=width,
h=height,
x=if(gt(a, A), 0, (width - height*a)/2),
y=if(lt(a, A), 0, (height - width/a)/2)
(here we can replace height*a by iw and width/a by ih as they are the size
of the frames the scaling filter outputs).
*/
'pad=' +
'w=' + width + ',' +
'h=' + height + ',' +
'x=if(gt(a,' + aspect + '),0,(' + width + '-iw*a)/2),' +
'y=if(lt(a,' + aspect + '),0,(' + height + '-ih/a)/2),' +
'color=' + color
];
}
FfmpegCommand.prototype.getSizeFilters = function() {
if (!this.options.video.size) {
// No size requested
if (this.options.video.aspect) {
this.options.logger.warn('Ignoring aspect ratio as withSize() was not called');
}
if (this.options._applyAutopad) {
this.options.logger.warn('Ignoring auto padding as withSize() was not called');
}
// TODO pixel aspect
// Keep original size
return [];
}
var fixedSize = this.options.video.size.match(/([0-9]+)x([0-9]+)/);
var fixedWidth = this.options.video.size.match(/([0-9]+)x\?/);
var fixedHeight = this.options.video.size.match(/\?x([0-9]+)/);
var percentRatio = this.options.video.size.match(/\b([0-9]{1,3})%/);
var width, height, aspect;
if (percentRatio) {
if (this.options.video.aspect) {
this.options.logger.warn('Ignoring aspect ratio as withSize() was called with a percent ratio');
}
if (this.options._applyAutopad) {
this.options.logger.warn('Ignoring auto padding as withSize() was called with a percent ratio');
}
// TODO pixel aspect
return ['scale=iw*' + percentRatio[1] + '/100:ih*' + percentRatio[1] + '/100'];
} else if (fixedSize) {
width = fixedSize[1];
height = fixedSize[2];
aspect = width / height;
if (this.options.video.aspect) {
this.options.logger.warn('Ignoring aspect ratio as withSize() was called with a fixed size');
}
if (this.options._applyAutopad) {
return getScalePadFilters(width, height, aspect, this.options.video.padcolor);
}
// TODO pixel aspect
// No autopad requested, rescale to target size
return ['scale=' + width + ':' + height];
} else if (fixedWidth || fixedHeight) {
if (this.options.video.aspect) {
// Specified aspect ratio
aspect = Number(this.options.video.aspect);
if (isNaN(aspect)) {
throw new Error('Invalid aspect ratio: ' + this.options.video.aspect);
}
width = fixedWidth ? fixedWidth[1] : Math.round(Number(fixedHeight[1]) * aspect);
height = fixedHeight ? fixedHeight[1] : Math.round(Number(fixedWidth[1]) / aspect);
if (this.options._applyAutopad) {
return getScalePadFilters(width, height, aspect, this.options.video.padcolor);
}
// TODO pixel aspect
// No autopad requested, rescale to target size
return ['scale=' + width + ':' + height];
} else {
// Keep input aspect ratio
if (this.options._applyAutopad) {
this.options.logger.warn('Ignoring auto padding as input aspect is kept');
}
// TODO pixel aspect
if (fixedWidth) {
return ['scale=' + fixedWidth[1] + ':-1'];
} else {
return ['scale=-1:' + fixedHeight[1]];
}
}
} else {
throw new Error('Invalid size specified: ' + this.options.video.size);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment