Electron FFmpeg 进度处理
Electron FFmpeg progress handling
我有一个 Electron 应用程序(Angular)。
我是 Electron 和所有这些进程间事件处理的新手。
我的问题是我有这个 ipcMain 处理程序(主进程)(我 'Invoke' 来自 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
我添加了评论来解释我想要实现的目标。
在我的 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'
我相信还有一些其他 'elegant' 方法可以在 Main 和 Renderer 进程之间实现这种行为,如果你能告诉我任何方法,我将不胜感激。
否则,你能帮我解决这个错误吗?或与我分享我可以阅读哪些内容来学习如何在 Electron 中使用 'Observables'。
这是我能找到的最好方法。
让我们从我的 ipcMain 开始(查看代码注释):
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 的方式(参见代码的注释):
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 的方式(参见代码注释):
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.
})
有什么意见欢迎留言:)
我有一个 Electron 应用程序(Angular)。
我是 Electron 和所有这些进程间事件处理的新手。
我的问题是我有这个 ipcMain 处理程序(主进程)(我 'Invoke' 来自 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
我添加了评论来解释我想要实现的目标。 在我的 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'
我相信还有一些其他 'elegant' 方法可以在 Main 和 Renderer 进程之间实现这种行为,如果你能告诉我任何方法,我将不胜感激。
否则,你能帮我解决这个错误吗?或与我分享我可以阅读哪些内容来学习如何在 Electron 中使用 'Observables'。
这是我能找到的最好方法。
让我们从我的 ipcMain 开始(查看代码注释):
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 的方式(参见代码的注释):
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 的方式(参见代码注释):
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.
})
有什么意见欢迎留言:)