Differences

This shows you the differences between two versions of the page.


Previous revision
Next revision
fuss:ffmpeg [2017/12/05 07:54] – [Convert Video to GIF Animation] office
Line 1: Line 1:
 +====== Terminology ======
  
 +Cropping and cutting have the same meaning but movie processing software seems to distinguish between the two:
 +
 +  * cropping a movie means to slice the visual canvas.
 +  * cutting a movie means to slice out a sequence of it.
 +
 +====== Crop a Movie ======
 +
 +The following command:
 +<code bash>
 +ffmpeg -i example.mov -filter:v "crop=w:h:x:y" result.mov
 +</code>
 +
 +trims a movie called ''example.mov'' and outputs the result in ''result.mov''. The trimming is performed by selecting a rectangle, ''w'' pixels wide by ''h'' pixel high, starting from the screen coordinates ''x'' and ''y'' from the top-left corner of the screen.
 +
 +====== Trimming a Movie ======
 +
 +The following example:
 +<code bash>
 +ffmpeg -i example.mov -ss 00:00:02 -t 00:00:28 result.mov
 +</code>
 +cuts a slice starting from ''2s'' into the movie and cuts out ''28s'' starting from that point. 
 +
 +====== Convert FLAC to MP3 Recursively ======
 +
 +The following command goes through the directories starting from where the command was issued and converts FLAC files to MP3 files. The one-liner requires ''ffmpeg'' and ''lame'' to be installed.
 +
 +Input file:
 +<code>
 +./TIPWCD001 - Various Artists - Halluci-Nations (1999)/06_Process_-_Blue_Moonies.flac
 +</code>
 +
 +Output file:
 +<code>
 +./TIPWCD001 - Various Artists - Halluci-Nations (1999)/06_Process_-_Blue_Moonies.mp3
 +</code>
 +
 +<code bash>
 +find . -name "*.flac" -exec sh -c 'ffmpeg -y -i "{}" -acodec libmp3lame -ab 320k "${0/flac/mp3}"' {} \;
 +</code>
 +
 +Note that this preserves the FLAC files and does not delete them.
 +
 +====== Lowering the Quality of Movies ======
 +
 +The following command:
 +<code bash>
 +ffmpeg -i example.mov -r 24 -b:v 256k result.mp4
 +</code>
 +takes as input ''example.mov'' and lowers the framerate to ''24fps'' and sets the video bitrate to ''256k''.
 +
 +It appears that scaling the movie down to a smaller resolution increases the filesize instead of lowering it.
 +
 +====== Convert Movies to iPad Format ======
 +
 +The ''IFS'' changes is required in order to process file names with spaces.
 +
 +<code bash>
 +OLDIFS=$IFS
 +IFS=$(echo -en "\n\b")
 +for i in *.avi; do 
 +  ffmpeg -i $i -acodec aac -ac 2 -vcodec libx264 -strict experimental -threads 24 -profile:v baseline -preset ultrafast -level 30 -ab 160k -b 1200k -f mp4 ${i/avi/mp4}
 +done
 +IFS=$OLDIFS
 +</code>
 +
 +====== Scale Movies ======
 +
 +Using ''-vf'' for ''ffmpeg >= 0.9'':
 +
 +<code bash>
 +ffmpeg -i input.mp4 -vf scale=iw/4:-1 output.mp4
 +</code>
 +
 +where ''iw'' stands for ''input width'' which is then divided by ''4''. The ''-1'' indicates that ''ffmpeg'' should preserve the ration and scale the height accordingly.
 +
 +Sometimes, this will not work because the width and height is not divisible by ''2''. To avoid that, you can issue:
 +<code bash>
 +ffmpeg -i input.mp4 -vf "scale=720:trunc(ow/a/2)*2" output.mp4
 +</code>
 +
 +which will scale the width to ''720'' and adjust the height according to that value.
 +
 +====== Speed-up Movies ======
 +
 +Using the ''setps'' video filter:
 +
 +<code bash>
 +ffmpeg -i input.mp4 -vf setpts=0.5*PTS output.mp4
 +</code>
 +
 +will double the speed of the movie in the output file.
 +
 +====== Split Clips into Equal Segments of a Given Size ======
 +
 +The following code is an adaptation from [[http://icephoenix.us/notes-for-myself/auto-splitting-video-file-in-equal-chunks-with-ffmpeg-and-python/|Antarctic Nest of Icephoenix]] and will split clips into equal segments of a given size.
 +
 +To use, save the file as ''ffmpeg-split.py'' and then run:
 +<code bash>
 +chmod +x ffmpeg-split.py
 +</code>
 +
 +in order to make it executable.
 +
 +Then, clips can be split using the command:
 +<code bash>
 +./ffmpeg-split.py -f someclip.wav -s N
 +</code>
 +
 +where ''N'' represents the number of seconds that each segment will have.
 +
 +
 +
 +<code python>
 +###########################################################################
 +##  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      ##
 +##  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  ##
 +##  rights of fair usage, the disclaimer and warranty conditions.        ##
 +###########################################################################
 +# Original version can be found at Antarctic Nest of Icephoenix at:       #
 +# http://icephoenix.us/notes-for-myself/auto-splitting-video-file-in-      #
 +# -equal-chunks-with-ffmpeg-and-python/                                   #
 +###########################################################################
 +#!/usr/bin/env python
 +
 +import subprocess
 +import re
 +import math
 +from optparse import OptionParser
 +
 +length_regexp = 'Duration: (\d{2}):(\d{2}):(\d{2})\.\d+,'
 +re_length = re.compile(length_regexp)
 +
 +def main():
 +
 +    (filename, split_length) = parse_options()
 +    if split_length <= 0:
 +        print "Split length can't be 0"
 +        raise SystemExit
 +
 +    output = subprocess.Popen("ffmpeg -i '"+filename+"' 2>&1 | grep 'Duration'", 
 +                            shell = True,
 +                            stdout = subprocess.PIPE
 +                            ).stdout.read()
 +    print output
 +    matches = re_length.search(output)
 +    if matches:
 +        clip_length = int(matches.group(1)) * 3600 + \
 +                        int(matches.group(2)) * 60 + \
 +                        int(matches.group(3))
 +        print "Clip length in seconds: "+str(clip_length)
 +    else:
 +        print "Can't determine clip length."
 +        raise SystemExit
 +
 +    split_count = int(math.ceil(clip_length/float(split_length)))
 +    if(split_count == 1):
 +        print "Clip length is less then the target split length."
 +        raise SystemExit
 +
 +    # -acodec copy and -vcodec copy will not give accurate results so do not use them
 +    split_cmd = "ffmpeg -i '"+filename+"' "
 +    for n in range(0, split_count):
 +        split_str = ""
 +        if n == 0:
 +            split_start = 0
 +        else:
 +            split_start = split_length * n
 +        
 +        split_str += " -ss "+str(split_start)+" -t "+str(split_length) + \
 +                    " '"+filename[:-4] + "-" + str(n) + "." + filename[-3:] + \
 +                    "'"
 +        print "About to run: "+split_cmd+split_str
 +        output = subprocess.Popen(split_cmd+split_str, shell = True, stdout =
 +                               subprocess.PIPE).stdout.read()
 +
 +
 +def parse_options():
 +    parser = OptionParser()    
 +    
 +    parser.add_option("-f", "--file",
 +                        dest = "filename",
 +                        help = "file to split, for example sample.avi",
 +                        type = "string",
 +                        action = "store"
 +                        )
 +    parser.add_option("-s", "--split-size",
 +                        dest = "split_size",
 +                        help = "split or chunk size in seconds, for example 10",
 +                        type = "int",
 +                        action = "store"
 +                        )
 +    (options, args) = parser.parse_args()
 +    
 +    if options.filename and options.split_size:
 +
 +        return (options.filename, options.split_size)
 +
 +    else:
 +        parser.print_help()
 +        raise SystemExit
 +
 +if __name__ == '__main__':
 +
 +    try: 
 +        main()
 +    except Exception, e:
 +        print "Exception occured running main():"
 +        print str(e)
 +
 +
 +</code>
 +
 +One of the important changes from the original is that the ''-acodec'' and ''-vcodec'' parameters are not used which guarantees an accurate split down to the frames. By omitting these parameters, ''ffmpeg'' is allowed to re-encode which guarantees that clip lengths are accurate. This is due to the fact that all the frames between key-frames in a clip are a function of those key-frames and if we were to cut between those key-frames then there would not be any information available to decode the clip.
 +
 +====== Preparing Video for Web Serving ======
 +
 +The most compatible video format up to date is MP4:
 +
 +<code bash>
 +ffmpeg -i input.mp4 -profile:v 'baseline' -pix_fmt yuv420p \
 +    -r 25 -crf 18 -vcodec libx264 -vb 448k \
 +    -acodec libfdk_aac -ar 44100 -ac 2 -b:a 96k \
 +    -movflags faststart -strict experimental output.mp4
 +</code>
 +
 +the command uses ''faststart'' that moves the ''moov'' metadata to the beginning of the file so the file can be played while being downloaded.
 +
 +====== Converting FRAPs Videos ======
 +
 +FRAPs captures videos in AVI format and if you want to use them on OSX, they will have to be converted first using ''ffmpeg'' (which can be installed using homebrew). To convert the video, issue:
 +<code bash>
 +ffmpeg -i input.avi -acodec libfdk_aac -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 output.mp4
 +</code>
 +
 +''libfdk_aac'' is the best encoder at the time of writing but it may not be recognised depending on how your ''ffmpeg'' was compiled - if that happens, try ''libfaac'' or ''aac''.
 +
 +====== Trim Metadata ======
 +
 +Trimming metadata contained in a media-file can be accomplished with ''ffmpeg'' by providing the extra switch ''-map_metadata -1''. This particularly works well with MP3 files that have embedded metadata when creating them under OS X.
 +
 +====== Strip Audio from Video Clip ======
 +
 +<code bash>
 +ffmpeg -i input.mp4 -c copy -an output.mp4
 +</code>
 +
 +
 +====== Install a Full FFmpeg Distribution on Debian ======
 +
 +[[http://www.deb-multimedia.org|deb-multimedia]] packages a full ''ffpmeg'' with all plugins. Add the following lines to ''/etc/apt/sources.list'':
 +<code>
 +deb http://www.deb-multimedia.org stable main non-free
 +deb-src http://www.deb-multimedia.org stable main non-free
 +</code>
 +
 +and then issue:
 +<code bash>
 +apt-get update
 +</code>
 +
 +to update the package list; followed by:
 +<code bash>
 +apt-get install deb-multimedia-keyring
 +</code>
 +
 +to install the keyring for the repo and then update with ''aptitude'':
 +<code bash>
 +aptitude update
 +</code>
 +
 +Finally, uninstall any existing ''ffmpeg'':
 +<code bash>
 +aptitude purge ffmpeg
 +</code>
 +
 +and install the new ''ffmpeg'' with:
 +<code bash>
 +aptitude install ffmpeg x264
 +</code>
 +
 +====== Convert Video to GIF Animation ======
 +
 +A typical usage case of FFMpeg is to convert a video file into a GIF animation. Assuming an input video named ''anim.mp4'', the conversion can be performed rather simply by issuing:
 +<code bash>
 +ffmpeg -i anim.mp4 anim.gif
 +</code>
 +where:
 +  * ''anim.mp4'' is the input video,
 +  * ''anim.gif'' is the resulting GIF.
 +
 +Unfortunately, the generate GIF file will be very large and might appear very slow. This is mostly due to ffmpeg trying to maintain the framerate such that it will generate as many frames as necessary.
 +
 +The first step is to dump all frames of the video file to a GIF file:
 +<code bash>
 +ffmpeg -i anim.mp4 -r 1 dump.gif
 +</code>
 +where:
 +  * ''-r 1'' will lower the framerate to 1 frame per second
 +
 +Now, the resulting file should be very large, so to reduce the size, the obtained file will be converted to another GIF file by lowering the framerate and specifying the amount of frames to skip:
 +<code bash>
 +ffmpeg -i dump.gif -vf "setpts=0.25*PTS" -r 7 final.gif
 +</code>
 +  * ''setpts=0.25*PTS'' will set the speed as $4$ times the current speed,
 +  * ''-r 1'' will drop or duplicate frames to achieve $7$ frames per second
 +
 +Achieving an acceptable GIF is a games of push and pull between the value of ''-r'' and the value of ''setpts''.
 +
 +Other very useful filters are:
 +  * ''decimate'' - will merge / drop duplicate frames hence lowering the GIF size,
 +  * ''deflicker'' - will attempt to stabilize the video,
 +  * ''scale'' - will scale the movie (down) and hence can be used to lower the file size
 +
 +In one pass:
 +<code bash>
 +ffmpeg -i a.gif -vf "deflicker, decimate=cycle=4, fps=8, setpts=0.35*PTS, scale=360:trunc(ow/a/2)*2" b.gif
 +</code>
 +the actions performed will be:
 +  * ''deflicker'' - attempt to deflicker / stabilize the video,
 +  * ''decimate=cycle=4'' - crop duplicate frames at a rate of $1$ duplicate frame out of $4$,
 +  * ''fps=8'' - attempt to set the framerate to $8$ frames per second,
 +  * ''setpts=0.35*PTS'' - speed up the movie by $0.35$ of the original speed.

fuss/ffmpeg.txt · Last modified: 2024/01/14 23:08 by office

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.