【问题标题】:Change video resolution in loop循环更改视频分辨率
【发布时间】:2020-11-14 09:06:01
【问题描述】:

我正在尝试将视频的分辨率降低到 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
    }
}

这是我与 cmets 一起使用的当前代码。基本上发生的情况是它卡在 while 循环中,因为视频的尺寸不会改变。使用console.log() 行测试。我认为,如果我能以某种方式解决 ffmpeg 问题,一切都会得到解决。 我会很感激任何帮助:)

PS:这都是用typescript制作的,然后用npx tsc构建成js

【问题讨论】:

  • copyFile 是异步的,因此在复制完成之前到达循环,getDimensions(...).then 也是如此。您不能像这样一个接一个地进行异步调用并期望它们按顺序运行。这基本上是 stackoverflow.com/questions/14220321/… 的副本
  • 顺便说一句,你不需要循环也不需要copyFile 这种东西,ffmpeg 可以自己处理,我会在稍后发布答案
  • 我查看了您链接的线程,它清除了一些东西。不知道 node.js 运行单线程。另外,感谢您尽快发布答案:) 我很感激
  • 一个问题,输入视频是正方形的吗(相同的高度和宽度)?如果不是你想要的输出是什么:1. 视频被拉伸以填充500x5002. 长宽比保持不变,视频被填充较小边缘上的黑色条纹使其成为500x5003。 长宽比保持不变,视频不一定是500x500(例如可以是500x400 或@987654333 @)?
  • 我希望视频具有相同的纵横比,但小于 500x500。例如,它是否为 240x360 并不重要,只要它保持相同的纵横比并且低于 500x500。 (基本上你的最后一个选择;))

标签: javascript node.js typescript ffmpeg


【解决方案1】:

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

顺便说一句,copyFilewhile 循环对于这种工作根本不是必需的,您可以使用 getDimensions 获取视频的尺寸,根据它们计算所需的尺寸并启动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();       
});

就这么简单!

【讨论】:

    猜你喜欢
    • 2016-03-27
    • 2014-05-15
    • 1970-01-01
    • 2016-02-05
    • 2012-07-01
    • 1970-01-01
    • 2021-03-02
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多