Reputation: 814
This previously working FFMPEG implementation, is no longer successful on my updated Angular 14 Electron 19 project. The getAudiVolume will exit with this error: " An error occurred while analysing: Output format null is not available
"
The component method
downloadYoutube(id: string){
const filename = id+'.mp4';
const filepath = Config.homePath? Config.homePath + '/' + filename : filename;
const stream = ytdl(id).pipe(fs.createWriteStream(filepath));
stream.on('finish', (data) => {
console.log(stream);
this.mediaService.getAudioVolumes(stream).subscribe((d) => {console.log('done', d);});
});
}
The service
import ffmpeg from 'fluent-ffmpeg-corrected';
import * as ffmpegBin from 'ffmpeg-static-electron';
import FS from 'fs';
import {Readable} from 'stream';
import {Config} from "../shared/config";
export interface IVolumes {
meanVolume: string;
maxVolume: string;
}
@Injectable()
export class MediaService {
ffmpegPath = ffmpegBin.path
.replace('app.asar/bin', 'app.asar.unpacked/' + this.binPath)
.replace('node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/renderer/bin', this.binPath)
.replace('browser/javascript', 'mac/x64') // TODO: platform hardcoded!
;
getAudioVolumes(stream: Readable | FS.WriteStream): Observable<IVolumes> {
if (!Config.isElectron){
this.ffmpegPath= 'node_modules/ffmpeg-static-electron/bin/mac/x64/ffmpeg';
}
ffmpeg.setFfmpegPath(this.ffmpegPath);
return new Observable((observer: NextObserver<IVolumes>) => {
const that = this;
ffmpeg(stream)
.withAudioFilter('volumedetect')
.addOption('-f', 'null')
.audioBitrate(128)
.on('progress', function(progress) {
console.log('Normalising Processing: ' + progress.percent + '% done');
})
.on('error', function(err) {
console.log('An error occurred while analysing: ' + err.message);
observer.error('DBs are not accessible');
})
.on('end', (stdout: any, stderr: string) => {
const max = that.parseVolume(stderr, 'max_volume:');
const mean = that.parseVolume(stderr, 'mean_volume:');
console.log('volume analysis done, MeanDB is ', mean);
observer.next({meanVolume: mean, maxVolume: max});
observer.complete();
})
.save('/dev/null');
});
}
"browser": { "fs": false, "child_process": false }
,"browser": { "fs": false}
npm run electron:build
An error occurred while analysing: Output format null is not available
Upvotes: 1
Views: 936
Reputation: 2151
After some debug I realize that the problem was in the utils.js
file on the fluent-ffmpeg
library, when it compares the instanceof Buffer
it always says false
because the Buffer created is a browserified Buffer instead of a strict node Buffer.
Why was this the error?, well, when you try to use the ffmpeg commands the library will check that the format passed (null
in this case) is one of the available ones, it does this by running ffmpeg -formats
wich returns, you guessed it, a Buffer (as any other ffmpeg command), so the validation was always saying that the format you passed was not "valid".
How you can fix this?, you can manually edit the node_modules
by hand, changing the condition -maybe- to str.buffer instanceof ArrayBuffer
. But a cleaner solution might be adding the Buffer as a pollyfil in the webpack config, like this:
npm install buffer -D
angular.webpack.js
in the plugins sectionconst webpack = require('webpack');
...
config.plugins = [
...config.plugins,
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
new NodePolyfillPlugin({
excludeAliases: ["console"]
})
];
Not sure if it works on all cases but with that you can do the build command and check that the error is gone.
Another thing:
WriteStream
to ffmpeg which is odd as it should be a ReadStream
, so maybe you will need to change that line to something like ffmpeg(FS.createReadStream((stream as any).path)
Hope it helps!
Upvotes: 1