Extract LUFS only from multiple file - bash

ffmpeg -i input.mp4 -af ebur128=framelog=verbose -f null - 2>&1 | awk '/I:/{print $2}'
The above command extract only LUFS value from input.mp4 file. But If there are number of mp4 files, how to apply similar command to extract LUFS value only from multiple mp4 files?
Please help.

Adapting this answer from How do you convert an entire directory with ffmpeg?
for i in *.mp4; do echo "$i:"; ffmpeg -i "$i" -map 0:a -af ebur128=framelog=verbose -f null - 2>&1 | awk '/I:/{print $2}'; done
Example output:
video1.mp4:
-21.8
video2.mp4:
-21.1
video3.mp4:
-21.8
-8.3
Note that video3.mp4 contains 2 separate audio streams.
This is assuming you can use Bash shell.
-map 0:a was added to only process the audio so the video is ignored and therefore the command is faster. See FFmpeg Wiki: Map.

Related

merge audio and video with ffmpeg doesnt work correctly

I have ubuntu 20.04 and in past days I did this job(merge video and audio) well in terminal and with ffmpeg:
ffmpeg -i input.mp4 -i input2.mp3 -c copy output.mp4
so fast I have recived output.mp4, but now I tried this one and get output without any sound!
I try another ways to merge this ones(also with ffmpeg) but there are no diffrent...
ffmpeg -f concat -safe 0 -i <(for f in ./input*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Note -f concat will select a demuxer. This alters the way -i nput files are read.
So instead video-files 'concat expects a txt-file listing the files to concatenate.
However we somehow omit the creation of that text file and use process substitution to generate and pass that list on the fly to demux.
For more details go here:
https://trac.ffmpeg.org/wiki/Concatenate#demuxer
If you want to merge several video files, you can use these command.
merge two video files.
ffmpeg -f concat -i 1.mp4 -1 2.mp4 -codec copy out.mp4
merge multiple video files.
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mpt -vcodec copy -acodec copy out.mp4

Using ffmpeg to convert mp3 to mp4 - how to draw filename on generated video?

Using trial and error I am using the following script on an OSX, to bulk convert a whole folder full of mp3 files, to mp4, by looping a specific video file:
for i in *.mp3; do /usr/local/bin/ffmpeg -stream_loop -1 -i /path_to_filename.mp4 -c copy -v 0 -f nut - | /usr/local/bin/ffmpeg -thread_queue_size 10K -i - -i "$i" -c copy -map 0:v -map 1:a -shortest "$(basename "$i" )".mp4 ; done; for f in *.mp3.mp4; do mv -v "$f" "${f/.mp3.mp4/.mp4}"; done
How can I also print/add/burn the mp3 filename, without the extension (.mp3), as an additional video layer at the bottom of the generated video screen, and with the added difficulty of word wrapping the text if is too long?
This command makes a temporary SRT file for the subtitles filter which will automatically deal with the placement and word wrapping:
for i in *.mp3; do echo "1" > subs.srt; echo "00:00:00,000 --> 10:00:00,000" >> subs.srt; echo "${i%.*}" >> subs.srt; ffmpeg -stream_loop -1 -i video.mp4 -i "$i" -filter_complex "[0:v]subtitles=subs.srt:force_style=Alignment=3,format=yuv420p[v]" -map "[v]" -map 1:a -c:v libx264 -c:a copy -shortest -movflags +faststart "${i%.*}.mp4"; done
Running the command in the directory containing the file allows avoidance of basename and creates a simpler command.
MP3 is not universally supported in MP4. Consider changing -c:a copy to -c:a aac if your player does not support it. But I suspect you're targeting YouTube which will be fine with MP3 in MP4.
The three instances of echo are inefficient but effective in avoiding any newline issues. Using one instance of printf would be more optimal, but I don't have access to macOS to test its printf implementation.

Reporting duplicated frames with FFmpeg

I am looking for a method to report (not just detect and remove) duplicated frames of video detected by FFmpeg - similar to how you can print out blackdetect, cropdetect, silencedetect, etc.
For example:
ffmpeg -i input.mp4 -vf blackdetect -an -f null - 2>&1 | grep blackdetect > output.txt
Outputs something like:
[blackdetect # 0x7f8032f03680] black_start:5.00501 black_end:7.00701 black_duration:2.002
But there's no "dupedetect" filter as far as I know, so I'm looking for any ideas/workarounds to get a read of where frames are duplicated.
Try -vp mpdecimate in the command line.
ffmpeg -i input.mp4 -vf mpdecimate -loglevel debug -an -f null - 2>&1 | grep 'drop_count:\d' > output.txt
Sample line of output:
[Parsed_mpdecimate_0 # 0x7fbbfa210380] lo:0<2653 lo:0<1326 lo:0<1326 drop pts:101101 pts_time:4.21254 drop_count:1

Pipe input in to ffmpeg stdin

I am trying to use ffmpeg to decode audio data. While it works to load from a file, I would like to avoid using files because to do so, means I would have to use a temporary. Instead, I'd like to pipe in the data(which I've previously loaded) using stdin.
Is this possible?
e.g.,
Manually load mp3 file
Pipe it in to the ffmpeg spawned process
Get raw output
(it should work with ffprobe and ffplay also)
ffmpeg has a special pipe flag that instructs the program to consume stdin.
note that almost always the input format needs to be defined explicitly.
example (output is in PCM signed 16-bit little-endian format):
cat file.mp3 | ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le pipe:
pipe docs are here
supported audio types are here
- is the same as pipe:
I couldn't find where it's documented, and I don't have the patience to check the source, but - appears to be the exact same as pipe: according to my tests with ffmpeg 4.2.4, where pipe: does what you usually expect from - in other Linux utilities as mentioned in the documentation of the pipe protocol:
If number is not specified, by default the stdout file descriptor will be used for writing, stdin for reading.
So for example you could rewrite the command from https://stackoverflow.com/a/45902691/895245
ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le pipe: < file.mp3
a bit more simply as:
ffmpeg -f mp3 -i - -c:a pcm_s16le -f s16le - < file.mp3
Related: What does "dash" - mean as ffmpeg output filename
I don't have enough reputation to add a comment, so...
MrBar's example
ffmpeg -i file.mp3 -c:a pcm_s16le -f s16le pipe: | ffmpeg -f mp3 -i pipe: -c:a pcm_s16le -f s16le encoded.mp3
should read,
ffmpeg -i file.mp3 -c:a pcm_s16le -f s16le pipe: | ffmpeg -f s16le -i pipe: -f mp3 encoded.mp3
Since you have to set the incoming stream's properties - and you may not feel like it - here's an alternative that I've used: use a fifo or a pipe (not the one mentioned above).
Here is an example using wget as a stream source, but cou can use anything, cat, nc, you name it:
$ mkfifo tmp.mp4 # or any other format
$ wget -O tmp.mp4 https://link.mp4 &
$ ffmpeg -i tmp.mp4 YourFileHere.mp4
Finally you may want to delete the pipe - you remove it like a normal file:
$ rm tmp.mp4
Voila!

ffmpeg - extract subtitles from piped input?

I have found two separate commands that I want to combine. One for taking piped input:
ffmpeg -i pipe:0
And another for extracting subtitles from a .ts file:
ffmpeg -i "movie=file.ts[out0+subcc]" -map s output.srt
But I can't work out how to combine them.
ffmpeg -i "movie=pipe:0[out0+subcc]" -map s output.srt
doesn't work. I'm kind of an ffmpeg newbie, so any ideas?
The solution requires escaping the colon after the "pipe".
Depending on your shell, and quoting rules, you'll need from 2 backslashes to... well, who knows :-)
Here's what has worked for me:
cat input.ts | ffmpeg -f lavfi -i 'movie=pipe\\:0[out+subcc]' -map s output.srt
If you use double quotes you'll need at least another backslash:
cat input.ts | ffmpeg -f lavfi -i "movie=pipe\\\:0[out+subcc]" -map s output.srt
Source: https://trac.ffmpeg.org/ticket/5229

Resources