繁体   English   中英

电子 fluent-ffmpeg mergeToFile() 命令承诺不会触发

[英]electron fluent-ffmpeg mergeToFile() command promise not triggering

我正在尝试将 fluent-ffmpeg 与我的电子应用程序一起使用,以将多个音频文件与视频中的图像连接在一起。 所以如果我有三个文件:

song1.mp3 1:00 song2.mp3 0:30 song3.mp3 2:00 front.jpg

我可以创建 3:30 秒长的output.mp4 ,并按顺序播放每个文件。 将 front.jpg 设置为背景图片。

我想先为这个视频创建连接的音频文件,然后我可以用两个输入渲染一个视频; 图像和 3:30 秒长的串联音频文件。 但是我很难让我的电子应用程序等待 ffmpeg 作业运行和完成。

我知道如何在命令行上完成所有这些 ffmpeg 作业,但我一直在遵循指南,了解如何将 ffmpeg 打包成可以在 mac/win10/linux 环境中运行的电子应用程序。 我现在正在win10上开发它。 gur.com/LtykP.png

我有一个按钮: <button onClick='fullAlbum("upload-${uploadNumber}")'>FULLALBUM</button>

当我单击运行fullAlbum()函数时,该函数调用combineMp3FilesOrig来运行实际的 ffmpeg 作业:

async function fullAlbum(uploadName) {
    //document.getElementById("buttonId").disabled = true;

    //get table
    var table = $(`#upload_${uploadNumber}_table`).DataTable()
    //get all selected rows
    var selectedRows = table.rows( '.selected' ).data()
    //get outputFile location
    var path = require('path');
    var outputDir = path.dirname(selectedRows[0].audioFilepath)
    //create outputfile
    var timestamp = new Date().getUTCMilliseconds();
    let outputFilepath = `${outputDir}/output-${timestamp}.mp3` 

    
    console.log('fullAlbum() button pressed: ', timestamp)

    await combineMp3FilesOrig(selectedRows, outputFilepath, '320k', timestamp);
    //document.getElementById("buttonId").disabled = false;

    console.log(`fullAlbum() /output-${timestamp}.mp3 should be created now`)
}

function combineMp3FilesOrig(selectedRows, outputFilepath, bitrate, timestamp) {
    console.log(`combineMp3FilesOrig(): ${outputFilepath}`)
    
    //begin get ffmpeg info
    const ffmpeg = require('fluent-ffmpeg');
    //Get the paths to the packaged versions of the binaries we want to use
    const ffmpegPath = require('ffmpeg-static').replace('app.asar','app.asar.unpacked');
    const ffprobePath = require('ffprobe-static').path.replace('app.asar','app.asar.unpacked');
    //tell the ffmpeg package where it can find the needed binaries.
    ffmpeg.setFfmpegPath(ffmpegPath);
    ffmpeg.setFfprobePath(ffprobePath);
    //end set ffmpeg info

    //create ffmpeg command
    console.log(`combineMp3FilesOrig(): create command`)
    const command = ffmpeg();
    //set command inputs
    command.input('C:\\Users\\marti\\Documents\\martinradio\\uploads\\CharlyBoyUTurn\\5. Akula (Club Mix).flac')
    command.input('C:\\Users\\marti\\Documents\\martinradio\\uploads\\CharlyBoyUTurn\\4. Civilian Barracks.flac')

    return new Promise((resolve, reject) => {
        console.log(`combineMp3FilesOrig(): command status logging`)
        command.on('progress', function(progress) {
            console.info(`Processing : ${progress.percent} % done`);
        })
        .on('codecData', function(data) {
            console.log('codecData=',data);
        })
        .on('end', function() {
            console.log('file has been converted succesfully; resolve() promise');
            resolve();
        })
        .on('error', function(err) {
            console.log('an error happened: ' + err.message, ', reject()');
            reject(err);
        })
        console.log(`combineMp3FilesOrig(): add audio bitrate to command`)
        command.audioBitrate(bitrate)
        console.log(`combineMp3FilesOrig(): tell command to merge inputs to single file`)
        command.mergeToFile(outputFilepath);
        console.log(`combineMp3FilesOrig(): end of promise`)
    });
    console.log(`combineMp3FilesOrig(): end of function`)
}

当我单击我的按钮一次时,我的 console.logs 显示输入了承诺,创建了命令,但该函数不等待 resolve() 就结束了; 等待几分钟不会改变任何事情。

在此处输入图片说明

如果我再次按下按钮:

在此处输入图片说明

一个新的命令被创建,到达 Promise 的末尾,但这次实际开始,并触发前一个命令开始。 然后运行这两个作业,它们的文件以正确的长度 (12:08) 和正确的质量 (320k) 呈现

我的承诺有什么我需要修复的涉及电子应用程序中的异步功能和承诺吗? 我尝试编辑我的 ffmpeg 命令以包含

command.run()

在我保证它被触发的承诺结束时; 但这导致控制台中的错误说Uncaught (in promise) Error: No output specified因为显然在 fluent-ffmpeg command.mergeToFile(outputFilepath); 不够好,我还需要包含.output(outputFilepath) 如果我将command.run()更改为command.output(outputFilepath).run() ,当我单击按钮时,ffmpeg 作业将被触发并呈现得非常好。 除了文件总是 128kbps

所以我试图弄清楚为什么我包含的代码块,我的 ffmpeg 命令在创建时没有第一次运行。

我玩过这个,我发现你的原始代码有同样的问题,文件以 128k 比特率输出。

这段代码似乎有效,尽管我得到的最大比特率为 320k(我认为这是编解码器的限制)。

再次测试后,我认为我的行为与您相同,因为该文件需要一些时间来生成。 如果我从 combineMp3FilesOrig 函数返回一个 Promise,则在单击处理程序中等待。 我禁用按钮直到呼叫完成,显然你的按钮 id 会有所不同。

function combineMp3FilesOrig(selectedRows, outputFile, bitrate) {
    const command = ffmpeg();
    var count = selectedRows.length;
    for(var i = 0; i < count; i++){
        command.input(selectedRows[i].audioFilepath)
    }   
    return new Promise((resolve, reject) => { 
        command.on('progress', function(progress) {
            console.info(`Processing : ${progress.percent} % done`);
        })
        .on('codecData', function(data) {
            console.log('codecData=',data);
        })
        .on('end', function() {
            console.log('file has been converted succesfully');
            resolve();
        })
        .on('error', function(err) {
            console.log('an error happened: ' + err.message);
            reject(err);
        }).audioBitrate(bitrate).mergeToFile(outputFile);
    });
}

async function convertFiles() {
    document.getElementById("buttonId").disabled = true;
    await combineMp3FilesOrig(selectedRows, 'output.mp3', '320k');
    document.getElementById("buttonId").disabled = false;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM