Why is there ffmpeg codec noise when encoding test tone? - audio

I used FFmpeg to generate a test clip with color bars and a tone. I also made a special filter to dump out the raw audio data to check it. I was surprised to find that there is significant noise riding on the audio tone after it has gone through the AAC codec. Is this expected? Is there a way to prevent it?
To make the test file I used:
ffmpeg -f lavfi -i "smptehdbars=duration=600:size=1280x720:rate=59.94" -qscale:v 1 -pix_fmt yuv420p smpte_r59_720.mp4
then
ffmpeg -i smpte_r59_720.mp4 -f lavfi -i "sine=frequency=1000:sample_rate=48000:duration=600" -qscale:v 1 -vcodec copy -c:a aac -b:a 192k -shortest -map 0:0 -map 1:0 smpte_r59_720T.mp4
and then
ffmpeg -i smpte_r59_720T.mp4 -y -map 0 -acodec aac -vcodec libx264 -crf 23 -bsf:v h264_mp4toannexb smpte_r59_720T.ts
(Trying to do this all in one step kept failing.)
Other variations on this have varying degrees of noise, sometimes above nominal amplitude and sometimes below.
After finding this problem I pulled a third party test tone .WAV file with 44.1KHz sample rate from the web and checked it. The raw file is clean, but the encoded file I made has noise.
Noise on TS SMPTE bars
Clean audio from MP4

Related

Include audio from FFmpeg overlay in output

I'm using the following command to combine two video files together, overlaying the second one at a certain point in the first file. The result is what I want except the audio from the overlayed file is missing.
ffmpeg.exe -y -hide_banner -ss 00:00:00.067 -i promo.mov -i tag.mov -filter_complex "[1:v]setpts=PTS+6.5/TB[a];[0:v][a]overlay=enable=gte(t\,6.5)[out]" -map [out] -map 0:a -map 1:a -c:v mpeg2video -c:a pcm_s16le -ar 48000 -af loudnorm=I=-20:print_format=summary -preset ultrafast -q:v 0 -t 10 complete.mxf
Without the -map 0:a I get no audio at all, but the second -map 1:a does not pass the audio from -i tag.mov
I have also tried amix but that combines audio from both clips starting at the beginning, and I want the audio from the second file to begin when that file starts overlaying.
It would also be helpful if I could make the audio from the first clip drop lower at the time of the overlay.
amix doesn't support introducing an input mid-way, so the workaround is to add leading silence. You can use the adelay filter to do this.
make the audio from the first clip drop lower at the time of the overlay
This is possible using a sidechaincompressor which takes two inputs and lowers the volume of the first input based on the volume of the second input.
So use,
ffmpeg.exe -y -hide_banner -ss 00:00:00.067 -i promo.mov -i tag.mov -filter_complex "[1:v]setpts=PTS+6.5/TB[1v];[0:v][1v]overlay=enable=gte(t\,6.5)[vout];[1:a]adelay=6.5s,apad,asplit=2[1amix][1aref];[0:a][1aref]sidechaincompress[0asc];[0asc][1amix]amix=inputs=2:duration=first[aout]" -map [vout] -map [aout] -c:v mpeg2video -c:a pcm_s16le -ar 48000 -af loudnorm=I=-20:print_format=summary -preset ultrafast -q:v 0 -t 10 complete.mxf

ffmpeg : how to take wav as audio input for creating a video?

I'm trying to use ffmpeg for rendering video where an audio file and image are taken as inputs, and turned into a video with the same dimensions as the image with the audio file playing for the duration of the video (basically a music video).
I have this working for flac and mp3 files, my ffmpeg command for mp3 is below:
ffmpeg -loop 1 -framerate 2 -i "front.png" -i "testMP3file.mp3" -vf "scale=2*trunc(iw/2):2*trunc(ih/2),setsar=1" -c:v libx264 -preset medium -tune stillimage -crf 18 -c:a copy -shortest -pix_fmt yuv420p -strict -2 "testMP3fileOutput1.mp4"
How can I take wav audio files as input instead of mp3? Is there a different codec I need to specify? This post talks about download libfaac and using that, is there any way to take wav audio file as input using just ffmpeg without downloading a separate library?
Just use a WAV file as input and change -c:a copy to -c:a aac (or omit -c:a if you want to use the default encoder which is -c:a aac for MP4 output):
ffmpeg -loop 1 -framerate 2 -i "front.png" -i "testMP3file.wav" -vf "scale=2*trunc(iw/2):2*trunc(ih/2),setsar=1,format=yuv420p" -c:v libx264 -preset medium -tune stillimage -crf 18 -c:a aac -shortest "testMP3fileOutput1.mp4"
Other changes:
No need for -strict -2: it does nothing. You can remove that from your command too.
I replaced -pix_fmt yuv420p with format=yuv420p so all your filtering is contained in the filtergraph.

FFMPEG amix filter causes main audio stream to cut out

So I have a video called 1.mkv and would like to mix in a variety of different audio clips at certain points. To do this I'm using the -filter_complex option. However, I'm running into some problems because when ffmpeg tries to mix in the first audio stream the audio works for a short while when the clip is playing and then all audio cuts out. I'm running ffmpeg version 2.8.15-0(which is up to date with my distro). Another "weird" thing about the video output is that in xplayer the video will freeze after the audio cuts out, and will work if you skip far enough ahead in the video(not sure if this is helpful but it might give some extra clues).
Full command:
ffmpeg -i "1.mkv" -i "5.wav" -i "2.wav" -i "3.wav" -i "6.wav" -i "7.wav" -i "4.wav" -i "9.wav" -i "8.wav" -i "10.wav" -filter_complex "[0:0]setdar=4/3[v0];
[2:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=20000|20000,volume=0.5[ad2];
[4:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=900000|900000,volume=0.5[ad4];
[3:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=300000|300000,volume=0.5[ad3];
[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=720000|720000,volume=0.5[ad1];
[7:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1140000|1140000,volume=0.5[ad7];
[9:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1260000|1260000,volume=0.5[ad9];
[8:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1020000|1020000,volume=0.5[ad8];
[5:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=960000|960000,volume=0.5[ad5];
[6:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=480000|480000,volume=0.5[ad6];
[0:1]volume=1[ad0];
[ad0][ad2][ad4][ad3][ad1][ad7][ad9][ad8][ad5][ad6]amix=inputs=10:duration=first:dropout_transition=0,dynaudnorm[a0]" -map "[v0]" -map "[a0]" -c:v libx264 -ar 44100 -c:a libmp3lame -preset ultrafast -crf 17 -b:v 1M out2.flv
partial command
ffmpeg -i "1.mkv" -i "2.wav" -filter_complex "[0:0]setdar=4/3[v0];
[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=20000|20000,volume=0.5[ad2];
[0:1]volume=1[ad0];
[ad0][ad2]amix=inputs=2:duration=first:dropout_transition=0,dynaudnorm[a0]" -map "[v0]" -map "[a0]" -c:v libx264 -ar 44100 -c:a libmp3lame -preset ultrafast -crf 17 -b:v 1M out2.flv
So I managed to solve this by playing around with the audio filters. The fix was converting the mono stream into a stereo before applying the audio filters. I was considering deleting the question but I'll leave it up incase someone has the same problem in the future.
mono to stereo
[1][1]amerge=inputs=2[a1]

libav / ffmpeg output optimisation for small file sizes

I am using the following command to take an audio mp3 file and make a video out of it (by using a static jpg picture). My aim is to get a mp3 audio that is as small as possible with still acceptable quality.
frequency="11000"
bitrate="45000"
avconv -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -metadata STEREO_MODE=mono -c:v libx264 -ar "$frequency" -b:a "$bitrate" -ac 0 result.mkv
My questions are:
1. how can I achieve that the resulting file is MONO?
2. is it possible to reduce the bitrate furthermore? I would like to use values below 45000, too.
3. My aim is to get control of the parameters that influence the file size most significantly. Presently I know that the frequency is quite important. Are there any other parameters that would help me to get a very small output file with still acceptable quality?
Thanks in advance.
Since you are coding to a compressed audio codec, the frequency doesn't directly affect the file size. However, a frequency of 11 kHz will reduce quality of music.
Instead, I'd suggest
frequency="22050"
bitrate="48000"
ffmpeg -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -c:v libx264 -crf 28 \
-ar "$frequency" -b:a "$bitrate" -ac 1 result.mkv
The CRF parameter controls video quality - lower values produce better quality but larger files. You'll get more savings from controlling that than audio bitrate, which is at the lower end anyway.
If your build has libfdk_aac included, you can instead use
frequency="22050"
bitrate="32000"
ffmpeg -loop 1 -i a.jpg -i audio.mp3 -shortest -r 1 -c:v libx264 -crf 28 \
-ar "$frequency" -c:a libfdk_aac -profile:a aac_he_v2 -b:a "$bitrate" -ac 1 result.mkv

Ffmpeg to duplicate an audio stream and encode this new stream

I have some video files that I need to re-encode due to compatibility issues. They are currently mkv files with h.264 video and ac3-a52 audio. I want to keep the h.264 video, convert the container to m4v and create two audio tracks, one with the original ac3-a52 and one copied from that but in aac stereo.
I assume there has to be some sort of audio stream mapping command but I don't know how to map and re-encode at the same time. What command should I enter into ffmpeg to achieve this?
Also, what is the difference between ac3 and ac3-a52? Will an apple TV still be able to pass through ac3-a52 or does that have to be converted to ac3?
this works for me:
ffmpeg -y -i Source.mkv -map 0:v -c:v copy -map 0:a -c:a copy -map 0:a -strict -2 -c:a aac out.mkv
-y – A global option to overwrite the output file if it already exists.
-map 0:v – Designate the video stream(s) from the first input as a source for the output file.
-c:v copy – Stream copy the video. This just muxes the input to the output. No re-encoding occurs.
-map 0:a – Designate the audio stream(s) from the first input as a source for the output file.
-c:a copy – Stream copy the audio. This just muxes the input to the output. No re-encoding occurs.
-strict -2 -c:a aac – Use the native FFmpeg AAC audio encoder. -strict -2 is required as a way that you acknowledge that the encoder is designated as experimental. It is not a great encoder, but it is not too bad at higher bitrates.
According to wikipedia, there is no difference between AC3 and ATSC A/52: the 1st one is the name of the codec, the 2nd is the name of the standard specifying the AC3 codec. Maybe someone have more knowledge about it?
I'm doing the same as the OP, but with an m4v container. I'm using the MacPorts "nonfree" variant of ffmpeg so that I can use libfaac, which gives better audio quality than the built-in AAC encoder and also had the same issue as #dkam. The command line I ended using is like this:
ffmpeg -i input.m4v -map 0:v -c:v copy -map 0:a -c:a:0 copy -map 0:a -c:a:1 libfaac output.m4v
(The videos are for playback on an iPad, which doesn't seem to be able to handle ac3.)
This command will take a video with 1 audio stream, and downmix to stereo and convert the audio stream and add it as a 2nd audio stream. It will be in AAC 384k.
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:0 -c:a:1 aac -b:a 384k -ac 2 OUTPUT.mkv
Explanation of the command
ffmpeg -i INPUT.mkv The application and input file
-strict -2 Enable downmixing support
-map 0 Tell ffmpeg read all Video, Audio, and Subtitle streams for the following arguments
-c copy Copy everything
-map 0:a:0 Tell ffmpeg to read the first audio stream for the following arguments
-c:a:1 aac Output the audio to a 2nd audio channel (0 = first channel) in aac format. Important! You must change the output channel to a higher number if there are multiple audio streams to prevent overwriting them.
-b:a 384k 384k bitrate (I don't know what's good for aac stereo but this is really high since it's for 5.1 aac)
-ac 2 Downmix to stereo
OUTPUT.mkv Output file
More examples
A video with two audio streams. Creating a third audio stream by encoding the first.
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:0 -c:a:2 aac -b:a 384k -ac 2 OUTPUT.mkv
Again a video with two audio streams, but you want to encode the second one
ffmpeg -i INPUT.mkv -strict -2 -map 0 -c copy -map 0:a:1 -c:a:2 aac -b:a 384k -ac 2 OUTPUT.mkv

Resources