Specifying input duration of .aac with ffmpeg - ffmpeg

I had an error with an mp4 recording, and after recovering the video and audio streams I've still got an issue. The aac audio file is 160kb/s CBR. However, ffmpeg returns this when trying to work with it;
[aac # 000001187e6944c0] Estimating duration from bitrate, this may be inaccurate
Input #0, aac, from 'result.aac':
Duration: 00:38:41.01, bitrate: 174 kb/s
Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 174 kb/s
That duration and bitrate is totally wrong. It should be ~42 minutes long, and it definitely has a bitrate of 160 kb/s.
This results in the audio being very inconsistently timed, as well as having all sorts of other issues. It's very weird.
Is there any way I can specify that the input is 160 cbr to try and wrangle it back into a usable file?

Related

Concatenating audio files with ffmpeg results in a wrong total duration

With "wrong total duration" I mean a total duration different from the sum of individual duration of audio files.
sum_duration_files != duration( concatenation of files )
In particular I am concatenating 2 OGG audio files with this command
ffmpeg -safe 0 -loglevel quiet \
-f concat -segment_time_metadata 1 -i {m3u_file_name} \
-vf select=concatdec_select \
-af aselect=concatdec_select,aresample=async=1 \
{ogg_file_name}
And I get the following
# Output of: ffprobe <FILE>.ogg
======== files_in
Input #0, ogg, from 'f1.ogg':
Duration: 00:00:04.32, start: 0.000000, bitrate: 28 kb/s
Stream #0:0: Audio: opus, 48000 Hz, mono, fltp
Input #0, ogg, from 'f2.ogg':
Duration: 00:00:00.70, start: 0.000000, bitrate: 68 kb/s
Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 160 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Note durations: 4.32 and 0.7 sec
And this is the output file.
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v1.ogg':
Duration: 00:00:04.61, start: 0.000000, bitrate: 61 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Duration: 4.61 sec
As 4.61 sec != 4.32 + 0.7 sec I have a problem.
The issue here is using a wrong concatenation approach for these files. As FFmpeg wiki article suggests, file-level concatenation (-f concat) requires all files in the listing to have the exact same codec parameters. In your case, only # of channels (mono) and sample format (flt) are common between them. On the other hand, codec (opus vs. vorbis) and sampling rate (48000 vs. 44100) are different.
-f concat grabs the first set of parameters and runs with it. In your case, it uses 48000 S/s for all the files. Although the second file is 44100 S/s, it assumes 48k (so it'll play it faster than it is). I don't know how the difference in the codec played out in the output.
So, a standard approach is to use -filter_complex concat=a=1:v=1:n=2 with these files given as separate inputs.
Out of curiosity, have you listen to the wrong-duration output file? [edit: never mind, your self-answer indicates one of them is a silent track]
I don't know WHY it happens, but I know how to avoid the problem in my particular case.
My case:
I am mixing (concatenating) different audio files generated by one single source with silence files generated by me.
Initially I generated the silence files with
# x is a float from python
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t {x:2.1f} -q:a 9 -acodec libvorbis silence-{x:2.1f}.ogg
Trying to resolve the issue I re-created those silences with the SAME parameters than the audios I was mixing with, that is (mono at 48Khz):
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t {x:2.1f} -c:a libvorbis silence-{x:2.1f}.ogg
And now ffprobe shows the expected result.
========== files out (concatenate of files_in)
Input #0, ogg, from 'f_concat_v2.ogg':
Duration: 00:00:05.02, start: 0.000000, bitrate: 56 kb/s
Stream #0:0: Audio: vorbis, 48000 Hz, mono, fltp, 80 kb/s
Metadata:
ENCODER : Lavc57.107.100 libvorbis
Duration: 5.02 = 4.32 + 0.70
If you want to avoid problems when concatenating silence with other sounds, do create the silence with the SAME parameters than the sound you will mix with (mono/stereo and Hz)
==== Update 2022-03-08
Using the info provided by #kesh I have recreated the silent ogg files using
ffmpeg -f lavfi -i anullsrc=r=48000:cl=mono -t 5.8 -c:a libopus silence-5.8.ogg
And now the
ffmpeg -safe 0 -f concat -segment_time_metadata 1
-i {m3u_file_name}
-vf select=concatdec_select
-af aselect=concatdec_select,aresample=async=1 {ogg_file_name}
Doesn't throw this error anymore (multiple times).
[opus # 0x558b2c245400] Error parsing the packet header.
Error while decoding stream #0:0: Invalid data found when processing input
I must say that the error was not creating (for me) any problem, because the output was what I expected, but now I feel better without it.

What is the difference of duration bitrate and stream bitrate in ffmpeg/ffprobe?

Why ffmpeg / ffprobe gives different bitrate values for the stream and for file as whole?
When I analyze an mp3 file with ffprobe, it gives different bitrates on first and second lines.
Does anyone know, what is the difference?
// File 1, there is problem
Duration: 02:05:47.04, start: 0.000000, bitrate: 193 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
// File 2, no problem
Duration: 02:05:51.05, start: 0.000000, bitrate: 192 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
(I need to get correct information about files because I process these files for fingerprinting)
If you want the actual bitrate of the audio stream, you'll need to parse it.
ffmpeg -i file -c copy -map 0:a -f null -
Note down the audio stream size on the last line, e.g. audio:8624kB and the duration on the line above it, e.g. time=00:03:43.16. Divide the first by the second to get the average bitrate of the stream.
If you want the notional bitrate i.e. the target set for the encoder, then it's the reading for the Stream.
The format bitrate i.e. the one next to start:, is crude, and simply divides the filesize by the duration. But this includes all streams and headers. Useful for a file with single video + single audio, but not for others.

ffmpeg doesn't seem to be working with multiple audio streams correctly

I'm having an issue with ffmpeg 3.2.2; ordinarily I ask it to make an MP4 video file with 2 audio streams. The command line looks like this:
ffmpeg.exe
-rtbufsize 256M
-f dshow -i video="screen-capture-recorder" -thread_queue_size 512
-f dshow -i audio="Line 2 (Virtual Audio Cable)"
-f dshow -i audio="Line 3 (Virtual Audio Cable)"
-map 0:v -map 1:a -map 2:a
-af silencedetect=n=-50dB:d=60 -pix_fmt yuv420p -y "c:\temp\2channelvideo.mp4"
I've wrapped it for legibility. This once worked fine, but something is wrong lately - it doesnt seem to record any audio, even though I can use other tools like Audacity to record audio from these devices just fine
I'm trying to do some diag on it by dropping the video component and asking ffmpeg to record the two audio devices to two separate files:
ffmpeg.exe
-f dshow -i audio="Line 2 (Virtual Audio Cable)" "c:\temp\line2.mp3"
-f dshow -i audio="Line 3 (Virtual Audio Cable)" "c:\temp\line3.mp3"
ffmpeg's console output looks like:
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, dshow, from 'audio=Line 2 (Virtual Audio Cable)':
Duration: N/A, start: 5935.810000, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, dshow, from 'audio=Line 3 (Virtual Audio Cable)':
Duration: N/A, start: 5936.329000, bitrate: 1411 kb/s
Stream #1:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Output #0, mp3, to 'c:\temp\line2.mp3':
Metadata:
TSSE : Lavf57.56.100
Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, s16p
Metadata:
encoder : Lavc57.64.101 libmp3lame
Output #1, mp3, to 'c:\temp\line3.mp3':
Metadata:
TSSE : Lavf57.56.100
Stream #1:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, s16p
Metadata:
encoder : Lavc57.64.101 libmp3lame
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Stream #0:0 -> #1:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
The problem i'm currently having is that the produced mp3 are identical copies of line 2 only; line 3 audio is not recorded. The last line is of concern; it seems to be saying that stream 0 is being mapped to both output 0 and 1? Do I need a map command for each file also? I thought it would be implicit due to the way i specified the arguments
Turned out I needed to add a -map x:a between each source and output file, where x was either 0 or 1 depending on if it was the first or second source..

ffmpeg not honoring sample rate in opus output

I am capturing a live audio stream to Opus, and no matter what I choose for the audio sample rate, I get 48khz output.
This is my command line
./ffmpeg -f alsa -ar 16000 -i sysdefault:CARD=CODEC -f
alsa -ar 16000 -i sysdefault:CARD=CODEC_1 -filter_complex
join=inputs=2:channel_layout=stereo:map=0.1-FR\|1.0-FL,asetpts=expr=N/SR/TB
-ar 16000 -ab 64k -c:a opus -vbr off -compression_level 5 output.ogg
And this is what ffmpeg responds with:
Output #0, ogg, to 'output.ogg': Metadata:
encoder : Lavf57.48.100
Stream #0:0: Audio: opus (libopus), 16000 Hz, stereo, s16, delay 104, padding 0, 64 kb/s (default)
Metadata:
encoder : Lavc57.54.100 libopus
However, it appears that ffmpeg has lied, because when analysing the file again, I get:
Input #0, ogg, from 'output.ogg': Duration: 00:00:03.21, start:
0.000000, bitrate: 89 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, s16, delay 156, padding 0
Metadata:
ENCODER : Lavc57.54.100 libopus
I have tried so many permutations of sample rate, simplifying down to a single audio input etc etc - always with the same result.
Any ideas?
This question should be asked and answered on Super User, since it's about using software instead of programming. But, since I know the answer, I'll post one anyway.
FFmpeg will encode Opus at the sample rate specified. You can verify this in the source code of libopusenc.c (here and here).
But FFmpeg will decode Opus at 48 kHz, even if it was encoded at a lower sample rate. You can verify this in libopusdec.c (here and here).
This is actually recommended by the Ogg Opus specification (IETF RFC 7845). Section 5.1, item 5 says:
An Ogg Opus player SHOULD select the playback sample rate according to the following procedure:
If the hardware supports 48 kHz playback, decode at 48 kHz.
Otherwise, if the hardware's highest available sample rate is a supported rate, decode at this sample rate.
Otherwise, if the hardware's highest available sample rate is less than 48 kHz, decode at the next higher Opus supported rate above the highest available hardware rate and resample.
Otherwise, decode at 48 kHz and resample.
Since FFmpeg and most hardware support 48 kHz playback, 48 kHz is used for decoding Opus in FFmpeg. The original sample rate is stored in the OpusHead packet of the Ogg container, so you can retrieve it using a parser or different player if you wish, but FFmpeg ignores it and just decodes at 48 kHz.

ffmpeg keeps converting second ac3 audio stream to mp2

I'm new to this forum, and hope someone can help.
I am trying to add a second audio track (chinese.ac3) to an XVID video (vts_01.avi) that already has an ac3 track.
These audio tracks are encoded to ac3, 48000 Hz, stereo, 128 kb/s, and I would like to keep them that way -- just multiplex the streams without transcoding.
This is the command I am using:
ffmpeg -i vts_01.avi -vcodec copy -i Chinese.ac3 -acodec copy -map 0:0 -map 0:1 -map 1:0 muxed2.avi -newaudio
ffmpeg does its work, except for the fact that it converts the second track to mp2, 64 kb/s.
Here is a relevant excerpt from the output, where the key part is 'Stream #0.2: Audio: mp2, 48000 Hz, stereo, s16, 64 kb/s' where I would like 'Stream #0.2: Audio: ac3, 48000 Hz, stereo, 128 kb/s':
Input #0, avi, from 'vts_01.avi':
Metadata:
encoder : Lavf53.5.0
Duration: 02:03:26.40, start: 0.000000, bitrate: 1954 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x352 [PAR 1:1 DAR 45:22], 23.98 tbr,
23.98 tbn, 23.98 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 128 kb/s
[ac3 # 018A7440] max_analyze_duration 5000000 reached at 5024000
[ac3 # 018A7440] Estimating duration from bitrate, this may be inaccurate
Input #1, ac3, from 'Chinese.ac3':
Duration: 02:03:26.36, start: 0.000000, bitrate: 128 kb/s
Stream #1.0: Audio: ac3, 48000 Hz, stereo, s16, 128 kb/s
File 'muxed2.avi' already exists. Overwrite ? [y/N] y
Output #0, avi, to 'muxed2.avi':
Metadata:
ISFT : Lavf53.5.0
Stream #0.0: Video: mpeg4, yuv420p, 720x352 [PAR 1:1 DAR 45:22], q=2-31, 23.
98 tbn, 23.98 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, 128 kb/s
Stream #0.2: Audio: mp2, 48000 Hz, stereo, s16, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Stream #1.0 -> #0.2
I have tried a number of different combinations, including explicitly forcing the stream to ac3 with:
ffmpeg -i vts_01.avi -vcodec copy -i chinese.ac3 -acodec ac3 -ac 2 -ar 48000 -ab 128k -map 0:0 -map 0:1 -map 1:0 muxed2.avi -newaudio
Same result.
I have also tried to assign a codec to the stream with stream specifier(based on http://ffmpeg.org/ffmpeg.html#toc-Stream-specifiers-1, but these options are not recognized by my ffmpeg.
I am running out of things to try.
(The OP edited the answer into the question. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I think I just found the solution
from http://ffmpeg-users.933282.n4.nabble.com/Encoding-with-multiple-Audio-tracks-td1289403.html There, James Darley says:
So your command line should look like:
ffmpeg -i INPUT [output options] OUTPUT [audio options] -newaudio [subtitle options] -newsubtitle
I then re-arranged my options accordingly, i.e. audio options for the new track after the output:
ffmpeg -i vts_01.avi -vcodec copy -acodec copy -i Chinese.ac3 muxed3.avi -acodec copy -newaudio
And I now gets my two ac3 audio tracks at the right bitrate.

Resources