Producing timelapses while drawing my webtoon panels

I’ve automated my video timelapse production. It’s as simple as can be so I’m making one per panel I draw for my webtoon. The thing is my video editing is always the same. So I can scripti it to death. It’s not meant to make original edits and super dynamic cuts.

It’s just a shell script that takes some image, sound and video globs as input and slugs everything. Adapts the video speed to match the sound duration, makes the transitions and panoramics with ffmpeg…

So I can do something like:

video.sh -i ~/Desktop/38_05.png -v 38/05/*mkv -s ~/Music/savfk/Savfk\ -\ The\ Travelling\ Symphony.wav -o 38_05.mp4

There is a couple options to allow keeping and resuming from temp files for fast iteration. I mainly used it for debug. but I guess no one cares at this point!

Here are a few ones:

6 Likes

Very nice! Scripting is really useful, especially if it’s in a Unix-like environment. And if everything fails, there’s always Python to fall back to :stuck_out_tongue:

1 Like

Actually on mac by a half-hearted choice. So yes *nix for the win!
The video.sh is a (z)shell script. I love how raw and concise it can feel compared to everyday java…
I do have a few python scripts for scribus and krita I couldn’t live without (Especially the krita one but Wolthera wrote 80% of it) but I mostly have some old things I would be ashamed of!

1 Like

That’s how I feel about my bash scripts :slight_smile:

1 Like

any chance you can share the script by chance? hopefully with comments?

I’m really interested in knowing more on how you use ffmpeg to automate all this. are there tutorials out there for this stuff? this would be a game changer for me.

The script needs to be made portable but that’s a next step. For now It’s only used on zsh on macOS + some hardcoded values (like the fps for me is decided at 60).
For now there is only one piece of comment in french :sweat_smile:

About the use of ffmpeg, here is how I

  • slug all the soundtracks
  • get the audio duration
  • slug all video input files (just the recording video, not the intro and panoramics).

$TEMP_SOUNDS and $TEMP_VIDEO are just constants… I think this is not the way we do in shell…

ffmpeg -f concat -safe 0 -i <(for f in $sounds; do echo file "'$f'"; done) -c:a copy $TEMP_SOUNDS
audioDuration=$(ffprobe -v error $TEMP_SOUNDS -select_streams a:0 -show_entries stream=duration | grep -v '\[' | cut -d '=' -f 2)
ffmpeg -f concat -safe 0 -i <(for f in $videos; do echo file "'$f'"; done) -c:v copy $TEMP_VIDEOS

This is full of my custom logic etc, I’m not sure that’s the best way to learn about ffmpeg. For

  1. I’m just a manual exploring noob
  2. it would be clearer with simple examples not tainted with my use case (There is a difference if the image is a portrait or landscape, I have output override confirmation/forcing, backup and resume logic in my naïve way…).

So I’ll just enumerate what comes next:

  • probe the main video length (the slug)
  • probe the extra videos’ length (the intro, the panoramics etc)
  • speed up the main video so it fits the sound length (reencoding needed here as I drop most frames)
  • Then I slice the main video in 3 parts [1st]-[2nnnnnnnnnnnnnnnnnnnnnd]-[3rd].
    so I can fade in and out [1st] and [3rd] (10 sec each) without reencoding all [2nd](several minutes).
  • Reslug everything [intro]-[pan1]-[1st]-[2nnnnnnnnnnnnnnnnnnnnnd]-[3rd]-[pan2].
  • Add the audio
2 Likes

So you don’t do any editing at all? You do everything in script/terminal?

ffmpeg -f concat -safe 0 -i <(for f in $videos; do echo file “‘$f’”; done) -c:v copy $TEMP_VIDEOS

So if I read the code above right, this concatenates all the videos in the directory the script is running in, right? Then it saves it to TEMP_VIDEOS?

This code is probably the one I need the most.

Also, how do you do code block in discourse?

also, how fast does ffmpeg reencode?

Yes, it’s a shell script, so all I do is run commands like the ones in the first post to indicate where is the final image, the soundtrack globs, the video globs, the output…

This temp video is just a slug of all videos. It’s like appending strings if you will.
This is the most basic thing you do in ffmpeg, so you will find lots of resources about this.
It’s cheap so you can concat an X hours video in a couple seconds. Then I can proceed with speeding up the video.

Sorry, I didn’t understand ?

I guess it’s as fast as can be depending on your parameters, as it’s used by everybody under the hood anyway (google, blender, whatever…)
Reencoding induces quality loss and heavy computing. In my script I only do it once as I drop frames to go from X hours to X minutes duration.

1 Like

Here is some valuable resource for the command you are interested in. It’s always worth reading the docs without the over simplification and misunderstanding of some extra youtuber/intermediate:
https://trac.ffmpeg.org/wiki/Concatenate

Here are the docs I must admit it’s gigantic and ffmpeg is far from being the easiest cli tool but it’s super powerfulll and you’ll need that to handle it:
https://ffmpeg.org/documentation.html

You might mean the Preformatted text (Ctrl + e) facility.
The icon is on the line of icons above the text entry box. Looks like ‘</>’

if hungry
then eat
else sleep

It does syntax highlighting but I don’t know its limitations for recognising syntax.

2 Likes

Oh OK! Me, I surround code with triple backticks ` not single quotes ’
From what I can see from the very first command, escaped spaces in string args are not handled well.

video.sh -i ~/Desktop/38_05.png -v 38/05/*mkv -s ~/Music/savfk/Savfk\ -\ The\ Travelling\ Symphony.wav -o 38_05.mp4

the first flag -i is colored, while the -o is melted in the string color.
The globs are colored in a random manner it seems etc…

There are some interesting and confusing differences between that and the </> icon method. I’ll leave it to someone else to explain the details :slight_smile:

</> is single backtick it seems it’s useful for highlighting inline coucou c'est moi

video.sh -i ~/Desktop/38_05.png -v 38/05/*mkv -s ~/Music/savfk/Savfk\ -\ The\ Travelling\ Symphony.wav -o 38_05.mp4

The “preformatted text” option will use single backticks for a single line, but triple backticks for multiple lines.

You can type a language name after the first set of backticks to get specific syntax highlighting, otherwise it will guess. For example with “```zshell”:

video.sh -i ~/Desktop/38_05.png -v 38/05/*mkv -s ~/Music/savfk/Savfk\ -\ The\ Travelling\ Symphony.wav -o 38_05.mp4
3 Likes

the preformatted text option is nested inside the gear button, so I didn’t see it right away.

@MangaTengu

ffmpeg -f concat -safe 0 -i <(for f in $videos; do echo file “‘$f’”; done) -c:v copy $TEMP_VIDEOS

Is this the actual code that would merge all the videos? Every single time I have used the concat command, I would always have to write a text file that would list all my videos. Concat would have to use that file in order to merge all the videos. I don’t see anywhere in your command that concat is reading a text file (unless I’m misreading it). Do you skip this step?

Please bear with me, I’m really no script writer

Sure i can explain!
I’m using a “file descriptor” <(command)
The resulting stream of command is treated as a file.
Here, command writes the result of:

for f in $videos; do
  echo file "'$f'" 
done

If I had written it to a file, I would have gotten your usual input:

file 'pizza strike.mkv'
file 'choco choc.mkv'
file 'babybell.mkv'

the ffmpeg here has the -safe 0 option to accept absolute paths,
because $videos is an array containing absolute file paths. (The files are not located relatively to the “file descriptor” which is /dev/fd/11 here).
So it’s more like:

file '/my/absolute/path/pizza strike.mkv'
file '/my/absolute/path/choco choc.mkv'
file '/my/absolute/path/babybell.mkv'
1 Like

ok, got it. I am not familiar with -safe 0 That’s a nifty thing to learn.

I’m making progress with my version of the script, yay!

1 Like

OMG my script is working! THANK YOU!

last question. from my research online it’s been mentioned several times that concat only works if the files all have the same resolution, framerate, file format, etc. but what would happen if the video files are not all the same? i could see concat giving an error if the file format is wrong, but what if the file formats are right but the resolution is wrong? or framerate is different, etc?

:+1:
Please see in the first link, the topic is tackled at this point:
https://trac.ffmpeg.org/wiki/Concatenate#differentcodec

1 Like