Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

108
Visualizações
Electron FFmpeg progress handling

I have an Electron app (with Angular).

I am new to Electron and all this inter-process event handling.

My problem is that I have this ipcMain handler(main process) (that I 'Invoke' from an Angular service) :

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));
    });
})

What I am trying to achieve is to follow the progress of a merge of a video and an audio (which may take several seconds to several minutes). But the problem here is that once the Promise is resolved, it does not send the next progress values (I end up receiving 3% and then never receive any other value even if 'merge' is still in progress).

Then I tried the following (main process) (which I am not able to compile):

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

I added comments to explain what I am trying to achieve. And in my Angular service I am invoking this handler as follows :

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
    });
});

On compilation I get the following error :

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

I am convinced that there is some other 'elegant' way to achieve this behavior between Main and Renderer processes, if you can lead me to any I would be thankful.

Otherwise, can you please help me out to solve this error ? or share with me what can I read to learn how to use 'Observables' in Electron.

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

This is the best way I could find.

Let's start with my ipcMain (see code's comments):

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

This is how I construct my Observable in Angular (see code's comments):

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

And finally this is how I use the Observable (see code's comments):

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.
})

Please feel free if you have any comments :)

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda