jbilcke-hf HF staff commited on
Commit
ccd3eba
·
1 Parent(s): 1083ad0
src/core/ffmpeg/concatenateVideosWithAudio.mts CHANGED
@@ -43,7 +43,8 @@ export const concatenateVideosWithAudio = async ({
43
  const tempDir = path.join(os.tmpdir(), uuidv4());
44
  await fs.mkdir(tempDir);
45
 
46
- if (audioTrack) {
 
47
  audioFilePath = path.join(tempDir, `audio.wav`);
48
  await writeBase64ToFile(addBase64Header(audioTrack, "wav"), audioFilePath);
49
  }
@@ -52,8 +53,12 @@ export const concatenateVideosWithAudio = async ({
52
  let i = 0
53
  for (const track of videoTracks) {
54
  if (!track) { continue }
 
 
55
  const videoFilePath = path.join(tempDir, `video${++i}.mp4`);
56
 
 
 
57
  await writeBase64ToFile(addBase64Header(track, "mp4"), videoFilePath);
58
 
59
  videoFilePaths.push(videoFilePath);
@@ -65,24 +70,28 @@ export const concatenateVideosWithAudio = async ({
65
  const tempFilePath = await concatenateVideos({
66
  videoFilePaths,
67
  })
 
68
 
69
  // Check if the concatenated video has audio or not
70
  const tempMediaInfo = await getMediaInfo(tempFilePath.filepath);
71
  const hasOriginalAudio = tempMediaInfo.hasAudio;
72
 
 
 
73
  const finalOutputFilePath = output || path.join(tempDir, `${uuidv4()}.${format}`);
74
 
75
  console.log(`concatenateVideosWithAudio: finalOutputFilePath = ${finalOutputFilePath}`)
76
 
77
  // Begin ffmpeg command configuration
78
- let cmd = ffmpeg();
79
 
80
- // Add silent concatenated video
81
- cmd = cmd.addInput(tempFilePath.filepath);
82
 
 
 
83
  // If additional audio is provided, add audio to ffmpeg command
84
  if (audioFilePath) {
85
- cmd = cmd.addInput(audioFilePath);
86
  // If the input video already has audio, we will mix it with additional audio
87
  if (hasOriginalAudio) {
88
  const filterComplex = `
@@ -91,7 +100,7 @@ export const concatenateVideosWithAudio = async ({
91
  [a0][a1]amix=inputs=2:duration=shortest[a]
92
  `.trim();
93
 
94
- cmd = cmd.outputOptions([
95
  '-filter_complex', filterComplex,
96
  '-map', '0:v',
97
  '-map', '[a]',
@@ -100,7 +109,7 @@ export const concatenateVideosWithAudio = async ({
100
  ]);
101
  } else {
102
  // If the input video has no audio, just use the additional audio as is
103
- cmd = cmd.outputOptions([
104
  '-map', '0:v',
105
  '-map', '1:a',
106
  '-c:v', 'copy',
@@ -109,7 +118,7 @@ export const concatenateVideosWithAudio = async ({
109
  }
110
  } else {
111
  // If no additional audio is provided, simply copy the video stream
112
- cmd = cmd.outputOptions([
113
  '-c:v', 'copy',
114
  hasOriginalAudio ? '-c:a' : '-an', // If original audio exists, copy it; otherwise, indicate no audio
115
  ]);
@@ -131,7 +140,7 @@ export const concatenateVideosWithAudio = async ({
131
 
132
  // Set up event handlers for ffmpeg processing
133
  const promise = new Promise<string>((resolve, reject) => {
134
- cmd.on('error', (err) => {
135
  console.error("concatenateVideosWithAudio: Error during ffmpeg processing:", err.message);
136
  reject(err);
137
  }).on('end', async () => {
 
43
  const tempDir = path.join(os.tmpdir(), uuidv4());
44
  await fs.mkdir(tempDir);
45
 
46
+ if (audioTrack && audioTrack.length > 0) {
47
+ console.log("concatenateVideosWithAudio: writing down an audio file from the supplied base64 track")
48
  audioFilePath = path.join(tempDir, `audio.wav`);
49
  await writeBase64ToFile(addBase64Header(audioTrack, "wav"), audioFilePath);
50
  }
 
53
  let i = 0
54
  for (const track of videoTracks) {
55
  if (!track) { continue }
56
+ // note: here we assume the input video is in mp4
57
+
58
  const videoFilePath = path.join(tempDir, `video${++i}.mp4`);
59
 
60
+ console.log("concatenateVideosWithAudio: writing down an audio file from the supplied base64 track")
61
+
62
  await writeBase64ToFile(addBase64Header(track, "mp4"), videoFilePath);
63
 
64
  videoFilePaths.push(videoFilePath);
 
70
  const tempFilePath = await concatenateVideos({
71
  videoFilePaths,
72
  })
73
+ console.log(`concatenateVideosWithAudio: tempFilePath = ${tempFilePath}`)
74
 
75
  // Check if the concatenated video has audio or not
76
  const tempMediaInfo = await getMediaInfo(tempFilePath.filepath);
77
  const hasOriginalAudio = tempMediaInfo.hasAudio;
78
 
79
+ console.log(`concatenateVideosWithAudio: hasOriginalAudio = ${hasOriginalAudio}`)
80
+
81
  const finalOutputFilePath = output || path.join(tempDir, `${uuidv4()}.${format}`);
82
 
83
  console.log(`concatenateVideosWithAudio: finalOutputFilePath = ${finalOutputFilePath}`)
84
 
85
  // Begin ffmpeg command configuration
86
+ let ffmpegCommand = ffmpeg();
87
 
88
+ ffmpegCommand = ffmpegCommand.addInput(tempFilePath.filepath);
 
89
 
90
+ ffmpegCommand = ffmpegCommand.outputOptions('-loglevel', 'debug');
91
+
92
  // If additional audio is provided, add audio to ffmpeg command
93
  if (audioFilePath) {
94
+ ffmpegCommand = ffmpegCommand.addInput(audioFilePath);
95
  // If the input video already has audio, we will mix it with additional audio
96
  if (hasOriginalAudio) {
97
  const filterComplex = `
 
100
  [a0][a1]amix=inputs=2:duration=shortest[a]
101
  `.trim();
102
 
103
+ ffmpegCommand = ffmpegCommand.outputOptions([
104
  '-filter_complex', filterComplex,
105
  '-map', '0:v',
106
  '-map', '[a]',
 
109
  ]);
110
  } else {
111
  // If the input video has no audio, just use the additional audio as is
112
+ ffmpegCommand = ffmpegCommand.outputOptions([
113
  '-map', '0:v',
114
  '-map', '1:a',
115
  '-c:v', 'copy',
 
118
  }
119
  } else {
120
  // If no additional audio is provided, simply copy the video stream
121
+ ffmpegCommand = ffmpegCommand.outputOptions([
122
  '-c:v', 'copy',
123
  hasOriginalAudio ? '-c:a' : '-an', // If original audio exists, copy it; otherwise, indicate no audio
124
  ]);
 
140
 
141
  // Set up event handlers for ffmpeg processing
142
  const promise = new Promise<string>((resolve, reject) => {
143
+ ffmpegCommand.on('error', (err) => {
144
  console.error("concatenateVideosWithAudio: Error during ffmpeg processing:", err.message);
145
  reject(err);
146
  }).on('end', async () => {