Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
·
e9ae5da
1
Parent(s):
73a3511
fix for text position
Browse files
src/core/ffmpeg/concatenateVideosWithAudio.mts
CHANGED
@@ -46,7 +46,7 @@ export const concatenateVideosWithAudio = async ({
|
|
46 |
|
47 |
if (audioTrack && audioTrack.length > 0) {
|
48 |
const analysis = extractBase64(audioTrack)
|
49 |
-
console.log(`concatenateVideosWithAudio: writing down an audio file (${analysis.extension}) from the supplied base64 track`)
|
50 |
audioFilePath = path.join(tempDir, `audio.${analysis.extension}`);
|
51 |
await writeBase64ToFile(addBase64Header(audioTrack, analysis.extension), audioFilePath);
|
52 |
}
|
@@ -60,7 +60,7 @@ export const concatenateVideosWithAudio = async ({
|
|
60 |
const analysis = extractBase64(audioTrack)
|
61 |
const videoFilePath = path.join(tempDir, `video${++i}.${analysis.extension}`);
|
62 |
|
63 |
-
console.log(`concatenateVideosWithAudio: writing down a video file (${analysis.extension}) from the supplied base64 track`)
|
64 |
|
65 |
await writeBase64ToFile(addBase64Header(track, analysis.extension), videoFilePath);
|
66 |
|
@@ -69,21 +69,21 @@ export const concatenateVideosWithAudio = async ({
|
|
69 |
|
70 |
videoFilePaths = videoFilePaths.filter((video) => existsSync(video))
|
71 |
|
72 |
-
console.log("concatenateVideosWithAudio: concatenating videos (without audio)..")
|
73 |
const tempFilePath = await concatenateVideos({
|
74 |
videoFilePaths,
|
75 |
})
|
76 |
-
console.log(`concatenateVideosWithAudio: tempFilePath = ${JSON.stringify(tempFilePath, null, 2)}`)
|
77 |
|
78 |
// Check if the concatenated video has audio or not
|
79 |
const tempMediaInfo = await getMediaInfo(tempFilePath.filepath);
|
80 |
const hasOriginalAudio = tempMediaInfo.hasAudio;
|
81 |
|
82 |
-
console.log(`concatenateVideosWithAudio: hasOriginalAudio = ${hasOriginalAudio}`)
|
83 |
|
84 |
const finalOutputFilePath = output || path.join(tempDir, `${uuidv4()}.${format}`);
|
85 |
|
86 |
-
console.log(`concatenateVideosWithAudio: finalOutputFilePath = ${finalOutputFilePath}`)
|
87 |
|
88 |
// Begin ffmpeg command configuration
|
89 |
let ffmpegCommand = ffmpeg();
|
@@ -95,12 +95,12 @@ export const concatenateVideosWithAudio = async ({
|
|
95 |
|
96 |
// If additional audio is provided, add audio to ffmpeg command
|
97 |
if (typeof audioFilePath === "string" && audioFilePath.length > 0) {
|
98 |
-
console.log(`concatenateVideosWithAudio: adding an audio file path: ${audioFilePath}`)
|
99 |
|
100 |
ffmpegCommand = ffmpegCommand.addInput(audioFilePath);
|
101 |
// If the input video already has audio, we will mix it with additional audio
|
102 |
if (hasOriginalAudio) {
|
103 |
-
console.log(`concatenateVideosWithAudio: case 1: additional audio was provided, and we already have audio: we mix`)
|
104 |
|
105 |
const filterComplex = `
|
106 |
[0:a]volume=${videoTracksVolume}[a0];
|
@@ -116,7 +116,7 @@ export const concatenateVideosWithAudio = async ({
|
|
116 |
'-c:a', 'aac',
|
117 |
]);
|
118 |
} else {
|
119 |
-
console.log(`concatenateVideosWithAudio: case 2: additional audio was provided, but we don't already have audio: we overwrite`)
|
120 |
|
121 |
// If the input video has no audio, just use the additional audio as is
|
122 |
ffmpegCommand = ffmpegCommand.outputOptions([
|
@@ -127,7 +127,7 @@ export const concatenateVideosWithAudio = async ({
|
|
127 |
]);
|
128 |
}
|
129 |
} else {
|
130 |
-
console.log(`concatenateVideosWithAudio: case 3: no additional audio provided, we leave the audio as-is`)
|
131 |
|
132 |
// If no additional audio is provided, simply copy the video stream
|
133 |
ffmpegCommand = ffmpegCommand.outputOptions([
|
@@ -183,7 +183,7 @@ export const concatenateVideosWithAudio = async ({
|
|
183 |
} catch (error) {
|
184 |
throw new Error(`Failed to assemble video: ${(error as Error).message}`);
|
185 |
} finally {
|
186 |
-
console.log(`concatenateVideosWithAudio: deleting ${JSON.stringify([...videoFilePaths].concat(audioFilePath), null, 2)}`)
|
187 |
await removeTemporaryFiles([...videoFilePaths].concat(audioFilePath))
|
188 |
}
|
189 |
};
|
|
|
46 |
|
47 |
if (audioTrack && audioTrack.length > 0) {
|
48 |
const analysis = extractBase64(audioTrack)
|
49 |
+
// console.log(`concatenateVideosWithAudio: writing down an audio file (${analysis.extension}) from the supplied base64 track`)
|
50 |
audioFilePath = path.join(tempDir, `audio.${analysis.extension}`);
|
51 |
await writeBase64ToFile(addBase64Header(audioTrack, analysis.extension), audioFilePath);
|
52 |
}
|
|
|
60 |
const analysis = extractBase64(audioTrack)
|
61 |
const videoFilePath = path.join(tempDir, `video${++i}.${analysis.extension}`);
|
62 |
|
63 |
+
// console.log(`concatenateVideosWithAudio: writing down a video file (${analysis.extension}) from the supplied base64 track`)
|
64 |
|
65 |
await writeBase64ToFile(addBase64Header(track, analysis.extension), videoFilePath);
|
66 |
|
|
|
69 |
|
70 |
videoFilePaths = videoFilePaths.filter((video) => existsSync(video))
|
71 |
|
72 |
+
// console.log("concatenateVideosWithAudio: concatenating videos (without audio)..")
|
73 |
const tempFilePath = await concatenateVideos({
|
74 |
videoFilePaths,
|
75 |
})
|
76 |
+
// console.log(`concatenateVideosWithAudio: tempFilePath = ${JSON.stringify(tempFilePath, null, 2)}`)
|
77 |
|
78 |
// Check if the concatenated video has audio or not
|
79 |
const tempMediaInfo = await getMediaInfo(tempFilePath.filepath);
|
80 |
const hasOriginalAudio = tempMediaInfo.hasAudio;
|
81 |
|
82 |
+
// console.log(`concatenateVideosWithAudio: hasOriginalAudio = ${hasOriginalAudio}`)
|
83 |
|
84 |
const finalOutputFilePath = output || path.join(tempDir, `${uuidv4()}.${format}`);
|
85 |
|
86 |
+
// console.log(`concatenateVideosWithAudio: finalOutputFilePath = ${finalOutputFilePath}`)
|
87 |
|
88 |
// Begin ffmpeg command configuration
|
89 |
let ffmpegCommand = ffmpeg();
|
|
|
95 |
|
96 |
// If additional audio is provided, add audio to ffmpeg command
|
97 |
if (typeof audioFilePath === "string" && audioFilePath.length > 0) {
|
98 |
+
// console.log(`concatenateVideosWithAudio: adding an audio file path: ${audioFilePath}`)
|
99 |
|
100 |
ffmpegCommand = ffmpegCommand.addInput(audioFilePath);
|
101 |
// If the input video already has audio, we will mix it with additional audio
|
102 |
if (hasOriginalAudio) {
|
103 |
+
// console.log(`concatenateVideosWithAudio: case 1: additional audio was provided, and we already have audio: we mix`)
|
104 |
|
105 |
const filterComplex = `
|
106 |
[0:a]volume=${videoTracksVolume}[a0];
|
|
|
116 |
'-c:a', 'aac',
|
117 |
]);
|
118 |
} else {
|
119 |
+
// console.log(`concatenateVideosWithAudio: case 2: additional audio was provided, but we don't already have audio: we overwrite`)
|
120 |
|
121 |
// If the input video has no audio, just use the additional audio as is
|
122 |
ffmpegCommand = ffmpegCommand.outputOptions([
|
|
|
127 |
]);
|
128 |
}
|
129 |
} else {
|
130 |
+
// console.log(`concatenateVideosWithAudio: case 3: no additional audio provided, we leave the audio as-is`)
|
131 |
|
132 |
// If no additional audio is provided, simply copy the video stream
|
133 |
ffmpegCommand = ffmpegCommand.outputOptions([
|
|
|
183 |
} catch (error) {
|
184 |
throw new Error(`Failed to assemble video: ${(error as Error).message}`);
|
185 |
} finally {
|
186 |
+
// console.log(`concatenateVideosWithAudio: deleting ${JSON.stringify([...videoFilePaths].concat(audioFilePath), null, 2)}`)
|
187 |
await removeTemporaryFiles([...videoFilePaths].concat(audioFilePath))
|
188 |
}
|
189 |
};
|
src/core/ffmpeg/createTextOverlayImage.mts
CHANGED
@@ -75,8 +75,8 @@ export async function createTextOverlayImage({
|
|
75 |
})}</head>
|
76 |
<body>
|
77 |
|
78 |
-
<!-- main
|
79 |
-
<div class="content">
|
80 |
|
81 |
<!-- main line of text -->
|
82 |
<p class="${textStyle}">
|
|
|
75 |
})}</head>
|
76 |
<body>
|
77 |
|
78 |
+
<!-- main container block -->
|
79 |
+
<div class="content ${textStyle}">
|
80 |
|
81 |
<!-- main line of text -->
|
82 |
<p class="${textStyle}">
|
src/core/utils/getCssStyle.mts
CHANGED
@@ -56,14 +56,12 @@ export function getCssStyle({
|
|
56 |
height: ${height || "100vh"};
|
57 |
overflow: hidden;
|
58 |
margin: 0;
|
59 |
-
padding: 0;
|
60 |
-
display: flex;
|
61 |
-
align-items: center;
|
62 |
-
justify-content: center;
|
63 |
-
}
|
64 |
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
67 |
display: flex;
|
68 |
flex-direction: column;
|
69 |
align-items: ${
|
@@ -74,16 +72,15 @@ export function getCssStyle({
|
|
74 |
};
|
75 |
}
|
76 |
|
|
|
|
|
|
|
|
|
77 |
p {
|
78 |
font-family: "${fontFamily}", sans-serif;
|
79 |
font-size: ${fontSize}vh;
|
80 |
font-weight: ${fontWeight};
|
81 |
border-radius: 2vh;
|
82 |
-
padding-top: ${py}vh;
|
83 |
-
padding-right: ${px}vh;
|
84 |
-
padding-bottom: ${py}vh;
|
85 |
-
padding-left: ${px}vh;
|
86 |
-
text-align: ${horizontalPosition};
|
87 |
|
88 |
/*
|
89 |
normally we should use those webkit features:
|
@@ -95,7 +92,7 @@ export function getCssStyle({
|
|
95 |
|
96 |
*/
|
97 |
text-shadow:
|
98 |
-
|
99 |
-${0.35}vh ${0.35}vh ${0.3}vh #000,
|
100 |
-${0.35}vh -${0.35}vh 0 #000,
|
101 |
${0.35}vh -${0.35}vh 0 #000;
|
|
|
56 |
height: ${height || "100vh"};
|
57 |
overflow: hidden;
|
58 |
margin: 0;
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
padding-top: ${py}vh;
|
61 |
+
padding-right: ${px}vh;
|
62 |
+
padding-bottom: ${py}vh;
|
63 |
+
padding-left: ${px}vh;
|
64 |
+
|
65 |
display: flex;
|
66 |
flex-direction: column;
|
67 |
align-items: ${
|
|
|
72 |
};
|
73 |
}
|
74 |
|
75 |
+
.content {
|
76 |
+
text-align: ${horizontalPosition};
|
77 |
+
}
|
78 |
+
|
79 |
p {
|
80 |
font-family: "${fontFamily}", sans-serif;
|
81 |
font-size: ${fontSize}vh;
|
82 |
font-weight: ${fontWeight};
|
83 |
border-radius: 2vh;
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
/*
|
86 |
normally we should use those webkit features:
|
|
|
92 |
|
93 |
*/
|
94 |
text-shadow:
|
95 |
+
${0.35}vh ${0.35}vh ${0.3}vh #000,
|
96 |
-${0.35}vh ${0.35}vh ${0.3}vh #000,
|
97 |
-${0.35}vh -${0.35}vh 0 #000,
|
98 |
${0.35}vh -${0.35}vh 0 #000;
|