FFMPEG (Input 8K AAC -> (AAC FLV) youtube streaming noise - audio

Hello I run a streaming encoder for a non profit cause. Chosen FFMPEG as it's very simple and doing the job near perfectly however the audio is noisy popping and cracking. Video is crystal clear.
ffmpeg version N-86950-g1bef008 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 7.1.0 (GCC)
Here is my command.
ffmpeg -rtsp_transport tcp -i $RTSP_SRC -vcodec copy -af "volume=12dB" -ar 8000 -acodec aac -f flv rtmp://a.rtmp.youtube.com/live2/$DEST_KEY
However when I just play the stream the noise levels are quite acceptable.
ffplay -rtsp_transport tcp -i $RTSP_SRC
What I have tried so far.
Change input audio sampling from 8K to 16K (that's all is supported currently). It made the noise problem much worse. I can't change it to a native FLV sampling(44100 or 22050 or 11025) at least not yet, the integrated rtsp stream does not support it.)
My working theory is during resampling stream noise is getting boosted. So to eliminate that I tried audio copy codec even then there is no significant improvement.

-af "equalizer=f=100:t=h:width=200:g=-64" Suppressing this frequency band cut all the crackling / popping noise for me.

Related

ffmpeg - output 5.1 AAC without lowpass on the LFE channel

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.

Webrtc streaming issue with Wowza and FFMPEG

I am trying to stream video and audio from a Camera in a browser using Webrtc and Wowza Media Server (4.7.3 version).
The camera stream (h264/aac) is first of all transcoded by using FFMPEG (version N-89681-g2477bfe built with gcc 4.8.5, last available version on ffmpeg website) in VP8/OPUS and then pushed to the Wowza Server.
By using the small Wowza webpage I ask for the Wowza stream to be displayed in the browser (Chrome Version 66.0.3336.5 Build officiel canary 32 bits).
FFMPEG used command :
ffmpeg -rtsp_transport tcp -i rtsp://<camera_stream> -vcodec libvpx -vb 600000 -crf 10 -qmin 0 -qmax 50 -acodec libopus -ab 32000 -ar 48000 -ac 2 -f rtsp rtsp://<IP_Address_Wowza>:<port_no_ssl>/<application_name>/test
When I click on Play stream I have a very bad quality video and audio (jerky video and very bad audio).
If I use this FFMPEG command:
ffmpeg -rtsp_transport tcp -i rtsp://<camera_stream> -vcodec libvpx -vb 600000 -crf 10 -qmin 0 -qmax 50 -acodec copy -f rtsp rtsp://<IP_Address_Wowza>:<port_no_ssl>/<application_name>/test
I will have a good video (flowing, smooth) but no audio (the camera micro is ON).
If libopus is the problem (as this test first shows), I tried libvorbis but with Chrome console I have this error "Failed to set remote offer sdp: Session error code: ERROR_CONTENT". Weird, cause libvorbis is one of the available codecs for Webrtc.
Is someone experiencing the same issue ? Did someone experience the same issue ?
Thanks in advance.
You probably have no audio because opus must have sample rate of 48000
You should add the flag:
"-ar 48000"
to the output settings
I also experienced the "bad quality video and audio issues".
I finally solved the issue by adding:
"-quality realtime" to the output settings .
That work well for me, I hope this will help you.

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.

How to stream on YouTube using a Raspberry Pi?

So I'm trying to stream on YouTube using a raspberry pi. The idea is for one raspberry pi to be used to stream the connected webcam and for another to display the stream, sort of like a surveillance camera. Both raspberry pi's are currently using Raspbian.
So is it possible for me to stream directly to YouTube on a Raspberry Pi.
You can use any Pi supported RTMP/Flash encoder to publish a YouTube live event. One example is ffmpeg which can be compiled on Raspbian.
Create your YouTube live event using the guide. You can find the various encoder settings here.
When everything is ready you can start streaming. For a 640x480#25 700k video stream the command will be something like:
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 -c:v libx264 -b:v 700k -maxrate 700k -bufsize 700k -an -f flv rtmp://<youtube_rtmp_server/<youtube_live_stream_id>
"So is it possible for me to stream directly to YouTube on a Raspberry
Pi?"
Yes. But you're going to need to do a bit of configuring and get different hardware depending on your project needs.
For my project, a day and night doorway "security camera" that streams live to youtube, I chose a Raspberry Pi Zero W running raspbian (headless) and a camera module with auto IR switching capabilities and IR lights.
I have edited the raspbian image so all of the configurations of the wifi and camera module interfaces, code, and dependencies I need are pre-installed, so I can just flash an sd card, slap it in a pi+camera+powersupply setup and it does its thing.
So, for this answer to be helpful at all, you're going to need to do plenty of research on FFMPEG, know what it is, learn what it does, and get it installed on your board... You should be able to run a few tests getting FFMPEG to just spit out maybe a 10-second long video from your camera. I wouldn't bother reading any more of my ramblings if you have not got that far yet, because things are about to get specific.
So, your board is online, you can see it on the network, it's got internet, it's got ffmpeg, it's ready to go.
Here is the ffmpeg "stream command" I use to start the live stream:
raspivid -o - -t 0 -vf -hf -fps 60 -b 12000000 -rot 180 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -i - -vcodec copy -acodec aac -ab 384k -g 17 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/SESSION_ID
I arrived at this "stream command" above by tweaking each parameter you see, one by one, and in different combinations and I eventually got a really crisp 1080p stream with no buffering issues at all except for the occasional bit of wifi lag that comes around on my setup. You are going to need to do a ton of research into what every parameter does to get things just right and trust me it's going to be a pain figuring out what does what in the beginning. I would lurk all around StackOverflow and other resources and just plug around and see what you can get to come out of your setup when it comes to these FFMPEG commands.
To test if this "stream command" or any other you find works for you, just change SESSION_ID at the end to your stream key and run it in the console.
After you get an output you are happy with, figure out on your own how you want to trigger your camera to start streaming, if you want it to start recording as soon as the board is ready to start sending data, you accomplish this by putting your "stream command" in /etc/rc.local and it will run that command as soon as it can.
For my project, I use 18650 cells charged by solar panels as the power source so I have to be conscious about the power I use so I wrote some NodeJS program monitor just that.
Alright, that's enough talking into the wind for now. Hopefully, any of this helped someone out there, cheers.
Audio working! This worked for me from a raspberry pi 4 with an rbp v1.3 camera and cheap usb audio interface. Also gets the default audio which you can set in the alsamixer:
raspivid -o - -t 0 -vf -hf -fps 30 -b 6000000 | ffmpeg -f alsa -ac 1 -ar 44100 -i default -acodec pcm_s16le -f s16le -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 60 -strict -2 -f flv rtmp://<destination/streamkey>

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