jbilcke-hf HF staff commited on
Commit
a25b190
·
1 Parent(s): deff001

add a zoom-in effect

Browse files
src/core/ffmpeg/imageToVideoBase64.mts CHANGED
@@ -14,6 +14,7 @@ import { getRandomDirectory } from "../files/getRandomDirectory.mts";
14
  * @param width - Optional. Width of the output video.
15
  * @param height - Optional. Height of the output video.
16
  * @param fps - Optional. Frame rate of the output video.
 
17
  *
18
  * @returns - A promise that resolves to the video as a Base64 encoded string.
19
  */
@@ -27,7 +28,8 @@ export async function imageToVideoBase64({
27
  codec = outputVideoFormat === "webm" ? "libvpx-vp9" : "libx264",
28
  width = 1920,
29
  height = 1080,
30
- fps = 25
 
31
  }: {
32
  inputImageInBase64: string
33
  outputFilePath?: string
@@ -39,6 +41,7 @@ export async function imageToVideoBase64({
39
  width?: number
40
  height?: number
41
  fps?: number
 
42
  }): Promise<string> {
43
 
44
  outputDir = outputDir || (await getRandomDirectory())
@@ -62,13 +65,13 @@ export async function imageToVideoBase64({
62
 
63
  // Set the path for the output video.
64
  outputFilePath = outputFilePath || path.join(outputDir, `output.${outputVideoFormat}`);
 
65
  const durationInSeconds = outputVideoDurationInMs / 1000;
66
 
67
- console.log("durationInSeconds: " + durationInSeconds)
68
-
69
  // Process the image to video conversion using ffmpeg.
70
  await new Promise<void>((resolve, reject) => {
71
- ffmpeg(inputImagePath)
 
72
  .inputOptions(['-loop 1']) // Loop the input image
73
  .outputOptions([
74
  `-t ${durationInSeconds}`,
@@ -78,6 +81,14 @@ export async function imageToVideoBase64({
78
  '-tune stillimage',
79
  '-pix_fmt yuv420p'
80
  ])
 
 
 
 
 
 
 
 
81
  .on('end', () => resolve())
82
  .on('error', (err) => reject(err))
83
  .save(outputFilePath);
 
14
  * @param width - Optional. Width of the output video.
15
  * @param height - Optional. Height of the output video.
16
  * @param fps - Optional. Frame rate of the output video.
17
+ * @param zoomInRatePerSecond - Optional. Zoom-in rate (by default 0.6, or which would zoom by 3% over 5 seconds)
18
  *
19
  * @returns - A promise that resolves to the video as a Base64 encoded string.
20
  */
 
28
  codec = outputVideoFormat === "webm" ? "libvpx-vp9" : "libx264",
29
  width = 1920,
30
  height = 1080,
31
+ fps = 25,
32
+ zoomInRatePerSecond = 0.6
33
  }: {
34
  inputImageInBase64: string
35
  outputFilePath?: string
 
41
  width?: number
42
  height?: number
43
  fps?: number
44
+ zoomInRatePerSecond?: number
45
  }): Promise<string> {
46
 
47
  outputDir = outputDir || (await getRandomDirectory())
 
65
 
66
  // Set the path for the output video.
67
  outputFilePath = outputFilePath || path.join(outputDir, `output.${outputVideoFormat}`);
68
+
69
  const durationInSeconds = outputVideoDurationInMs / 1000;
70
 
 
 
71
  // Process the image to video conversion using ffmpeg.
72
  await new Promise<void>((resolve, reject) => {
73
+
74
+ let ffmpegCommand = ffmpeg(inputImagePath)
75
  .inputOptions(['-loop 1']) // Loop the input image
76
  .outputOptions([
77
  `-t ${durationInSeconds}`,
 
81
  '-tune stillimage',
82
  '-pix_fmt yuv420p'
83
  ])
84
+
85
+ // Apply zoompan filter only if zoom rate is greater than 0
86
+ if (zoomInRatePerSecond > 0) {
87
+ const totalZoomFactor = 1 + (zoomInRatePerSecond / 100) * durationInSeconds;
88
+ ffmpegCommand = ffmpegCommand.videoFilters(`zoompan=z='min(zoom+${zoomInRatePerSecond}/100,zoom*${totalZoomFactor})':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=1`);
89
+ }
90
+
91
+ return ffmpegCommand
92
  .on('end', () => resolve())
93
  .on('error', (err) => reject(err))
94
  .save(outputFilePath);