Electron FFmpeg 进度处理

Posted

技术标签:

【中文标题】Electron FFmpeg 进度处理【英文标题】:Electron FFmpeg progress handling 【发布时间】:2022-01-23 21:40:35 【问题描述】:

我有一个 Electron 应用程序(使用 Angular)。

我是 Electron 和所有这些进程间事件处理的新手。

我的问题是我有这个 ipcMain 处理程序(主进程)(我从 Angular 服务“调用”):

ipcMain.handle('video-audio-merge', (event, filename) => 
    return new Promise((resolve) => 
        new FFmpeg(filename+'.mp4').addInput(filename+'.mp3')
        .on('progress', progress => resolve(progress.percent)) // The problem is in this line
        .save('merged_'+filename+'.mp4')
        .on('end', () => resolve(100));
    );
)

我想要实现的是跟踪视频和音频合并的进度(可能需要几秒钟到几分钟)。但是这里的问题是,一旦 Promise 被解决,它就不会发送下一个进度值(我最终会收到 3%,然后即使 'merge' 仍在进行中,也不会收到任何其他值)。

然后我尝试了以下(主进程)(我无法编译):

const Observable = require('rxjs');
...
ipcMain.handle('video-audio-merge', (event, filename) => 
    return new Promise((resolve) => 
        resolve( // Will resolve to an Observable that will be able to provide progress values
            new Observable<number>(subscriber => 
                new FFmpeg(filename+'.mp4').addInput(filename+'.mp3')
                .on('progress', progress => subscriber.next(progress.percent)) // Streaming progress values
                .save('merged_'+filename+'.mp4')
                .on('end', () => subscriber.completed());
            ) // End Observable
        ); // End Resolve
    ); // End Promise
) // End ipcMain.handle

我添加了 cmets 来解释我想要实现的目标。 在我的 Angular 服务中,我按如下方式调用此处理程序:

const electron = (<any>window).require('electron');
import  Observable  from 'rxjs';
...
electron.ipcRenderer.invoke('video-audio-merge', filename).then((subscriber: Observable<number>) =>  // This should resolve to my Observable
    subscriber.subscribe((progress: number) =>  // I subscribe to the Observable to get progress values
        console.log(progress); // here I should be using my progress value
    );
);

编译时出现以下错误:

A javascript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'rxjs-compat'

我相信在 Main 和 Renderer 进程之间还有其他一些“优雅”的方式来实现这种行为,如果你能引导我了解任何我将不胜感激的方法。

否则,你能帮我解决这个错误吗?或者与我分享我可以阅读哪些内容来学习如何在 Electron 中使用“Observables”。

【问题讨论】:

【参考方案1】:

这是我能找到的最好方法。

让我们从我的 ipcMain 开始(参见代码的 cmets):

ipcMain.on('video-audio-merge', (event, filename) => 
    new FFmpeg(filename+'.mp4').addInput(filename+'.mp3')
        .on('progress', (progress) => 
            event.reply(filename,  progress: progress.percent ); /* 'event.reply' as its name indicates sends a response through channel <filename>, 
                                                                       which I use on the renderer process side to listen to progress value */
        )
        .save('./merged_'+filename+'.mp4');
) // end ipcMain.on

这就是我在 Angular 中构建 Observable 的方式(参见代码的 cmets):

VideoAudioMerge(filename: string) 
    return new Observable<any>(observer => 
        electron.ipcRenderer.on(filename, (event: any, data: any) =>  /* Creates an ipcRenderer listener on channel named <filename>, 
                                                                          so when multiple files are progressing at the same time each will send it's 
                                                                          progress value on a different channel */
            observer.next(data.progress);
            if(data.progress >= 100)  observer.complete();
        );
        electron.ipcRenderer.send('video-audio-merge', filename);
    );
 // end VideoAudioMerge

最后这就是我使用 Observable 的方式(参见代码的 cmets):

this.VideoAudioMerge(filename).subscribe( progress => 
    this.progress = progress
,
(error) => /*Error handling */,
() => 
    electron.ipcRenderer.removeAllListeners(filename); // At the end of video merge remove each <filename> listener.
)

如果您有任何 cmets,请随时 :)

【讨论】:

以上是关于Electron FFmpeg 进度处理的主要内容,如果未能解决你的问题,请参考以下文章

???electron???????????????????????????

Electron 构建桌面应用程序开发资料整理

electron框架优缺点

电子 - 如何在电子应用程序中使用 ffmpeg

如何在 Election 中的 Main.js 和 html.js 之间发送和获取数据

与 Electron 相比,Chrome 应用程序的优缺点是啥?