Friday, August 30, 2019

A guide to ffmpeg
12. Increase/Reduce Video Playback Speed
To increase video play back speed, run this command. The -vf option sets the video filters that helps to adjust the speed.

$ ffmpeg -i video.mpg -vf "setpts=0.5*PTS" highspeed.mpg

ou can also reduce video speed as follows:

$ ffmpeg -i video.mpg -vf "setpts=4.0*PTS" lowerspeed.mpg -hide_banner
FFmpeg to the rescue! You can select the codecs needed by using the -c flag.
This flag lets you set the different codec to use for each stream. For example, to set the audio stream to be Vorbis, you would use the following command:
ffmpeg -i input.mp3 -c:a libvorbis output.ogg
The same can be done to change the video as well as the audio stream:
ffmpeg -i input.mp4 -c:v vp9 -c:a libvorbis output.mkv
This will make a Matroska container with a VP9 video stream and a Vorbis audio stream, essentially the same as the WebM we made earlier.
The command ffmpeg -codecs will print every codec FFmpeg knows about.

Changing a single stream

More often than you'd like, the file you have is partially correct with only a single stream in the wrong format. It can be very time consuming to re-encode the correct stream. FFmpeg can help with this situation:
ffmpeg -i input.webm -c:v copy -c:a flac output.mkv
This command copies the video stream from input.webm into output.mkv and encodes the Vorbis audio stream into a FLAC. The -c flag is really powerful.

Changing a container

The prior example can be applied to both the audio and video streams, allowing you to convert from one container format to another without having to do any additional stream encoding:
ffmpeg -i input.webm -c:av copy output.mkv
Change the quality
ffmpeg -i input.webm -c:a copy -c:v vp9 -b:v 1M output.mkv
This will copy the audio (-c:a copy) from input.webm and convert the video to a VP9 codec (-c:v vp9) with a bit rate of 1M/s (-b:v), all bundled up in a Matroska container (output.mkv).
Another way we can impact quality is to adjust the frame rate of the video using the -roption:
ffmpeg -i input.webm -c:a copy -c:v vp9 -r 30 output.mkv
This creates a new Matroska with the audio stream copied over and the video stream's frame rate forced to 30 frames per second, instead of using the frame rate from the input (-r 30).
You can also adjust the dimensions of your video using FFmpeg. The simplest way is to use a predetermined video size:
ffmpeg -i input.mkv -c:a copy -s hd720 output.mkv
This modifies the video to 1280x720 in the output, but you can set the width and height manually if you want:
ffmpeg -i input.mkv -c:a copy -s 1280x720 output.mkv
This produces the exact same output as the earlier command. If you want to set custom sizes in FFmpeg, please remember that the width parameter (1280) comes before height (720).

Get File Information From a Video File
ffmpeg -i video.avi

Convert Images To a Video Sequence
This command will transform all the images from the current directory (named image1.jpg, image2.jpg, etc…) to a video file named video.mpg.

ffmpeg -f image2 -i image%d.jpg video.mpg
Convert a Video to X Images
This command will generate imagess named image1.jpg, image2.jpg, etc, from a given video file. The following image formats are available: PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI.

ffmpeg -i video.mpg image%d.jpg
Crop a Video File
Cropping is a very common operation in video editing. FFmpeg provides a crop filter for this specific purpose:

ffmpeg -i input.mp4 -filter:v "crop=out_w:out_h:x:y" output.mp4
The options are as follows:

out_w is the width of the output rectangle
out_h is the height of the output rectangle
x and y specify the top left corner of the output rectangle
output.mp4 is the output file
Resize a Video
Using the -vf scale filter, it is possible to resize videos to a desired size:

ffmpeg -i input.avi -vf scale=320:240 output.avi
The same works with images as well:

ffmpeg -i input.jpg -vf scale=320:240 output_320x240.png
Extract a Portion of a Video
Another very common operation on video files is to extract a specific portion of a given video. This can be done super easily:

ffmpeg -ss 00:00:30 -i orginalfile.mpg -t 00:00:05 -vcodec copy -acodec copy newfile.mpg
In the example above, we are cutting out a part starting at 00:00:30 into the original file with a 5 seconds length. -ss indicates the starting time, and -t indicates the duration.

Encode a Video Sequence for the iPod/iPhone
You can easily convert a video for iPhones and older iPods using this command:

ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
Explanations :

Source : source_video.avi
Audio codec : aac
Audio bitrate : 128kb/s
Video codec : mpeg4
Video bitrate : 1200kb/s
Video size : 320px par 180px
Generated video : final_video.mp4

Extract Sound From a Video, And Save It in Mp3 Format
Creating an audio file from a video is an easy task:

ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192k -f mp3 sound.mp3
Explanations :

Source video : source_video.avi
Audio bitrate : 192kb/s
output: mp3 format
Generated sound : sound.mp3
Convert a Wav File to Mp3
FFmpeg isn’t only for videos, there’s a lot you can do with audio files as well. This example will convert a .wav file to mp3 format.

ffmpeg -i input_sound.avi -vn -ar 44100 -ac 2 -ab 192k -f mp3 output_sound.mp3

Image Overlay on a Video
Let’s finish this round-up with an advanced command. Here we are applying an overlay image to an existing video:

ffmpeg -i input.mp4 -i image.png -filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy output.mp4
Some explanations:

