I asked in another question (http://stackoverflow.com/questions/8012494/sorry-this-video-cannot-be-played-streaming-mp4-to-android/8012874#8012874) about video playback in android using VideoView. Apparently, the problem there is due to the way my video is encoded, as another video (512Kb mp4 off the web) plays correctly using my code. As videos are uploaded by my end users to the web site, I don't have any control of the videos themselves, however I do have control over re-coding these. I re-code them using ffmpeg
to bring them to a standard MP4 (H.264+AAC) format and scale them to the same size (320x240).
Here's the ffmpeg info of a video that would not play:
sh-3.2$ ffmpeg -i video.bad.mp4
FFmpeg version SVN-r25679-snapshot, Copyright (c) 2000-2010 the FFmpeg developers
built on Nov 5 2010 09:34:37 with gcc 4.3.2
configuration: --prefix=/usr --enable-shared --enable-libmp3lame --enable-gpl --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-libgsm --enable-x11grab --enable-libx264 --enable-libtheora --extra-cflags=-Wall --enable-swscale --enable-libdc1394 --enable-nonfree --disable-mmx --disable-stripping --enable-avfilter --disable-altivec --disable-armv5te --disable-armv6 --disable-vis --enable-nonfree --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-version3
libavutil 50.32. 6 / 50.32. 6
libavcore 0.12. 0 / 0.12. 0
libavcodec 52.94. 3 / 52.94. 3
libavformat 52.84. 0 / 52.84. 0
libavdevice 52. 2. 2 / 52. 2. 2
libavfilter 1.56. 0 / 1.56. 0
libswscale 0.12. 0 / 0.12. 0
libpostproc 51. 2. 0 / 51. 2. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.bad.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf52.84.0
Duration: 00:00:45.93, start: 0.000000, bitrate: 591 kb/s
Stream #0.0(und): Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 535 kb/s, 15 fps, 15 tbr, 15 tbn, 30 tbc
Stream #0.1(und): Audio: aac, 48000 Hz, stereo, s16, 51 kb/s
And here's the ffmpeg info of a video that plays correctly:
sh-3.2$ ffmpeg -i video.mp4
FFmpeg version SVN-r25679-snapshot, Copyright (c) 2000-2010 the FFmpeg developers
built on Nov 5 2010 09:34:37 with gcc 4.3.2
configuration: --prefix=/usr --enable-shared --enable-libmp3lame --enable-gpl --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-libgsm --enable-x11grab --enable-libx264 --enable-libtheora --extra-cflags=-Wall --enable-swscale --enable-libdc1394 --enable-nonfree --disable-mmx --disable-stripping --enable-avfilter --disable-altivec --disable-armv5te --disable-armv6 --disable-vis --enable-nonfree --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-version3
libavutil 50.32. 6 / 50.32. 6
libavcore 0.12. 0 / 0.12. 0
libavcodec 52.94. 3 / 52.94. 3
libavformat 52.84. 0 / 52.84. 0
libavdevice 52. 2. 2 / 52. 2. 2
libavfilter 1.56. 0 / 1.56. 0
libswscale 0.12. 0 / 0.12. 0
libpostproc 51. 2. 0 / 51. 2. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: mp41
title : crazytown - http://www.archive.org/details/Cartoon-Crazytown
encoder : Lavf51.10.0
Duration: 00:07:50.40, start: 0.000000, bitrate: 578 kb/s
Stream #0.0(und): Video: h264, yuv420p, 320x240, 510 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc
Stream #0.1(und): Audio: aac, 48000 Hz, stereo, s16, 63 kb/s
I have two questions here, actually. First, which of the details in my "bad" video does android not like? And, second, what parameters should I use with ffmpeg to recode my videos? As present I use this:
ffmpeg -i $input_video_file -y -s 320x240 -vcodec libx264 -vpre medium -acodec libfaac -b 510K -ar 48000 -aspect 4:3 $tmpfile.mp4
qt-faststart $tmpfile.mp4 $output_video_file.mp4
But this produces a video that's not playable on android. Any help is greatly appreciated.
First, your version of ffmpeg is over a year old. A lot has improved with ffmpeg and H.264 since last year. Please try upgrading to at least ffmpeg-0.7.
It's a little difficult to tell exactly where the problem is because ffmpeg isn't displaying all the options passed to x264 for H.264 encoding. Try increasing the verbosity of ffmpeg output (using
-v 1
or-v 2
somewhere near the beginning of the ffmpeg command). But based on my experience using ffmpeg to transcode videos for Android, my guess is that you're not using the H.264 Baseline profile (see the wikipedia article on H.264 if you're curious). Try adding-profile baseline
if you have ffmpeg-0.7 or later.If you can't upgrade your ffmpeg for some reason or another, you can specify the Baseline profile by using the
-vpre baseline
option after you specify-vpre medium
. If for some reason you get an error trying to use the Baseline preset, you can manually force the Baseline options by specifying-coder 0 -bf 0 -flags2 -wpred-dct8x8
on the command line after the-vpre medium
.