Skip to content

wrappers for ffmpeg, to simplify creating youtube videos from a series of mov files.

License

Notifications You must be signed in to change notification settings

zarniwhoop73/video-scripts

Repository files navigation

History:

 In mid summer 2011 I spent a little time in southern France, taking still
photos with my Olympus four-thirds system.  I do have an ultra-wide zoom in
that system, but I do not usually take it with me because it weighs a ton.
On a few occasions, I realised that a 24mm lens (35mm equivalent) would have
been useful, and on other occasions (such as photographing butterflies) a
lens longer than 210mm equivalent would have been very useful.

 So, when I got home I investigated the current compact cameras and got
myself a panasonic FZ45.  This comes with a video capability.  At home, I
managed to configure this so that I could create QuickTime mov files, and
confirmed that I could play these.  I then went on a long holiday to Austria
and Switzerland, hoping to photograph narrow-gauge trains, and butterflies.

 Once I was there, I realised that some movies of the railways would be a
nice souvenir.  Unfortunately, many of my clips turned out to be "not very
good" - holding a camera one-handed never helps, the audio from a moving train
mostly records wind noise on the microphone, and most of the time I had no idea
what would be coming up.  So, many of my clips were not sufficiently interesting
to stand on their own.

 But I did have three shortish clips which looked as if they might be worth
putting on youtube.  At that time I had ffmpeg-0.6.0, or perhaps 0.7 by the
time I was playing with these files.  Getting the mov files to something which
was smaller (I had a very slow upload speed), acceptable to youtube, and of
adequate quality) took a lot of experimentation, and I found it very painful.

 Along the way, I got pointed to MediaInfo which has been very useful for my
subsequent examination of audio and video files.  I then started to try to
work out what I could do with those clips that would only be useful as part
of a longer film.  I quickly discovered that using the -vol option in ffmpeg
would let me make the sound quieter for those parts where the wind noise
dominated, and I made some notes about which clips I might want to use.  But
then I got back into {,beyond-}linuxfromscratch editing and never found the
time to get back to this.

 In May 2014 I finally managed to set aside some time for this.  First, I
looked for libre editing tools.  Gentoo have ebuilds for many of these, which
helped me work out dependencies.  I first tried avidemux, but on my hardware
(possibly, because I use alsa, not pulse, for sound) the sound was useless.
I looked at various things - lives did not run when I eventually built it, and
google had no results matching my problem.  The other editing tools seemed to
have a lot of dependencies, particularly in Python for doing "fancy" things
which I didn't particularly want to do.  In the end, I decided to see if I could
use ffmpeg on the command line for what I wanted to achieve.  My requirements
were fairly limited:

- clip the duration of the file in some cases, typically by losing the end
  but in some cases it might also be useful to lose the start.

 Update: since my camera produces QuickTime mov files where every frame is a
 keyframe, I have discovered it is easier to make a copy of the original
 file using
  ffmpeg -i original.mov -ss start-offset -t duration -c copy -y newname.mov
 and then I can confirm the number of frames.

- reduce the volume

- fade the video in/out at the end of each clip

- similarly, fade the sound in/out

- produce static captions on static backgrounds (a title for the movie, perhaps
  "That's All Folks!" at the end).

- for me, overlaying captions onto film clips was not something I wanted to do,
  my aims are very much KISS.  However, after looking at some films from other
  people I can see that this is a useful thing to do - if it is not too hard.

   Almost failed at "not too hard" - I have a problem with using double quotes
  within variables which are used to make up the arguments for -vf, and it bit
  me again here : the command values after the first space in the text were
  treated as new commands.  In the end, changing the space(s) to UTF-8
  non-break-space using rxvt-unicode to let me enter the glyph value of '(00)A0'
  made this work.  However, now that I have used this (split clip into before,
  with-text, after input files using ffmpeg before processing them) I notice
  that every time text appears or disappears, there is a slight visible stutter
  in the finished video if I play it in vlc (xine is fine).

- put the various clips together.

- do not lose too much visual quality!  In practice, I have to balance this
  agaisnt my upload speeds - on a good day, I get 2Mbps up, which is about
  10.5MB per minute.

- upload them to youtube.

- and, eventually, I added the ability to put a title there, because showing
  the filename is not particularly nice.  Unfortunately, this does not always
  show at youtube - when I started, the full filename was shown, but now I'm
  not clear what is picked up - perhaps anything in parentheses () is ignored.
  Or, maybe I have to fill in the first blank field after uploading ;)  Looks
  as if the title is not necessarily used, but it's still a nice thing to have
  when reviewing the local files.

 I began by using the ffmpeg settings which had worked for me in 2011 (setting
a video bandwidth of 5500k, and two-pass conversion to x264).  I found out that
ffmpeg's video fades only seemed to work (in ffmpeg-2.2.2) when start-frame and
number-of-frames were specified (times should supposedly work), and that I could
not fade the aac audio.

 I tried creating the audio files in other formats, and quickly noticed (by
using mediainfo to check) that the audio was typically longer than the video,
often by 125ms or more.  I knew that I would want to merge ten or more clips
for the videos, so the difference in stream lengths looked as if it might
mean that the sound would increasingly lag the picture, but not in a consistent
fashion.  I then tried creating wav files for the audio, and found they were
usually the exact same length as the video.

 Unfortunately, x264 video with wav audio is not a valid format for an mp4
video file.  So, I put them into an mkv container - this is not a common
combination, but vlc and parole seem happy enough with it [ xine gives silent
audio with these work files, but is fine with the finished x264/aac files ].

 Joining the clips together gave me more problems, but the ffmpeg wiki pointed
me to a method that worked.  Unfortunately the command line becomes longer and
longer as the number of clips increases, and ffmpeg has to re-encode which
takes time and implies a potential loss of quality but does let me change the
audio to aac (using fdk_aac : the ffmpeg binaries are probably not distributable
because of license incompatabilities, so distros will not have this encoder,
but for those of us who build from source for our own use that is not an issue).

 Meanwhile, I was trying different settings in ffmpeg.  These did not all do
what I thought they would, but I eventually came up with some settings that
created larger files, of subjectively better quality but (hopefully) not _too_
slow to upload.

 After this, I knew what I wanted to do, and it was time to start scripting.
For me, the biggest problem with any program is validating what it has been
told to do.  I think these scripts are now adequately useful for me.

Update from 2022:

 I decided it would be convenient to take some other mkv videos I had
downloaded and put them in an mp4 container so that I could play them in
firefox. For this I have added mkv2mp4.sh which does not depend on the other
scripts, but in those cases where it needs to recode the audio it, like the
others, uses ffmpeg linked against fdk_aac.  This was tested with ffmpeg5.1.
When I looked at the ffmpeg wiki in around August 22, using fdk_aac was said
to still give higher quality than ffmpeg's own aac encoder.

 The scripts are:

mkv2mp4.sh		Convert an mkv video to mp3.  Use mediainfo to
			minimally check the format, and if the audio is
			neither aac nor MPEG Audio then recode it to aac.
			That is necessary for files with e.g. Ogg audio.
			Also recode the video if other formats such as VP9.

mpv2mp4.sh		Take one of my mkv files produced by the other
			scripts and put it into an M@EG-4 container so that
			firefox can play a local copy.  Needs MediaInfo.

video-clip.sh		convert an input file to mp4 and optionally fade
			the video in/out, extract the audio to wav,
			optionally change the volume and fade it in out,
			merge the results into an mkv container.  This
			trades file size for run time.  The quality
			settings are hardcoded.

			 On my AMD Phenom, processing individual clips
			takes about 1.25x real-time (and several multiples
			of that to decide what to use, where to cut, and
			to review tham!).  Merging (i.e. remuxing) takes
			about 1.1x real time.  For a video which lasted
			about 10m30, the final file was 433MB but the total
			including the workfiles was 2.2GB. On _my_ upload
			speed, that will take between 40 minutes and an
			hour to upload.  So, if you use these scripts,
			I recommend that you produce a short video as a
			test.

video-single.sh		symlink to video-clip.sh, processes one input file
			to create an mkv output file of "final" quality (as
			in video-merge.sh, below) with aac audio.

video-slide.sh		convert a png to an mkv file.  The resulting
			files seem to be 67ms longer than intended, but
			both streams have the same length.  Optionally,
			fade the video in/out.

	Those scripts read parameters in the form name="value".  If you are
	silly enough to supply the same parameter twice, the latter will be
	used, except when setting the expected number of frames.

video-merge.sh		specify output="filename", optionally title="My Title",
			 and a series of input files which are to be processed
			 in order.  They will be concatenated in ffmpeg - that
			involves remuxing, and the output quality is slightly
			reduced, to get less-huge files.  The resulting file is
			still very big.

video-summary.sh	Produce a summary of a file, such as what streams
			it contains (my scripts assume one video and one audio),
			duration, frame rate (calculated if ffprobe returns
			'N/A').

 LICENSE:

 If there is anything interesting in my scripts, I probably found it via google.
My original intention was to mark these as Public Domain.  But in some countries
there are apparently issues with that, so you may use these scripts under the
terms of the wtfpl.

Ken Moffat

About

wrappers for ffmpeg, to simplify creating youtube videos from a series of mov files.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages