Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pass text file to complexFilter #1272

Open
jrohlandt opened this issue May 16, 2024 · 1 comment
Open

pass text file to complexFilter #1272

jrohlandt opened this issue May 16, 2024 · 1 comment

Comments

@jrohlandt
Copy link

jrohlandt commented May 16, 2024

Version information

  • fluent-ffmpeg version: 2.1.2
  • ffmpeg version: 4.1
  • OS: Windows 11

Is it possible to pass a file to complexFilter? I'm running into issues on Windows becuase I have to add hundreds of png overlays to a video.
Is there something like complexFilterScript() or how can I achieve this?

@benoitlahoz
Copy link

benoitlahoz commented Oct 28, 2024

I finally ended with a solution with drawtext filter, but I believe it should be valid for overlay (explanation below).

My situation:

  • I have a huge amount of images I concat in a sequence with different duration according to a curve.
  • I want to overlay their respective duration to check if my curve is correct.

The solution: build a string of filters with template strings and use enable between.

const files = ['path1', 'path2', etc...];

let txt = ''; // our description of files to be treated.
let filters = ''; // the filters we want to apply.
let currentPosition = 0; // current position in file.
let img = 0; // index of current image.

for (const file of files) {
  // Get the image path.
  /// In this case it's defined by 'image' followed by the index of the image then '.jpg'.
  const filepath = path.join(
    VIDEOS_PATH,
    '.tmp',
    `image${String(img).padStart(4, '0')}.jpg`
  );

  // Omitted for brevity.
  const duration = /* get the duration of this specific file. */

  // Append to the string of files that will be treated.
  txt += `file '${filepath}'\nduration ${duration}\n`;

  // Here the important part: append to the 'filters' string that will be passed to 'complexFilters'.
  // 'enable' is the key.
 
  filters += `drawtext=enable='between(t,${currentPosition},${currentPosition + duration})':text='${duration}':x=10:y=H-th-10:fontsize=32:fontcolor=white, `;

  // Next position in file.
  currentPosition += duration;
  img++;
}

// Write the text file that describes our inputs.
fs.writeFileSync(path.join(VIDEOS_PATH, '.tmp', `desc.txt`), txt, 'utf8');

ffmpeg()
  // Add inputs with file.
  .addInput(path.join(VIDEOS_PATH, '.tmp', `desc.txt`))
  // Concat.
  .inputOptions(['-safe 0', '-f concat'])

  // Pass the filters!
  .complexFilter(filters)

  .fps(25)
  .output(
    path.join(VIDEOS_PATH, `output.mov`)
  )
  .run();

For overlay, you can look this or this SO answers. I guess you could add overlays inputs the same way. The problem will be to retrieve [YOUR_INDEX:v] in the filter string. Didn't tested it though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants