FFMPEG H.264 encoding for HTML5 (and ultimately MP

2020-07-20 00:05发布

问题:

I want to convert an MP4 file to an MPEG-DASH video capable of being played through the DASH-IF HTML5 player on Chrome. I use FFMPEG and MP4Box (from GPAC) to transcode the video and then split it, and keep getting a MEDIA_ERR_SRC_NOT_SUPPORTED error on the JavaScript console.

From the (very sparse) information available online (see this Chromium thread), it would appear as though Chrome natively only supports MP4 files with the Constrained Baseline encoding profile, and is very strict on only supporting the "avc1.42E01E,mp4a.40.2" codecs.

I have tried pretty much everything I can to encode the video from the command line, prior to splitting with MP4Box, with FFMPEG to get an H.264 video encoding with codec profile "avc1.42E01E", but it just keeps giving me "avc1.42C01E". Here's one of the (many) FFMPEG commands I've tried:

ffmpeg -y -i Sintel_-_Third_Open_Movie_by_Blender_Foundation.mp4 -profile:v baseline -level:v 30 -acodec libvo_aacenc -vcodec libx264 sintel-recoded.mp4

According to the ITU-T standard, sections 7.4.2.1.1 and A2.1-A2.3, a video encoding of "avc1.42E01E" implies constraint flags of 0xE0 (constraint_set flags 0, 1 and 2 are set), whereas "avc1.42C01E" implies constraint flags of 0xC0 (constraint_set flags 0 and 1 are set). The former (0xE0) implies conformance to the Baseline, Main and Extended profiles, whereas the latter (0xC0) implies conformance to only the Baseline and Main profiles.

Apparently, FFMPEG doesn't support the Extended profile for H.264.

Does anyone perhaps have any advice as to how to encode an MP4 file as "avc1.42E01E"? Ideally with FFMPEG, but I am open to using other encoders?

回答1:

After digging around online for ages, and asking questions in a few places like GitHub, I found that part of the problem was that I wasn't separating my audio and video prior to segmenting with MP4Box:

# transcode the video to "avc1.42c00d,mp4a.40.2"
ffmpeg -i Sintel_-_Third_Open_Movie_by_Blender_Foundation.mp4 -c:v libx264 -c:a libvo_aacenc -profile:v baseline -level:v 13 -g 250 -r 25 -keyint_min 250 -strict experimental -b:a 96k sintel.mp4

# copy out the video only
ffmpeg -i sintel.mp4 -c:v copy -an sintel-video.mp4

# copy out the audio only
ffmpeg -i sintel.mp4 -c:a copy -vn sintel-audio.mp4

# create the MPD manifest with MP4Box, but only with onDemand profile
MP4Box -dash 10000 -profile dashavc264:onDemand -out sintel.mpd sintel-audio.mp4 sintel-video.mp4

Plays just fine in Chrome 40.x with the dash.js player. Trouble is, it doesn't work for the live MP4Box profile (with separate M4S files for each segment), but it's at least a start.

Edit: I've since had a lot more success with preparing and fragmenting my content using castLabs' DASH.encrypt utility. See the wiki entries for details on how to make use of the utility. Still haven't managed to get my content DASH'd with MP4Box unfortunately.



回答2:

If you are not forced to use ffmpeg, I would suggest to give x264 a try, like the guys from dash-player.com described in one of their blog posts. From my experience I can definitely say, that Chrome supports far more than one profile for video.