diff --git a/public/MainEvents/Processes/BinFiles/FFmpegCommand.js b/public/MainEvents/Processes/BinFiles/FFmpegCommand.js index 55af905..35dbf76 100644 --- a/public/MainEvents/Processes/BinFiles/FFmpegCommand.js +++ b/public/MainEvents/Processes/BinFiles/FFmpegCommand.js @@ -1,5 +1,6 @@ import { spawn } from 'child_process' import { getBinPath } from '../Helpers/AppPaths.js' +import * as fs from 'fs' const getFFmpegFileName = () => { @@ -8,10 +9,27 @@ const getFFmpegFilePath = () => { return getBinPath(getFFmpegFileName()) }, - convertAudioToMp3 = (srcFile, dstMp3) => { + getAudioInfos = (srcFile) => { + return new Promise((resolve, reject) => { + const stream = spawn(getFFmpegFilePath(), ['-i', srcFile]) + let data = '' + stream.stderr.on('data', (d) => { + data += d.toString() + }) + stream.on('close', () => { + const infos = data.toString().match(/Stream #[0-9]:[0-9]: Audio: ([A-Za-z0-9,/ ]+)/i) + if (infos === null || infos.length < 2) { + reject('audio-infos-not-found') + } else { + resolve(infos[1].toLowerCase().split(', ')) + } + }) + }) + }, + ffmpegAudioToMp3 = (srcFile, dstMp3) => { return new Promise((resolve, reject) => { const stream = spawn(getFFmpegFilePath(), ['-i', srcFile, '-map_metadata', '-1', '-map_chapters', '-1', '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', dstMp3]) - stream.on('close', code => { + stream.on('close', (code) => { if (code === 0) { resolve() } else { @@ -20,10 +38,37 @@ const }) }) }, + convertAudioToMp3 = (srcFile, dstMp3, forceConverting) => { + if (!forceConverting) { + return new Promise((resolve, reject) => { + getAudioInfos(srcFile) + .then((infos) => { + if (infos[0] === 'mp3' && infos[1] === '44100 hz' && (infos[2] === 'stereo' || infos[2] === 'mono')) { + try { + fs.copyFileSync(srcFile, dstMp3) + resolve() + } catch (ignored) { + reject() + } + } else { + ffmpegAudioToMp3(srcFile, dstMp3) + .then(() => resolve()) + .catch(() => reject()) + } + }) + .catch((e) => { + ffmpegAudioToMp3(srcFile, dstMp3) + .then(() => resolve()) + .catch(() => reject()) + }) + }) + } + return ffmpegAudioToMp3(srcFile, dstMp3) + }, convertImageToPng = (srcFile, dstPng, width, height) => { return new Promise((resolve, reject) => { const stream = spawn(getFFmpegFilePath(), ['-i', srcFile, '-vf', 'scale=' + width + 'x' + height + ':flags=bilinear', dstPng]) - stream.on('close', code => { + stream.on('close', (code) => { if (code === 0) { resolve() } else { @@ -35,7 +80,7 @@ const extractMetadataFromMp3 = (srcFile, dstTxt) => { return new Promise((resolve, reject) => { const stream = spawn(getFFmpegFilePath(), ['-i', srcFile, '-f', 'ffmetadata', dstTxt]) - stream.on('close', code => { + stream.on('close', (code) => { if (code === 0) { resolve() } else { @@ -47,7 +92,7 @@ const extractPngFromMp3 = (srcFile, dstPng) => { return new Promise((resolve, reject) => { const stream = spawn(getFFmpegFilePath(), ['-i', srcFile, '-filter:v', 'scale=256x256', '-an', dstPng]) - stream.on('close', code => { + stream.on('close', (code) => { if (code === 0) { resolve() } else { @@ -60,6 +105,7 @@ const export { getFFmpegFileName, getFFmpegFilePath, + getAudioInfos, convertAudioToMp3, convertImageToPng, extractMetadataFromMp3, diff --git a/public/MainEvents/Processes/Import/ConvertFolderSTUdio.js b/public/MainEvents/Processes/Import/ConvertFolderSTUdio.js index 5329645..8ae4484 100644 --- a/public/MainEvents/Processes/Import/ConvertFolderSTUdio.js +++ b/public/MainEvents/Processes/Import/ConvertFolderSTUdio.js @@ -133,7 +133,8 @@ function convertFolderSTUdio (srcPath, storyName) { } fs.writeFileSync(path.join(dstPath, 'metadata.json'), JSON.stringify(metadata)) process.stdout.write('success') - } + }, + false ) ) } catch (e) { diff --git a/public/MainEvents/Processes/Import/ConvertMusic.js b/public/MainEvents/Processes/Import/ConvertMusic.js index 9c72a5c..5bac931 100644 --- a/public/MainEvents/Processes/Import/ConvertMusic.js +++ b/public/MainEvents/Processes/Import/ConvertMusic.js @@ -70,7 +70,7 @@ function convertMusic (srcPath) { return } - convertAudio(srcPath, musicDstPath) + convertAudio(srcPath, musicDstPath, true) .then(() => { process.stdout.write('*music-searching-cover*2*3*') diff --git a/public/MainEvents/Processes/Import/Helpers/AudioFile.js b/public/MainEvents/Processes/Import/Helpers/AudioFile.js index 68e0590..92e8606 100644 --- a/public/MainEvents/Processes/Import/Helpers/AudioFile.js +++ b/public/MainEvents/Processes/Import/Helpers/AudioFile.js @@ -8,11 +8,11 @@ const return ext === '.mp3' || ext === '.ogg' || ext === '.flac' || ext === '.wav' || ext === '.aac' }, - convertAudio = async (fromPath, toPath) => { - await convertAudioToMp3(fromPath, toPath) + convertAudio = async (fromPath, toPath, forceConverting) => { + await convertAudioToMp3(fromPath, toPath, forceConverting) }, - convertAudios = (srcAudios, dstAudios, index, length, onEnd) => { + convertAudios = (srcAudios, dstAudios, index, length, onEnd, forceConverting) => { if (!srcAudios.length) { onEnd(index) return @@ -24,9 +24,9 @@ const process.stdout.write('*converting-audio*' + index + '*' + length + '*') - convertAudio(srcAudio, dstAudio) - .then(() => convertAudios(srcAudios, dstAudios, index + 1, length, onEnd)) - .catch(() => convertAudios(srcAudios, dstAudios, index + 1, length, onEnd)) + convertAudio(srcAudio, dstAudio, forceConverting) + .then(() => convertAudios(srcAudios, dstAudios, index + 1, length, onEnd, forceConverting)) + .catch(() => convertAudios(srcAudios, dstAudios, index + 1, length, onEnd, forceConverting)) }, checkCoverExists = (artist, album, coverPath) => {