When extracting Audio streams using ffmpeg from containers such as MP4, how does ffmpeg increase bitrate, if it is higher than the source bitrate?
An example might be ffmpeg -i video.mp4 -f mp3 -ab 256000 -vn music.mp3. What does ffmpeg do if the incoming bitrate is 128k? Does it interpolate or default to 128k on the output music.mp3? I know this seems like not a so-called "programming question" but ffmpeg forum says it is going out of business and no one will reply to posts there.
During transcoding, ffmpeg (or any transcoder) decodes the input into an uncompressed version; for audio, that's PCM. The encoder compresses this PCM data. It has no idea of, or interaction with, the original source representation.
If no bitrate is specified, ffmpeg will use the default rate control mode and bitrate of the encoder. For MP3 or AAC, that's typically 128 kbps for a stereo output . Although it can be lower, like 96 kbps for Opus. Encoders typically adjust based on no. of output channels. So for a 6-ch output, it may be 320 kbps. If a bitrate is specified, that's used unless the value is invalid (beyond the encoder's range). In which case, the encoder will fallback on its default bitrate selection.
Related
From what I understand, the overall bitrate of a file is a sum of the bitrate of all streams(video and audio) and the container bitrate. Ffmpeg provides option to set video bitrate and audio bitrate individually using -b:v and -b:a flags.
Can we set a bitrate for the whole file using ffmpeg and let it calculate the individual stream bitrates on its own?
I am using ffmpeg to rotate videos 90 or 180 degrees in a Python script. It works great. But, I am curious as to why the output file would be a smaller amount of bytes than the input file.
Here are the commands I use:
180 degrees:
ffmpeg -i ./input.mp4 -preset veryslow -vf "transpose=2,transpose=2,format=yuv420p" -metadata:s:v rotate=0 -codec:v libx264 -codec:a copy ./output.mp4
90 degrees:
ffmpeg -i ./input.mp4 -vf "transpose=2" ./output.mp4
For example, a GoPro Hero 3 MP4 file was originally 2.0 GB. The resulting output file was 480.9 MB. Another GoPro file was 2.0 and its resulting file was 671.5 MB. Is this maybe because the GoPro files were 2.0 but contains empty space, sort of like how some NTFS filesystems make a minimal 4k file, even when there is less bytes in it?
If this isn't the GoPro Hero 3, how do I rotate the files 90 or 180 degrees but ensure the output file size is the same? Or, is data loss expected? Does the data loss have to do with the format?
Note that the quality of the video doesn't appear to be damaged, which is good. So, I am interested in learning more about why this is happening, then I can read the section of ffmpeg documentation that is relevant to this.
Thank you!
Bitrate is ignored from the start
ffmpeg fully decodes the input into uncompressed raw video and audio (except when stream copying – more about that below). The input format or bitrate does not matter: it does this for all formats. The encoder then works from these raw, decoded frames. See diagram.
H.264 vs H.264
Your input and output are both H.264. A format, such as H.264, is created by an encoder. Anyone can make an encoder. However, not all encoders are equal. Given the same input, the output from one H.264 encoder may have the same quality as an output from another H.264 encoder, but the bitrate may be several times smaller.
The GoPro H.264 encoder was made to work on a platform with limited hardware. That means bitrate (file size) is sacrificed for speed and quality. x264 is the ultimate H.264 encoder: nothing can beat its quality-to-bitrate ratio.
Rotate without re-encoding
You can stream copy (re-mux) and rotate at the same time. The rotation is handled by the metadata/sidedata:
ffmpeg -i input.mp4 -metadata:s:v rotate=90 -c copy output.mp4
Downside is your player/device may ignore the rotation, so you may have to physically rotate with filters which requires re-encoding, and therefore stream copy can't be used.
I had the same rotation issue once...
I fixed it by "resetting" the rotation instead...
ffmpeg ...... -metadata:s:v rotate="0" ......
I am trying to change the sampling rate of an M4a file from 44100Hz to a customized value let's say 51200Hz. I used the followng command which worked fine with wav sampling rate conversion:
ffmpeg -i audio.m4a -ar 51200 audio_51200.m4a
Unfortunately, it generates a file with a 48000 Hz sampling rate. Any ideas?
There is a limited set of frequencies for AAC profiles. For example for HE AAC:
http://www.atsc.org/wp-content/uploads/2015/03/A153-Part-8-2012.pdf
So ffmpeg adjust any non-standard frequency to nearest available
Update: The set of available sampling frequencies is limited by AAC ADIF (Audio Data Interchange Format) and ADTS (Audio Data Transport Stream). So other rates just can't be encoded. Here are values for field sampling_frequency_index form subclause 8.1.1.2 in ISO/IEC 13818-7 standard:
Recommendations for selecting sample frequency:
I'm trying to perform a real-time encoding of a video using HEVC with ffmpeg. I'm able to achieve the required performance when running the x265 encoder separately without the support of ffmpeg. This way the my system can perform the encoding at 30 frames per second. However, my requirement is to create a MPEG-TS stream with the encoded content and therefore, the video is encoded with the ffmpeg as follows:
ffmpeg -s:v 1280x720 -i input.yuv -c:v libx265 -x265-params crf=20:keyint=25:fps=25:preset=ultrafast -f mpegts out.ts
Strangely, the performance of the encoding is reduced drastically and I'm only able to achieve an encoding performance of just 10 frames per second.
Is this a problem of the multiplexing process within ffmpeg?. Could someone please help me to resolve this issue.
Thanks.
This is can be a reason q factor in FFmpeg. You need to compare q value of FFmpeg and x265 bin. This is my guess.
Say I have something like this
ffmpeg -i video.avi -ar 22050 -ab 32 -f flv -s 320x240 video.flv
-ar (Audio sampling rate in Hz)
-ab (Audio bit rate in kbit/s)
regarding the -ar and the -ab how do I know what rate to use? I got this ffmpeg command from a site somewhere and I was wondering how the person knew what values to put for the rates? Do I need to understand audio in order to figure that out?
Probably 44100 for audio sampling rate and 128 for bit rate should be sufficient.
Check Wikipedia's sampling rate and audio bit rate articles for examples to see if those values are too high or too low for what you're trying to do.
You have to use "ffmpeg -i video.avi" to know the sampling rate and the bitrate of the audio stream in the source video.avi.
The audio stream can be extracted with the same sampling rate and bitrate without lose quality.
You can decide to reduce one of them for size reasons, but don't increment one of them to increase quality because you never can't upgrade the original quality.
I'm using -ar 22050 and -ab 48 for Avi and Mpeg video files. It works normally.