FFmpeg - 2. deo

Share on:




Minimal example: transcode from MP3 to WMA:

1ffmpeg -i input.mp3 output.wma
bash

You can get the list of supported formats with:

1ffmpeg -formats
bash

You can get the list of installed codecs with:

1ffmpeg -codecs
bash

Convert WAV to MP3, mix down to mono (use 1 audio channel), set bit rate to 64 kbps and sample rate to 22050 Hz:

1ffmpeg -i input.wav -ac 1 -ab 64000 -ar 22050 output.mp3
bash


Convert any MP3 file to WAV 16khz mono 16bit:

1ffmpeg -i 111.mp3 -acodec pcm_s16le -ac 1 -ar 16000 out.wav

Convert any MP3 file to WAV 20khz mono 16bit for ADDAC WAV Player:

1ffmpeg -i 111.mp3 -acodec pcm_s16le -ac 1 -ar 22050 out.wav
bash

1for i in *.mp3; do ffmpeg -i "$i" -acodec pcm_s16le -ac 1 -ar 22050 "${i%.mp3}-encoded.wav"; done
bash

Picking the 30 seconds fragment at an offset of 1 minute:

In seconds:

1ffmpeg -i input.mp3 -ss 60 -t 30 output.wav
bash

In HH:MM:SS format:

1ffmpeg -i input.mp3 -ss 0:01:00 -t 0:00:30 output.wav
bash

Split an audio stream at specified segment rate (e.g. 3 seconds)

1ffmpeg -i somefile.mp3 -f segment -segment_time 3 -c copy out%03d.mp3
bash


1ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac 
bash
  • vn is no video.
  • acodec copy says use the same audio stream that's already in there.
1ffmpeg -i video.mp4 -f mp3 -ab 192000 -vn music.mp3
bash
  • The -i option in the above command is simple: it is the path to the input file.
  • The second option -f mp3 tells ffmpeg that the ouput is in mp3 format.
  • The third option i.e -ab 192000 tells ffmpeg that we want the output to be encoded at 192Kbps and -vn tells ffmpeg that we dont want video.
  • The last param is the name of the output file.



1ffmpeg -i INPUT.mp4 -i AUDIO.wav -shortest -c:v copy -c:a aac -b:a 256k OUTPUT.mp4
bash

strip audio stream away from video

1ffmpeg -i INPUT.mp4 -codec copy -an OUTPUT.mp4
bash

combine the two streams together (new audio with originally exisiting video)

1ffmpeg -i 36.MOV -i 36.wav -map 0:v -map 1:a -c copy -y 36-encoded.mov
bash

or add an offset to audio

1ffmpeg -i 36.MOV -itsoffset -0.25 -i 36.wav -map 0:v -map 1:a -c copy -y 36-encoded.mov
bash


You say you want to "extract audio from them (mp3 or ogg)".
But what if the audio in the mp4 file is not one of those? you'd have to transcode anyway.
So why not leave the audio format detection up to ffmpeg?

To convert one file:

1ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg 
bash

To convert many files:

1for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done 
bash

You can of course select any ffmpeg parameters for audio encoding that you like, to set things like bitrate and so on.

Use -acodec libmp3lame and change the extension from .ogg to .mp3 for mp3 encoding.

