Reputation: 11834
I have two videos (.mp4) files. One uploads to whatsapp and another does not.
Using ffmpeg I checked their properties:
a) Properties of video which uploads:
Duration: 00:00:56.45, start: 0.148000, bitrate: 1404 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1080x1080, 1359 kb/s, 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (HE-AACv2) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 47 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
b) video which does not upload to whatsapp (because its says format not supported)
Duration: 00:00:56.10, start: 0.000000, bitrate: 543 kb/s
Stream #0:0: Video: h264 (High) (H264 / 0x34363248), yuv420p, 1080x1080 [SAR 1:1 DAR 1:1], 464 kb/s, 23.98 fps, 23.98 tbr, 23.98 tbn, 47.95 tbc
Stream #0:1: Audio: aac (LC) ([255][0][0][0] / 0x00FF), 48000 Hz, stereo, fltp, 56 kb/s
The difference in video I noticed:
(avc1 / 0x31637661)
vs (H264 / 0x34363248)
1359 kb/s
vs 464 kb/s
90k tbn
vs 23.98 tbn
What can be the reason?
Also the second video is not being played in Android.
The link for the video is https://drive.google.com/open?id=0B4UM6vTHw4pyMExQQ1lxZGp0N2c
Upvotes: 62
Views: 38736
Reputation: 43
Copying @teocci's answer for powershell:
ffmpeg -i 'input.mp4' `
-c:v libx264 -pix_fmt yuv420p `
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -vb 1024k `
-acodec aac -ar 44100 -ac 2 `
-minrate 1024k -maxrate 1024k -bufsize 1024k `
-movflags +faststart `
output.mp4
If you video already has aac:
ffmpeg -i 'input.mp4' `
-c:v libx264 -pix_fmt yuv420p `
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -vb 1024k `
-acodec copy `
-minrate 1024k -maxrate 1024k -bufsize 1024k `
-movflags +faststart `
output.mp4
Check out the original answer for mode details. Not allowed to comment so posting an answer instead
Upvotes: 0
Reputation: 8935
I tried all previous commands and I got some errors. I was able to encode my video using this command and here is the explanation and why I set it up like this for a better compatibility:
ffmpeg -i input.mp4 \
-c:v libx264 -pix_fmt yuv420p \
-profile:v baseline -level 3.0 \
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -vb 1024k \
-acodec aac -ar 44100 -ac 2\
-minrate 1024k -maxrate 1024k -bufsize 1024k \
-movflags +faststart \
output.mp4
-acodec aac -ar 44100 -ac 2
to -acodec copy
to preserve the audio quality.option | explanation |
---|---|
-vcodec libx264 |
Chooses video encoder libx264 |
-pix_fmt yuv420p |
Ensures YUV 4:2:0 chroma subsampling for compatibility |
-profile:v baseline |
Set the encoding profile to baseline. Used primarily for low-cost applications that require additional data loss robustness |
-level 3.0 |
Set the operating point level to 3.0 which is necessary to have compatibility with WhatsApp |
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" |
If you get not divisible by 2 error see |
-acodec aac |
Chooses audio encoder aac |
-minrate 1024k |
set min bitrate tolerance to 1024k (in bits/s). It is of little use elsewise |
-maxrate 1024k |
set max bitrate tolerance to 1024k (in bits/s). Requires bufsize to be set |
-bufsize 1024k |
set rate-control buffer size to 1024k (in bits) |
-movflags +faststart |
enables fast start for streaming |
Normally, a MP4 file has all its metadata packets stored at the end of the file, in data units named atoms. The mdat
atom is located before the moov
atom. If the file is created by adding the -movflags faststart
, the moov
atom is moved at the beginning of the MP4 file. By using this option, the moov
atom is located before the mdat
atom. This allows video playback to begin before the file has been completely downloaded.
Upvotes: 16
Reputation: 12818
2023-01-22 I used the most upvoted answer format and it worked for video, but audio was not working on iPhones. Here's what worked for me:
ffmpeg -i broken.mp4 -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -ac 2 working.mp4
I had to add -ac 2
because the audio format I had wasn't seen as stereo by iOS.
Upvotes: 5
Reputation: 971
This is worked for me in 2020
ffmpeg -i broken.mp4 -c:v libx264 -profile:v high -level 3.0 -pix_fmt yuv420p -brand mp42 fixed.mp4
Upvotes: 7
Reputation: 1702
There are some options for a better compatibility:
ffmpeg -i broken.mp4 -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p working.mp4
With -profile:v baseline -level 3.0
you make the file more compatible with most older players, including WhatsApp ;). Although, this disables some advanced features.
-pix_fmt yuv420p
is necessary to compile to baseline (YUV planar color space with 4:2:0 chroma subsampling).
Also, you can adjust other options as bitrate, framerate, audio, etc.
Source: H.264 docs
Upvotes: 126
Reputation: 6323
ffmpeg -i brokenvideo.mp4 -c:v libx264 -c:a aac fixedvideo.mp4
Also had to apply this fix: FFMPEG (libx264) "height not divisible by 2"
Upvotes: 9