This shows you the differences between two versions of the page.
Previous revisionNext 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 " | ||
+ | </ | ||
+ | |||
+ | trims a movie called '' | ||
+ | |||
+ | ====== Trimming a Movie ====== | ||
+ | |||
+ | The following example: | ||
+ | <code bash> | ||
+ | ffmpeg -i example.mov -ss 00:00:02 -t 00:00:28 result.mov | ||
+ | </ | ||
+ | cuts a slice starting from '' | ||
+ | |||
+ | ====== 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 '' | ||
+ | |||
+ | Input file: | ||
+ | < | ||
+ | ./TIPWCD001 - Various Artists - Halluci-Nations (1999)/ | ||
+ | </ | ||
+ | |||
+ | Output file: | ||
+ | < | ||
+ | ./TIPWCD001 - Various Artists - Halluci-Nations (1999)/ | ||
+ | </ | ||
+ | |||
+ | <code bash> | ||
+ | find . -name " | ||
+ | </ | ||
+ | |||
+ | 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 | ||
+ | </ | ||
+ | takes as input '' | ||
+ | |||
+ | It appears that scaling the movie down to a smaller resolution increases the filesize instead of lowering it. | ||
+ | |||
+ | ====== Convert Movies to iPad Format ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code bash> | ||
+ | OLDIFS=$IFS | ||
+ | IFS=$(echo -en " | ||
+ | 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/ | ||
+ | done | ||
+ | IFS=$OLDIFS | ||
+ | </ | ||
+ | |||
+ | ====== Scale Movies ====== | ||
+ | |||
+ | Using '' | ||
+ | |||
+ | <code bash> | ||
+ | ffmpeg -i input.mp4 -vf scale=iw/ | ||
+ | </ | ||
+ | |||
+ | where '' | ||
+ | |||
+ | Sometimes, this will not work because the width and height is not divisible by '' | ||
+ | <code bash> | ||
+ | ffmpeg -i input.mp4 -vf " | ||
+ | </ | ||
+ | |||
+ | which will scale the width to '' | ||
+ | |||
+ | ====== Speed-up Movies ====== | ||
+ | |||
+ | Using the '' | ||
+ | |||
+ | <code bash> | ||
+ | ffmpeg -i input.mp4 -vf setpts=0.5*PTS output.mp4 | ||
+ | </ | ||
+ | |||
+ | 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:// | ||
+ | |||
+ | To use, save the file as '' | ||
+ | <code bash> | ||
+ | chmod +x ffmpeg-split.py | ||
+ | </ | ||
+ | |||
+ | in order to make it executable. | ||
+ | |||
+ | Then, clips can be split using the command: | ||
+ | <code bash> | ||
+ | ./ | ||
+ | </ | ||
+ | |||
+ | where '' | ||
+ | |||
+ | |||
+ | |||
+ | <code python> | ||
+ | ########################################################################### | ||
+ | ## Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 ## | ||
+ | ## Please see: http:// | ||
+ | ## rights of fair usage, the disclaimer and warranty conditions. | ||
+ | ########################################################################### | ||
+ | # Original version can be found at Antarctic Nest of Icephoenix at: # | ||
+ | # http:// | ||
+ | # -equal-chunks-with-ffmpeg-and-python/ | ||
+ | ########################################################################### | ||
+ | # | ||
+ | |||
+ | import subprocess | ||
+ | import re | ||
+ | import math | ||
+ | from optparse import OptionParser | ||
+ | |||
+ | length_regexp = ' | ||
+ | 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(" | ||
+ | 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: " | ||
+ | else: | ||
+ | print " | ||
+ | raise SystemExit | ||
+ | |||
+ | split_count = int(math.ceil(clip_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 = " | ||
+ | for n in range(0, split_count): | ||
+ | split_str = "" | ||
+ | if n == 0: | ||
+ | split_start = 0 | ||
+ | else: | ||
+ | split_start = split_length * n | ||
+ | | ||
+ | split_str += " -ss " | ||
+ | " '" | ||
+ | "'" | ||
+ | print "About to run: " | ||
+ | output = subprocess.Popen(split_cmd+split_str, | ||
+ | | ||
+ | |||
+ | |||
+ | def parse_options(): | ||
+ | parser = OptionParser() | ||
+ | | ||
+ | parser.add_option(" | ||
+ | dest = " | ||
+ | help = "file to split, for example sample.avi", | ||
+ | type = " | ||
+ | action = " | ||
+ | ) | ||
+ | parser.add_option(" | ||
+ | dest = " | ||
+ | help = "split or chunk size in seconds, for example 10", | ||
+ | type = " | ||
+ | action = " | ||
+ | ) | ||
+ | (options, args) = parser.parse_args() | ||
+ | | ||
+ | if options.filename and options.split_size: | ||
+ | |||
+ | return (options.filename, | ||
+ | |||
+ | else: | ||
+ | parser.print_help() | ||
+ | raise SystemExit | ||
+ | |||
+ | if __name__ == ' | ||
+ | |||
+ | try: | ||
+ | main() | ||
+ | except Exception, e: | ||
+ | print " | ||
+ | print str(e) | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | One of the important changes from the original is that the '' | ||
+ | |||
+ | ====== Preparing Video for Web Serving ====== | ||
+ | |||
+ | The most compatible video format up to date is MP4: | ||
+ | |||
+ | <code bash> | ||
+ | ffmpeg -i input.mp4 -profile:v ' | ||
+ | -r 25 -crf 18 -vcodec libx264 -vb 448k \ | ||
+ | -acodec libfdk_aac -ar 44100 -ac 2 -b:a 96k \ | ||
+ | -movflags faststart -strict experimental output.mp4 | ||
+ | </ | ||
+ | |||
+ | the command uses '' | ||
+ | |||
+ | ====== 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 '' | ||
+ | <code bash> | ||
+ | ffmpeg -i input.avi -acodec libfdk_aac -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 output.mp4 | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | ====== Trim Metadata ====== | ||
+ | |||
+ | Trimming metadata contained in a media-file can be accomplished with '' | ||
+ | |||
+ | ====== Strip Audio from Video Clip ====== | ||
+ | |||
+ | <code bash> | ||
+ | ffmpeg -i input.mp4 -c copy -an output.mp4 | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Install a Full FFmpeg Distribution on Debian ====== | ||
+ | |||
+ | [[http:// | ||
+ | < | ||
+ | deb http:// | ||
+ | deb-src http:// | ||
+ | </ | ||
+ | |||
+ | and then issue: | ||
+ | <code bash> | ||
+ | apt-get update | ||
+ | </ | ||
+ | |||
+ | to update the package list; followed by: | ||
+ | <code bash> | ||
+ | apt-get install deb-multimedia-keyring | ||
+ | </ | ||
+ | |||
+ | to install the keyring for the repo and then update with '' | ||
+ | <code bash> | ||
+ | aptitude update | ||
+ | </ | ||
+ | |||
+ | Finally, uninstall any existing '' | ||
+ | <code bash> | ||
+ | aptitude purge ffmpeg | ||
+ | </ | ||
+ | |||
+ | and install the new '' | ||
+ | <code bash> | ||
+ | aptitude install ffmpeg x264 | ||
+ | </ | ||
+ | |||
+ | ====== 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 '' | ||
+ | <code bash> | ||
+ | ffmpeg -i anim.mp4 anim.gif | ||
+ | </ | ||
+ | where: | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | Unfortunately, | ||
+ | |||
+ | 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 | ||
+ | </ | ||
+ | where: | ||
+ | * '' | ||
+ | |||
+ | 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 " | ||
+ | </ | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | Achieving an acceptable GIF is a games of push and pull between the value of '' | ||
+ | |||
+ | Other very useful filters are: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | In one pass: | ||
+ | <code bash> | ||
+ | ffmpeg -i a.gif -vf " | ||
+ | </ | ||
+ | the actions performed will be: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' |