Skip to content

Commit

Permalink
Merge pull request #10 from mediamonks/feature/audio
Browse files Browse the repository at this point in the history
Adds audio option to video generation process
  • Loading branch information
PabloCarreira authored Feb 26, 2024
2 parents e40e225 + 343dda7 commit 179dee4
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
6 changes: 5 additions & 1 deletion cli/displayAdsRecorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const findAdsInDirectory = require("../src/util/findAdsInDirectory");
new program.Option("-g, --gif [loop]", "If you want to output animated gifs and loop them or play once").choices(['once', 'loop'])
)
.option("-m, --mp4", "If you want to output video")
.option("-au, --audio <relative path to audio file from target dir>", "If you want to add audio")
.option("-v, --volume <volume>", "When adding audio you can specify volume")
.addOption(
new program.Option("-f, --fps <data>", "fps for gif and/or mp4").choices(['15', '30', '60'])
)
Expand Down Expand Up @@ -64,7 +66,9 @@ const findAdsInDirectory = require("../src/util/findAdsInDirectory");
output: outputChoices.map(e => e.value).filter(e => options[e]),
gifLoopOptions: gifLoopOptionsMap[options.gif],
fps: options.fps,
jpgMaxFileSize: options.jpg
jpgMaxFileSize: options.jpg,
audio: options.audio,
volume: options.volume,
}

// inquirer questions
Expand Down
19 changes: 18 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const recordAd = require("./util/recordDisplayAd");
const addAudioToVideo = require("./util/addAudioToVideo");
const renderVideo = require("./util/renderVideoFromFiles");
const getBackupImage = require("./util/getBackupImage");
const renderGIf = require("./util/renderGifFromVideoFile");
Expand Down Expand Up @@ -43,6 +44,10 @@ module.exports = async function displayAdsRecorder(options, chunkSize = 10) {
await runWithChunks(recordGif, "making GIFs")
}

if (adSelection.output.includes("mp4") && adSelection.audio) {
await runWithChunks(addAudio, "adding audio track to videos")
}

await runWithChunks(clearScreenshots, "clearing tmp files")
}

Expand Down Expand Up @@ -99,6 +104,18 @@ module.exports = async function displayAdsRecorder(options, chunkSize = 10) {
});
}

async function addAudio(adLocation) {
const [url, htmlBaseDirName] = urlFromAdLocation(adLocation);

const video = path.join(targetDir, `${htmlBaseDirName}.mp4`)
const audio = path.join(targetDir, adSelection.audio)
await addAudioToVideo(
video,
audio,
adSelection.volume
);
}

async function clearScreenshots(adLocation) {
const screenshots = path.join(path.dirname(adLocation), ".cache/");
await fs.rm(screenshots, { force: true, recursive: true })
Expand All @@ -108,7 +125,7 @@ module.exports = async function displayAdsRecorder(options, chunkSize = 10) {
const startTime = new Date().getTime();
const progressBar = new cliProgress.SingleBar({
format:
`${name}${' '.repeat(25 - name.length)}[{bar}] {percentage}% | ETA: {eta}s | {value}/{total}`,
`${name}${' '.repeat(30 - name.length)}[{bar}] {percentage}% | ETA: {eta}s | {value}/{total}`,
}, cliProgress.Presets.shades_classic);
progressBar.start(adSelection.location.length, 0);

Expand Down
37 changes: 37 additions & 0 deletions src/util/addAudioToVideo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path
const ffmpeg = require("fluent-ffmpeg")
const fs = require('fs/promises')
ffmpeg.setFfmpegPath(ffmpegPath)

module.exports = async function addAudioToVideo(
video,
audio,
volume = 1
) {
const output = video.replace('.mp4', '-audio.mp4')

return new Promise((resolve, reject) => {
ffmpeg()
.addInput(video)
.addInput(audio)
.withOptions([
`-af volume=${volume}`,
// '-filter:a loudnorm' // normalize audio volume
])
.output(output)
.outputOptions([
'-map 0:v',
'-map 1:a',
'-c:v copy',
'-shortest' // comment if your audio is shorter
])
.on('error', reject)
.on("end", async () => {
// since we can't save to the same file we're working with - using tmp file
await fs.copyFile(output, video)
await fs.unlink(output)
resolve(video);
})
.run()
})
}
1 change: 1 addition & 0 deletions src/util/renderVideoFromFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = async function renderVideoFromFiles(
process.fps(fps);
process.videoBitrate(10000);
process.output(output);
process.outputOptions(['-pix_fmt yuv420p'])
process.on("end", () => {
resolve(output);
});
Expand Down

0 comments on commit 179dee4

Please sign in to comment.