简体   繁体   English

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

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

I am trying to use fluent-ffmpeg with my electron app to concatenate multiple audio files together with an image in a video.我正在尝试将 fluent-ffmpeg 与我的电子应用程序一起使用,以将多个音频文件与视频中的图像连接在一起。 So if i have three files:所以如果我有三个文件:

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

I could create output.mp4 which would be 3:30 seconds long, and play each file one after the other in order.我可以创建 3:30 秒长的output.mp4 ,并按顺序播放每个文件。 With front.jpg set as the background image.将 front.jpg 设置为背景图片。

I am trying to create the concatenated audio file first for this video, then I can just render a vid with two inputs;我想先为这个视频创建连接的音频文件,然后我可以用两个输入渲染一个视频; image and the 3:30second long concatenated audio file.图像和 3:30 秒长的串联音频文件。 But I'm having difficulty getting my electron app to wait for the ffmpeg job to run and complete.但是我很难让我的电子应用程序等待 ffmpeg 作业运行和完成。

I know how to do all of these ffmpeg jobs on the command-line, but I've been following this guide for how to package ffmpeg into an electron app that can run on mac/win10/linux environments.我知道如何在命令行上完成所有这些 ffmpeg 作业,但我一直在遵循指南,了解如何将 ffmpeg 打包成可以在 mac/win10/linux 环境中运行的电子应用程序。 I'm developing it on win10 right now.我现在正在win10上开发它。 gur.com/LtykP.png gur.com/LtykP.png

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

that when I click runs the fullAlbum() function that calls combineMp3FilesOrig to run the actual ffmpeg job:当我单击运行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`)
}

When I click my button once, my console.logs show the promise is entered, the command is created, but the function just ends without waiting for a resolve();当我单击我的按钮一次时,我的 console.logs 显示输入了承诺,创建了命令,但该函数不等待 resolve() 就结束了; Waiting a couple minutes doesnt change anything.等待几分钟不会改变任何事情。

在此处输入图片说明

If I press the button again:如果我再次按下按钮:

在此处输入图片说明

A new command gets created, reaches the end of the promise, but this time actually starts, and triggers the previous command to start.一个新的命令被创建,到达 Promise 的末尾,但这次实际开始,并触发前一个命令开始。 Both jobs then run and their files are rendered at the correct length (12:08) and the correct quality (320k)然后运行这两个作业,它们的文件以正确的长度 (12:08) 和正确的质量 (320k) 呈现

Is there something with my promise I need to fix involving async functions and promises in an electron app?我的承诺有什么我需要修复的涉及电子应用程序中的异步功能和承诺吗? I tried editing my ffmpeg command to include我尝试编辑我的 ffmpeg 命令以包含

command.run()

At the end of my promise to ensure it gets triggered;在我保证它被触发的承诺结束时; but that leads to an err in console saying Uncaught (in promise) Error: No output specified because apparently in fluent-ffmpeg command.mergeToFile(outputFilepath);但这导致控制台中的错误说Uncaught (in promise) Error: No output specified因为显然在 fluent-ffmpeg command.mergeToFile(outputFilepath); isnt good enough and I need to include .output(outputFilepath) as well.不够好,我还需要包含.output(outputFilepath) If I change command.run() to command.output(outputFilepath).run() , when i click my button, the ffmpeg job gets triggered and rendered perfectly fine.如果我将command.run()更改为command.output(outputFilepath).run() ,当我单击按钮时,ffmpeg 作业将被触发并呈现得非常好。 EXCEPT THAT THE FILE IS ALWAYS 128kbps除了文件总是 128kbps

So I'm trying to figure out why my included code block, my ffmpeg command doesn't run the first time when its created.所以我试图弄清楚为什么我包含的代码块,我的 ffmpeg 命令在创建时没有第一次运行。

I've played about with this and I'm seeing the same issue with your original code, the file is being output with 128k bitrate.我玩过这个,我发现你的原始代码有同样的问题,文件以 128k 比特率输出。

This code seems to work, though the max bitrate I'm getting is 320k (I presume this is a limitation of the codec).这段代码似乎有效,尽管我得到的最大比特率为 320k(我认为这是编解码器的限制)。

After testing again I think I'm getting the same behaviour as you are, in that the file takes some time to generate.再次测试后,我认为我的行为与您相同,因为该文件需要一些时间来生成。 If I return a Promise from the combineMp3FilesOrig function, then await in the click handler.如果我从 combineMp3FilesOrig 函数返回一个 Promise,则在单击处理程序中等待。 I disable the button until the call is complete, obviously your button id will be different.我禁用按钮直到呼叫完成,显然你的按钮 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