私は、electronアプリでfluent-ffmpegを使用して、複数のオーディオファイルをビデオ内の画像と連結しようとしています。したがって、3つのファイルがある場合:
song1.mp3 1:00 song2.mp3 0:30 song3.mp3 2:00 front.jpg
output.mp4
3:30秒の長さのファイルを作成し、各ファイルを順番に再生することができました。front.jpgを背景画像として設定します。
このビデオの連結オーディオファイルを最初に作成しようとしています。次に、2つの入力でビデオをレンダリングできます。画像と3:30秒の長さの連結オーディオファイル。しかし、電子アプリでffmpegジョブが実行されて完了するのを待つのに苦労しています。
コマンドラインでこれらすべてのffmpegジョブを実行する方法を知っていますが、mac / win10 / linux環境で実行できるelectronアプリにffmpegをパッケージ化する方法についてはこのガイドに従っています。私は今win10でそれを開発しています。gur.com/LtykP.png
私はボタンを持っています: <button onClick='fullAlbum("upload-${uploadNumber}")'>FULLALBUM</button>
クリックすると、実際のffmpegジョブを実行するためにfullAlbum()
呼び出す関数がcombineMp3FilesOrig
実行されます。
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`)
}
ボタンを1回クリックすると、console.logsにpromiseが入力され、コマンドが作成されたことが示されますが、関数はresolve()を待たずに終了します。数分待っても何も変わりません。
もう一度ボタンを押すと:
新しいコマンドが作成され、promiseの終わりに到達しますが、今回は実際に開始し、前のコマンドをトリガーして開始します。次に、両方のジョブが実行され、それらのファイルが正しい長さ(12:08)および正しい品質(320k)でレンダリングされます。
電子アプリの非同期関数とpromiseに関連して修正する必要があるpromiseに何かありますか?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);
isnt good enough and I need to include .output(outputFilepath)
as well. If I change command.run()
to command.output(outputFilepath).run()
, when i click my button, the ffmpeg job gets triggered and rendered perfectly fine. EXCEPT THAT THE FILE IS ALWAYS 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.
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.
This code seems to work, though the max bitrate I'm getting is 320k (I presume this is a limitation of the codec).
もう一度テストした後、ファイルの生成に時間がかかるという点で、私はあなたと同じ動作をしていると思います。CombineMp3FilesOrig関数からPromiseを返す場合は、クリックハンドラーで待機します。通話が完了するまでボタンを無効にします。明らかにボタン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;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加