I'm looking for a way to get only the lines that contains a specified word, in this case all lines that contains the word Stream from an output
I've tried;
streams=$(ffprobe -i "movie.mp4" | grep "Stream")
but that didn't get any results..
or do I need to output it to a file and then try to extract the lines I'm looking for?
#paulsm4 was spot on ... the output goes to STDERR.
streams=$(ffprobe -i "movie.mp4" |& grep "Stream")
Note the &
No need for grep. Just use ffprobe directly to get whatever info you need.
Output all info
ffprobe -loglevel error -show_format -show_streams input.mp4
Video info only
ffprobe -loglevel error -show_streams -select_streams v input.mp4
Audio info only
ffprobe -loglevel error -show_streams -select_streams a input.mp4
Width x height
See Getting video dimension / resolution / width x height from ffmpeg
Duration
See How to get video duration?
Format / codec
Is there a way to use ffmpeg to determine the encoding of a file before transcoding?
Using ffprobe to check audio-only files
Info on frames
See Get video frames information with ffmpeg
More info and examples
See FFmpeg Wiki: ffprobe
Related
I need to create multiple thumbnails (ex. 12) from a video at equal times using ffmpeg.
So for example if the video is 60 seconds - I need to extract a screenshot every 5 seconds.
Im using the following command to get the frame in the 5ths second.
ffmpeg -ss 5 -i video.webm -frames:v 1 -s 120x90 thumbnail.jpeg
Is there a way to get multiple thumbnails with one command?
Get duration (optional)
Get duration using ffprobe. This is an optional step but is helpful if you will be scripting or automating the next commands.
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
Example result:
60.000000
Output one frame every 5 seconds
Using the select filter:
ffmpeg -i input.mp4 -vf "select='not(mod(t,5))',setpts=N/FRAME_RATE/TB" output_%04d.jpg
or
ffmpeg -i input.mp4 -vf "select='not(mod(t,5))'" -vsync vfr output_%04d.jpg
Files will be named output_0001.jpg, output_0002.jpg, output_0003.jpg, etc. See image muxer documentation for more info and options.
To adjust JPEG quality see How can I extract a good quality JPEG image from a video with ffmpeg?
Output specific number of equally spaced frames
This will output 12 frames from a 60 second duration input:
ffmpeg -i input.mp4 -vf "select='not(mod(t,60/12))'" -vsync vfr output_%04d.jpg
You must manually enter the duration of the input (shown as 60 in the example above). See an automatic method immediately below.
Using ffprobe to automatically provide duration value
Bash example:
input=input.mp4; ffmpeg -i "$input" -vf "select='not(mod(t,$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $input)/12))'" -vsync vfr output_%04d.jpg
With scale filter
Example using the scale filter:
ffmpeg -i input.mp4 -vf "select='not(mod(t,60/12))',scale=120:-1" -vsync vfr output_%04d.jpg
$ffmpegPath = exec('which ffmpeg'); $ffprobePath = exec('which ffprobe');
$command = "$ffprobePath -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $input_video"; $video_duration = shell_exec($command);
$thumbnails_output = 'output%02d.png'; $command = "$ffmpegPath -i $input_video -vf fps=3/$video_duration $thumbnails_output";
shell_exec($command);
I am merging a few user-generated videos together with ffmpeg-concat and sometimes run into an audio sync issue. I figured that it fails when audio and video duration mismatch. E.g.:
ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 IMG_7679.mov
16.666016
ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 IMG_7679.mov
16.670998
Question is — how do make audio and video duration equal prior to concat, without loosing the content?
Or maybe classic ffmpeg's concat solves this issue somehow and I should use it?
you can use the trim and or atrim filter to cut a part of the audio or video.
[v]trim=0:3.23,setpts=START-PTS[vout]
[a]atrim=0:3.23,asetpts=START-PTS[aout]
setpts and asetpts fixes the timestamps
I only want to touch files that aren't 44.1 (as mp3 is lossy, so re-encoding/resampling files that dont needed to be touched is t good)
I have started playing with ffprobe (assuming this is the best way?), but got stuck with the syntax. Using:
ffprobe -show_streams -select_streams a format=sample_rate -of default=noprint_wrappers=1:nokey=1 myfile.mp3
Its not happy with this syntax, saying "myfile.mp3 provided as input filename, but 'format=sample_rate' was already specified."
Is there a better way to achieve this? If not, can someone help me with my ffmpeg probe syntax?
Remove -show_streams, add -loglevel error, and change format=sample_rate to -show_entries stream=sample_rate.
ffprobe -loglevel error -select_streams a -show_entries stream=sample_rate -of default=noprint_wrappers=1:nokey=1 myfile.mp3
I'm trying to get the size of an input video using ffmpeg, below is the code that I use, what I'm trying to do is to first store the result into a txt file and then do some parsing to get the size of the video:
$ ffmpeg -i TheNorth.mp4
The terminal says "At least one output file must be specified"
Then I tried this:
$ ffmpeg -i TheNorth.mp4 result.txt
The terminal says "Unable to find a suitable output format for 'size.txt'"
So how could I get the result and save it to the specified file?
You can store the output ffmpeg generates with piping:
ffmpeg -i TheNorth.mp4 2> result.txt
You need to use 2> here, as ffmpeg writes to StdErr (and not StdOut).
ffprobe
If you just want to get the size of the video then you can get that, and other info, directly with ffprobe. This will avoid redirection, temporary output files, and the additional parsing.
$ ffprobe -v error -select_streams v:0 -show_entries stream=height,width -of csv=p=0:s=x input.mkv
1280x720
See FFmpeg Wiki: FFprobe Tips for more examples.
tee
For users who want to encode and capture the resulting console output, I recommend using tee. The problem with pure redirection is that important messages such as error messages, failures, and prompts can be missed.
You can avoid this by including tee to show the output in the console and to save it to a file:
ffmpeg -i input … output |& tee console.txt
ffmpeg outputs to stderr instead of the more typical stdout, so the & is added to the | pipe to deal with that. This is only for Bash 4+. If you're using something else then change |& to 2>&1 which redirects stderr to stdout before it is sent to the pipe.
Somewhat better idea is to use ffprobe
ffprobe -show_format -print_format json TheNorth.mp4
that will output JSON formated info about video. Guess it is easier to parse than raw output. To redirect output to file use just ordinary pipe > result.txt similar to accepted answer but without two.
I am developing a web app, where people can record videos. I have been able to send chunks of audio n video to server successfully, where I am trying to combine them and return as single proper file.
my problem is if the recording is for one hour, after merging the chunks
video length : 1:00:00 , audio length : 00:59:30,
now, this is not a issue of audio not getting recorded( I have checked that), the problem is, somehow, when i merge the chunks of audio, it shrinks,
I find that it is progressive sync issue where it gets worse and worse as time increases.
I have searched the net for the solution, most places say async, I have tried using it, but to no avail, is the below usage correct?
ffmpeg -i audio.wav -async 1 -i video.webm -y -strict -2 v.mp4
(v.mp4 is the final file that I provide to the users.)
found a solution(or a temp fix, depends of how you look at it),
it involves combination of ffmpeg and ffprobe ... i have done audio streching( ratio<1)
ffprobe -i a.mp3 -show_entries format=duration -v quiet -print_format json
ffprobe -i v.mp4 -show_entries format=duration -v quiet -print_format json
ffmpeg -i a.mp3 -filter:a atempo="0.9194791304347826" aSync.mp3 // audio is being stretched.
ffmpeg -i aSync.mp3 -i v.mp4 final.mp4