ffmpeg - output 5.1 AAC without lowpass on the LFE channel - audio

I'm trying to encode 6 arbitrary mono audio streams into a single AAC 5.1 track in an mp4 container (here with test streams):
ffmpeg -f lavfi -i testsrc=duration=10:size=100x100:rate=30 -f lavfi -i aevalsrc="-2+random(0)" -filter_complex "[1:a][1:a][1:a][1:a][1:a][1:a]join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-LFE|4.0-BL|5.0-BR[a]" -map '0:v' -map "[a]" -c:a aac -channel_layout 5.1 -t 10 testlfe.mp4
5 of the channels replicate the input audio just fine (modulo encoding). However, the LFE channel is lowpassed. Extracting with:
ffmpeg -i testlfe.mp4 -filter_complex "channelsplit=channel_layout=5.1:channels=LFE[LFE]" -map '[LFE]' testlfe.wav
I get a lowpassed rumble, instead of the original full white noise
(from ffmpeg -i testlfe.wav -lavfi showspectrumpic=s=640x320 testlfe.png)
Is there a way to prevent the lowpass from happening?
I couldn't find any references whether that's inherent to the AAC 5.1 encoding, something that ffmpeg does, or inherent to the decoding process. (I did decode my same test files using something that uses Microsoft MediaFoundation and the LFE channel was still lowpassed).

Turns out, the AAC codec inherently limits the LFE bandwidth, so there's no way around it.
(thanks to kesh in the comments) Wikipedia's Advanced Audio Encoding article claims the upper limit is 120Hz which matches my spectrogram, but doesn't cite a source. The actual ISO/IEC 13818-7:2006(en) Standard costs a bunch of money to read as usual, but in the free glossary there is an entry:
low frequency enhancement ( LFE ) channel:
limited bandwidth channel for low frequency audio effects in a multichannel system

Encode with
ffmpeg -i 6channels.wav -filter "channelmap=0|1|2|3|4|5:6.0(front)" -c:a libfdk_aac -ac 6 -profile:a aac_he -vbr 1 -cutoff 18000 -movflags +faststart 6channels-vbr1-fdk.m4a
It can also be done with regular aac codec.

Related

FFMPEG encode audio and forced subtitles at same time?

I'm using latest static build of ffmpeg windows.
My input file (.mkv) is:
[video] - 1080, V_MPEG4/ISO/AVC, 14.6 Mbps, ID#0
[audio] - DTS 5.1, 1510 Kbps, ID#1
[subtitles] - S_TEXT/ASS Lossless English, ID#14
My problem is this: I convert the audio, so that my target player, a XB1 console (media support faq), is able to play audio/video. However sometimes its rather difficult to hear or parts may be in foreign language, so I want to force the english subtitles into the mix at the same time I convert the audio.
Currently for the audio, I use the following command
ffmpeg -i input.mkv -codec copy -acodec ac3 output.mkv
Can I somehow tie in the forced subtitles (onto the video) in order to save an extra process of taking the output.mkv and trying to force subtitles on?
Edit: I've tried using the following command to extract subtitles to be able to edit them
ffmpeg -i Movie.mkv -map 0:s:14 subs.srt
However i get the error: Stream map '0:s:14' matches no streams
Edit2: attempted to extract subtitles and succeeded with
ffmpeg -i input.mkv -map 0:14 -c copy subtitles.ass
but still looking to force the subtitles, nonetheless!
Also - a little bonus to this question - can I somehow extract the .ass file and edit it to only produce subtitles for foreign parts - so english audio doesn't have subtitles during the movie but foreign audio does have subtitles?
Cheers
Edit3:
When I try to use both of the commands at once (my earlier mentioned audio converter & one from the ffmpeg wiki)
ffmpeg -i input.mkv -codec copy -acodec ac3 -vf "ass=subs.ass" output.mkv
I get the following error from ffmpeg,
Filtergraph 'ass=subs.ass' was defined for video output stream 0:0 but codec copy was selected.
Filtering and streamcopy cannot be used together.
Since your media player does not support subtitles, the text has to be burnt onto the video image. For that, use
ffmpeg -i input.mkv -vf "ass=subs.ass" -c:v libx264 -crf 20 -c:a ac3 output.mkv
This will re-encode the video, since text is being added. The CRF value controls the video quality. Lower values produce better quality but larger files. 18 to 28 is a decent range to try.

FFMPEG Encode encode into .3g2 best quality?

I'd like to get the best .3g2 quality for my video encoding. I've read about this format on wiki, but as a newbie, I'm not sure to get the best sound/video bitrate.
Format sizes are 128x96, 176x144, 352x288, 704x576, and max 1408x1152 pixels.
I couldn't find the highest video bitrate.
I've tried this :
ffmpeg -i C:\projet.avi -s 1408x1152 -vf "split [a], pad=iw*2:ih [b], [a] alphaextract, [b] overlay=w" -vb 1220000000 -ac 1 -ar 8000 C:\projet.alpha.3g2
it says
"[h263 # 0000000000666bc0] bitrate tolerance 4000000 too small for bitrate 12200000000, overriding
[libopencore_amrnb # 000000000066aee0] bitrate not supported: use one of 4.75k, 5.15k, 5.90k, 6.70k, 7.40k, 7.95k, 10.20k, 12.20k, using 12.20k"
I don't understand what it means ?
Others : I've tried to mention stereo sound, 44000Hz, but it seems not supported.
Any help/Suggestions ? Thank you !
P.S: I need alpha channel and .3g2 for an Augmented Reality software on iOS and Android.
LAST EDIT : I'm still with
ffmpeg -i c:/test.avi -s 1408x1152 -vf "split [a], pad=iw*2:ih [b], [a] alphaextract, [b] overlay=w" -vb 4000000 -ac 1 -ar 8000 C:\test.alpha.3g2
It's working well except error messages, and bad quality sound. Any more ideas ?
For video, your supplied bitrate (1200M!) is too high. Use -q:v 1 instead of -b:v for best quality.
For audio, by default, ffmpeg tells the encoder to use a bitrate of 128k unless specified otherwise. Which is not valid for the default encoder used here. So the encoder has overridden the generic value with 12.20k.
If your application supports it, use
ffmpeg -i C:\projet.avi -filter_complex "[0]alphaextract[a];[0][a]hstack" -c:v libx264 -crf 20 -c:a aac C:\projet.alpha.3g2

FFmpeg How to use alimiter Filter?

I cannot find enough documentation on the alimiter filter.
https://ffmpeg.org/ffmpeg-filters.html#alimiter
I used -filter_complex alimiter=limit=0.5 and it applied to the file but it boosted the volume.
I thought it was supposed to hardlimit the volume down?
FFmpeg says through cmd limit range [0.0625 - 1]
ffmpeg -i audio.wav -y -acodec libmp3lame -b:a 320k -ar 44100 -ac 2 -joint_stereo 1 -filter_complex alimiter=limit=0.5 audio.mp3
Here's a look at the two files through Adobe Audition
Original
FFmpeg alimiter 0.5
I found the problem was here:
level
Auto level output signal. Default is enabled. This normalizes audio back to 0dB if enabled.
I tried chaining the filter like this using level=disabled
-filter_complex alimiter=level_in=1:level_out=1:limit=0.5:attack=7:release=100:level=disabled
It now hard limits without raising the volume.

Re-encode video stream only with ffmpeg (and with all audio streams)

I'm looking for a way to re-encode the video stream of a movie only and keep all other streams as they are using ffmpeg or more specific streamio/streamio-ffmpeg (Github - StreamIO-FFMPEG).
I already tried various combinations of -map 0 or -map a:0 -map s:0, but in all combinations I tried, either nothing is encoded at all, or not all other streams are copied to the new file. In most cases there is only one audio stream after encoding, when there were two before, and sometimes the subtitle streams are lost, too. Also most times the info what language the streams are in gets lost.
So when I have a movie file (mkv) with the following streams:
0: video [H.264, 1080p]
1: audio [english, mp3]
2: audio [french, mp3]
3: subtitle [english (forced)]
4: subtitle [english]
What should the ffmpeg parameters be, if I want to encode the video file to H.265 and 720p and keep all other streams as they are?
What should the parameters be, if I additionally want to encode the audio streams as AAC?
Thanks in advance!
Use
ffmpeg -i in.mkv -vf scale=hd720 -map 0 -c copy -c:v libx265 out.mkv
To encode audio as well,
ffmpeg -i in.mkv -vf scale=hd720 -map 0 -c copy -c:v libx265 -c:a aac out.mkv
(The order of the arguments above matter)

Normalize audio in an avi file

I have an avi file that has different levels of audio. Is there a way to decrease and increase appropriately where needed the audio of my file using ffmpeg?
In ffmpeg you can use the volume filter to change the volume of a track. Make sure you download a recent version of the program.
Find out the gain to apply
First you need to analyze the audio stream for the maximum volume to see if normalizing would even pay off:
ffmpeg -i video.avi -af "volumedetect" -f null /dev/null
Replace /dev/null with NUL on Windows. This will output something like the following:
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] histogram_0db: 87861
As you can see, our maximum volume is -5.0 dB, so we can apply 5 dB gain. If you get a value of 0 dB, then you don't need to normalize the audio.
Apply the volume filter:
Now we apply the volume filter to an audio file. Note that applying the filter means we will have to re-encode the audio stream. What codec you want for audio depends on the original format, of course. Here are some examples:
Plain audio file: Just encode the file with whatever encoder you need:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Your options are very broad, of course.
AVI format: Usually there's MP3 audio with video that comes in an AVI container:
ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.
MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.
ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.mp4
Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.
In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.
The author's info is: Jon Skarpeteig in SuperUser
You can use my ffmpeg-normalize script for that.
First, install a recent version of ffmpeg. Then, install via pip install ffmpeg_normalize, then run it on an AVI file:
ffmpeg-normalize input.avi -o output.mkv -c:a aac -b:a 192k
Here, we're choosing to re-encode the audio with AAC at 192 kBit/s, and copy the video stream over to the output. This will perform EBU R128 normalization, but simple peak/RMS normalization is also possible.

Resources