循环更改视频分辨率

时间:2020-07-24 13:29:21

标签: javascript node.js typescript ffmpeg

我正在尝试将视频的分辨率降低到500x500以下。我不想将其精确地更改为500x500,因为那样会破坏视频质量。因此,我试图做的是将一个循环中的分辨率降低75%,并且该循环只会在视频低于500x500时停止。从理论上讲,这并不难,但我似乎无法弄清楚。

var vidwidth = 501; //Create variable and put it to 501
var vidheight = 501; //so that it won't go through the If Statement
fs.copyFile(filepath2, './media/media.mp4', (err: any) => { //Copy given file to directory
    console.log('filepath2 was copied to media.mp4'); //Log confirmation (Not appearing for some reason, but file is copied)
})
while (true) {
    getDimensions('./media/media.mp4').then(function (dimensions: any) { //Get dimensions of copied video
        var vidwidth = parseInt(dimensions.width)   //Parse to Int
        var vidheight = parseInt(dimensions.height) //and put in variables
    })
    ffmpeg('./media/media.mp4')                 //Call ffmpeg function with copied video path
        .output('./media/media.mp4')            //Set output to the same file so we can loop it
        .size('75%')                            //Reduce resolution by 75%
        .on('end', function() {                 //Log confirmation on end
            console.log('Finished processing'); //(Not appearing)
        })                                      //
        .run();                                 //Run function
    if (vidwidth < 500 && vidheight < 500) {    //Check if both the width and height is under 500px
        break;                                  //If true, break the loop and continue
    }
}

这是我正在使用注释的当前代码。基本上会发生什么,因为视频的尺寸不会改变,它会陷入while循环中。经过console.log()行测试。我认为,如果我能以某种方式解决ffmpeg问题,将全部解决。 我将不胜感激:)

PS:这都是用打字稿制作的,然后使用npx tsc

内置到js中

1 个答案:

答案 0 :(得分:2)

问题在于,该循环阻止了回调的调用,因为javascript在一个线程上运行(有关此问题的更多信息,请参见Callback of an asynchronous function is never called)。其中没有被调用的回调之一是vidwidth的回调,其中变量vidheighttrue被更改,因此检查它们是否小于500并最终小于中断循环永远不会copyFile,并且循环将永远运行。无论如何,这都不是处理异步函数的正确方法(请在另一个SO问题How do I return the response from an asynchronous call?中了解有关此信息的详细信息。)

顺便说一下,whilegetDimensions循环对于此类工作完全没有必要,您可以使用ffmpeg来获取视频的尺寸,计算基于它们的所需尺寸并启动ffmpeg任务(copyFile将在不更改输入文件的情况下处理结果文件的创建,因此不需要getDimensions(filepath2).then((dimensions: any) => { // get the dimension of the input file let sizeStr = dimensions.width < dimensions.height ? "?x500" : "500x?"; // if width is smaller than height, reduce the height to 500 and calculate width based on that, same goes for the other way around ffmpeg(filepath2) // the input is the original video, don't worry 'ffmpeg' won't alter the input file .output('./media/media.mp4') // the output file path .size(sizeStr) // use the 'sizeStr' string calculated previously (read more about it here: https://github.com/fluent-ffmpeg/node-fluent-ffmpeg#video-frame-size-options) .on('end', () => console.log('Finished processing')) .run(); }); )。像这样:

{{1}}

就这么简单!