If what you want is to really extract the audio, you can simply "copy" the audio track to a file using -acodec copy. Of course, the main difference is that transcoding is slow and cpu-intensive, while copying is really quick as you're just moving bytes from one file to another. Here's how to copy just the audio track (assuming it's in mp3 format):

1ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3 
bash

Note that in this case, the audiofile format has to be consistent with what the container has (i.e. if the audio is AAC format, you have to say audiofile.aac). You can use the ffprobe command to see which formats you have, this may provide some information:

1for file in *; do ffprobe $file 2>&1 |grep Audio; done 
bash

A possible way to automatically parse the audio codec and name the audio file accordingly would be:

1for file in *mp4 *avi; do ffmpeg -i "$file" -vn -acodec copy "$file".`ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'`; done
bash

Note that this command uses sed to parse output from ffprobe for each file, it assumes a 3-letter >audio codec name (e.g. mp3, ogg, aac) and will break with anything different.


Encoding multiple files

You can use a Bash "for loop" to encode all files in a directory:

1mkdir newfiles
2for f in *.m4a; do ffmpeg -i "$f" -codec:v copy -codec:a libmp3lame -q:a 2 newfiles/"${f%.m4a}.mp3"; done
bash

1ffmpeg -i input.m4a -acodec libmp3lame -ab 128k output.mp3
bash

m4a to mp3 conversion with ffmpeg and lame


A batch file version of the same command would be:

1for f in *.m4a; do ffmpeg -i "$f" -acodec libmp3lame -ab 256k "${f%.m4a}.mp3"; done
bash


  • vf [ss][filename][outputFileName]
    where vf is a custom bash script as follows:
1ffmpeg -ss $1 -i $2 -qmin 1 -q:v 1 -qscale:v 2 -frames:v 1 -huffman optimal $3.jpg
bash
  • ss offset = frame number divided by FPS of video = the decimal (in milliseconds) ffmpeg needs i.e. 130.5



concat demuxer

1$ cat mylist.txt
2file '/path/to/file1'
3file '/path/to/file2'
4file '/path/to/file3'
bash
1$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp
bash

1ffmpeg -i video.flv image%d.jpg
bash

1ffmpeg -f image2 -i image%d.jpg imagestovideo.mp4
2ffmpeg -i image-%03d.png -c:v libx264 -pix_fmt yuv420p test.mp4
3ffmpeg -r 1/5 -i image-%03d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p test.mp4
bash

1ffmpeg -loop 1 -i image.png -c:v libx264 -t 60 -pix_fmt yuv420p -vf scale=1920:1080 out.mp4
bash

1$ ffmpeg -framerate 30 -pattern_type glob -i '*.jpeg' -c:v libx264 -pix_fmt yuv420p gan-1.mov
bash

1$ ffmpeg -i image-%04d.jpg -c:v libx264 -pix_fmt yuv420p -vf "scale=max(1280\,a*720):max(1280\,720/a),crop=1280:720" test.mp4
bash

1$ ffmpeg -i image-%04d.jpg -c:v libx264 -pix_fmt yuv420p -vf "scale=720:-2" test.mp4
bash

1$ ffmpeg -i image-%04d.jpg -c:v libx264 -pix_fmt yuv420p -vf "scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih), pad=1280:720:(1280-iw*min(1280/iw\,720/ih))/2:(720-ih*min(1280/iw\,720/ih))/2" test.mp4
bash

1920 version:

1$ ffmpeg -i image-%04d.jpg -c:v libx264 -pix_fmt yuv420p -vf "scale=iw*min(1920/iw\,1080/ih):ih*min(1920/iw\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\,1080/ih))/2:(1080-ih*min(1920/iw\,1080/ih))/2" test.mp4
bash

1ffmpeg -i input.mov -vcodec libx264 -pix_fmt yuv420p output.mp4
bash

1ffmpeg -i audio.xxx -c:a flac audio.flac
bash

You can modify a video file directly without having to re-encode the video stream.
However the audio stream will have to be re-encoded.

Left channel to mono:

1ffmpeg -i video.mp4 -map_channel 0.1.0 -c:v copy mono.mp4
bash

Left channel to stereo:

1ffmpeg -i video.mp4 -map_channel 0.1.0 -map_channel 0.1.0 -c:v copy stereo.mp4
bash

If you want to use the right channel, write 0.1.1 instead of 0.1.0.


Here's a command line that will slice to 30 seconds without transcoding:

1ffmpeg -t 30 -i inputfile.mp3 -acodec copy outputfile.mp3
bash

Do you need to cut video with re-encoding or without re-encoding mode? You can try to following below command.
Synopsis: ffmpeg -i [input_file] -ss [start_seconds] -t [duration_seconds] [output_file]


Example:

1ffmpeg -i source.mp4 -ss 00:00:05 -t 00:00:10 -c copy cut_video.mp4
bash

Example:

1ffmpeg -i source.mp4 -ss 00:00:05 -t 00:00:10 -async 1 -strict -2 cut_video.mp4
bash

If you want to cut off section from the beginning, simply drop -t 00:00:10 from the command


Example:

1ffmpeg -i input.mov -vcodec libx264 -crf 24 output.mp4
bash

It reduced a 100mb video to 9mb.. Very little change in video quality.

Example:

1ffmpeg -i video.mov -vf eq=saturation=0 -s 640x480 -c:v libx264 -crf 24 output.mp4
bash

make a grayscale version and scale to 640x480


1ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 31 -b:v 1M output.webm
bash

more info


1ffmpeg -i file.mkv
bash

check for streams that you want (video/audio). be sure to convert/specify DTS 6 channel audio stream

1ffmpeg -i input.mkv -strict experimental -map 0:0 -map 0:1 -c:v copy -c:a:1 libmp3lame -b:a 192k -ac 6 output.mp4
bash

1ffmpeg -i source.mov -i watermark.png -filter_complex "overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2" output.mp4
bash

1ffmpeg -i input.mp4 -filter_complex "[0:v]reverse,fifo[r];[0:v][r] concat=n=2:v=1 [v]" -map "[v]" output.mp4
bash


more commands
http://www.catswhocode.com/blog/19-ffmpeg-commands-for-all-needs