overlay=25:25: The image will be positioned 25px to the right and 25px down, originating from the top left corner (0:0).
enable='between(t,0,20)': The overlay image will be shown from 00:00:00 to 00:00:20
Youtube-dl is a nifty little tool you can use to grab videos from YouTube and several other video-streaming services. It's super straightforward to use:
As a general rule, options are applied to the next specified file. Therefore, order is important, and you can have the same option on the command line multiple times. Each occurrence is then applied to the next input or output file. Exceptions from this rule are the global options (e.g. verbosity level), which should be specified first.
Do not mix input and output files – first specify all input files, then all output files. Also do not mix options which belong to different files. All options apply ONLY to the next input or output file and are reset between files.
  • To set the video bitrate of the output file to 64 kbit/s:
    ffmpeg -i input.avi -b:v 64k -bufsize 64k output.avi
  • To force the frame rate of the output file to 24 fps:
    ffmpeg -i input.avi -r 24 output.avi
  • To force the frame rate of the input file (valid for raw formats only) to 1 fps and the frame rate of the output file to 24 fps:
    ffmpeg -r 1 -i input.m2v -r 24 output.avi
Calculate the bitrate you need by dividing 1 GB by the video length in seconds. So, for a video of length 16:40 (1000 seconds), use a bitrate of 1000000 bytes/sec:
ffmpeg -i input.mp4 -b 1000000 output.mp4
Additional options that might be worth considering is setting the Constant Rate Factor, which lowers the average bit rate, but retains better quality. Vary the CRF between around 18 and 24 — the lower, the higher the bitrate.
ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4

Second command, using -crf 24 took a 255.3MB video I had and reduced it to 72.7MB without lowering the quality noticeably.
brew install ffmpeg
for f in *.mkv;do ffmpeg -i "$f" -c:v copy -c:a aac -b:a 256k -strict -2 "${f%mkv}mp4";done
for f in *.avi;do ffmpeg -i "$f"  -strict -2 "${f%avi}mp4";done
The command -strict -2 is necessitated by the AAC codec which is experimental, but works (libaac), if you add those two parameters. The output file is high-quality by default.
ffmpeg -i input.avi -strict -2 output.mp4

Wednesday, August 28, 2019

Autocomplete in bash
 and compgen builtins make it possible for tab completion to recognize partial parameters and options to commands. In a very simple case, we can use complete from the command-line to specify a short list of acceptable parameters.
bash$ touch sample_command
bash$ touch file1.txt file2.txt file2.doc file30.txt file4.zzz
bash$ chmod +x sample_command
bash$ complete -f -X '!*.txt' sample_command

bash$ ./sample[Tab][Tab]
file1.txt   file2.txt   file30.txt
The -f option to complete specifies filenames, and -X the filter pattern.
For anything more complex, we could write a script that specifies a list of acceptable command-line parameters. The compgen builtin expands a list of arguments to generate completion matches.
Let us take a modified version of the script as an example command. This script accepts a number of command-line parameters, preceded by either a single or double dash. And here is the corresponding completion script, by convention given a filename corresponding to its associated command.
Example J-1. Completion script for
# file: UseGetOpt-2
# parameter-completion

_UseGetOpt-2 ()   #  By convention, the function name
{                 #+ starts with an underscore.
  local cur
  # Pointer to current completion word.
  # By convention, it's named "cur" but this isn't strictly necessary.

  COMPREPLY=()   # Array variable storing the possible completions.

  case "$cur" in
    COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
                               --file --log --test --help --' -- $cur ) );;
#   Generate the completion matches and load them into $COMPREPLY array.
#   xx) May add more cases here.
#   yy)
#   zz)

  return 0

complete -F _UseGetOpt-2 -o filenames ./
#        ^^ ^^^^^^^^^^^^  Invokes the function _UseGetOpt-2.
The command that setups autocompletion is complete. When giving it a list, pass them in as an augument to the -Woption:
complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" wait-for-host
I’m capturing the output of the command with $() and wrapping it in double quotes. The last argument is the name of the command (which can be also be a function or alias) that will use this autocompletion. Now we get this:
~ wait-for-host www<TAB>  
~ wait-for-host www
That works fine, but it’s static and applies only to one command. Instead you can create a reusable function.
_known_hosts() {
    local know_hosts cur
    known_hosts=$(cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\[")


    COMPREPLY=( $(compgen -W "$known_hosts" -- ${cur}) )
    return 0
BASH auto completion functions are powerful things, but for today we’re keeping it simple. First we build a list of options as before and store it in $known_hosts. Second we get the current word, the command argument, which is be tab completed. Finally, we pass that list and that word into compgen which is BASH’s internal matcher. compgen has some powerful features, but in this case it’s just going to return a list of hosts in $known_hosts that start with the word we hit tab on.
Then we tell the completion that we are using a function by giving it the -f option, along with the function name, instead of -W:
complete -F _known_hosts wait-for-host
And you can use the _known_hosts function for other commands as well:
complete -F _known_hosts ssh
This is a good exercise in understanding autocompletion, but it’s pretty basic. Fortunately, people have already done all of the hard work in the bash-completion project. This ships by default with many Linux distros. On the Mac:
brew install bash-completion
The add:
if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
For example, given the following hosts(5) file in place at /etc/hosts:      localhost www mx rad
An appropriate call to compgen would yield this output:
$ compgen -A hostname

We could then use this to complete hostnames for network diagnostic tools like ping(8):
$ complete -A hostname ping
There’s a simple way to make host completion much more useful by defining the HOSTFILE variable in ~/.bashrc to point to any other file containing a list of hostnames. You could, for example, create a simple file ~/.hosts in your home directory, and then include this in your ~/.bashrc:
# Use a private mock hosts(5) file for completion
This setup allows you to set hostname completion as the default method for all sorts of network-poking tools, falling back on the usual filename completion if nothing matches with -o default:
$ complete -A hostname -o default curl dig host netcat ping telnet


Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts