The issue had been there perhaps for a while but only got caught until recently as the project moves on to user interface. We found the MP4 videos generated by GStreamer were not playable on browser. We tried to play the file on IE, Edge, Firefox, Chrome, none of them took the MP4. Well, to be precise, only if VLC was not embedded.
In other words, the MP4 files worked fine on VLC, either in local file mode or in network stream (http) mode. That’s part of the reason we didn’t realized there could be a problem. Given MP4 is such a widely used format, I was a little surprised by running into the road block.
For the purpose of troubleshooting, I created a webpage with a MP4 I created on TX2 and a short video from NASA for reference, and in each case I applied two methods of access, by href link and by HMTL5 video tag.
http://jmrcubed.com/cdn_v07/sdb/demo/mp4av/
Given the URL addresses, I ran ffprobe to compare the stream formats, using the command
ffprobe -i -show_format -hide_banner -show_streams
For the NASA video (playable on all major browsers and VLC), I got:
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=1/60
codec_tag_string=avc1
codec_tag=0x31637661
width=1280
height=720
coded_width=1280
coded_height=720
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=31
color_range=N/A
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
timecode=N/A
refs=1
is_avc=1
nal_length_size=4
id=N/A
r_frame_rate=30/1
avg_frame_rate=30/1
time_base=1/30
start_pts=0
start_time=0.000000
duration_ts=3493
duration=116.433333
bit_rate=2527807
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=3493
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
TAG:creation_time=1970-01-01 00:00:00
TAG:language=und
TAG:handler_name=VideoHandler
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/44100
codec_tag_string=mp4a
codec_tag=0x6134706d
sample_fmt=fltp
sample_rate=44100
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0avg_frame_rate=0/0
time_base=1/44100
start_pts=0
start_time=0.000000
duration_ts=5135360
duration=116.448073
bit_rate=192015
max_bit_rate=202248
bits_per_raw_sample=N/A
nb_frames=5015
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
TAG:creation_time=2015-02-12 21:50:26
TAG:language=eng
TAG:handler_name=IsoMedia File Produced by Google, 5-11-2011
[/STREAM]
[FORMAT]
filename=http://jmrcubed.com/cdn_v07/sdb/demo/mp4av/nasa2.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=116.446667
size=39625399
bit_rate=2722303
probe_score=100
TAG:major_brand=mp42
TAG:minor_version=0
TAG:compatible_brands=isommp42
TAG:creation_time=2015-02-12 21:50:26
[/FORMAT]
For MP4 from TX2’s GStreamer, I got:
[STREAM]
index=0
codec_name=hevc
codec_long_name=HEVC (High Efficiency Video Coding)
profile=Main
codec_type=video
codec_time_base=1/90000
codec_tag_string=[36][0][0][0]
codec_tag=0x0024
width=1280
height=480
coded_width=1280
coded_height=480
has_b_frames=0
sample_aspect_ratio=0:1
display_aspect_ratio=0:1
pix_fmt=yuv420p
level=120
color_range=tv
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=unspecified
timecode=N/A
refs=1
id=0x41
r_frame_rate=30/1
avg_frame_rate=30/1
time_base=1/90000
start_pts=324000000
start_time=3600.000000
duration_ts=3324000
duration=36.933333
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[15][0][0][0]
codec_tag=0x000f
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=0x42
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/90000
start_pts=324000000
start_time=3600.000000
duration_ts=3327359
duration=36.970656
bit_rate=36375
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
[/STREAM]
[FORMAT]
filename=http://jmrcubed.com/cdn_v07/sdb/demo/mp4av/2cam_640x480.mp4
nb_streams=2
nb_programs=1
format_name=mpegts
format_long_name=MPEG-TS (MPEG-2 Transport Stream)
start_time=3600.000000
duration=36.970656
size=19347832
bit_rate=4186635
probe_score=100
[/FORMAT]
Here is the GStreamer command I was using to generate the MP4 video (two cameras on a customized CSI board with DMICs):
gst-launch-1.0 nvcamerasrc sensor-id=1 \
! 'video/x-raw(memory:NVMM), width=1920, height=1080, framerate=30/1, format=NV12' \
! nvvidconv flip-method=4 \
! video/x-raw, width=640, height=480, framerate=30/1, format=I420 \
! textoverlay text='camLeft' \
! mixer.sink_0 \
nvcamerasrc sensor-id=0 \
! 'video/x-raw(memory:NVMM), width=1920, height=1080, framerate=30/1, format=NV12' \
! nvvidconv flip-method=4 \
! video/x-raw, width=640, height=480, framerate=30/1, format=I420 \
! textoverlay text='camRight' \
! mixer.sink_1 \
videomixer name=mixer sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=640 sink_1::ypos=0 \
! timeoverlay \
! omxh265enc bitrate=4000000 control-rate=2 \
! h265parse \
! tee name=t t. ! queue \
! mpegtsmux name=mux alsasrc 'device=hw:tegrasndt186ref,1' ! audioresample \
! audio/x-raw,rate=48000,channels=2 ! queue ! voaacenc bitrate=32000 ! aacparse \
! queue ! mux. mux. \
! filesink location=2cam_640x480.mp4 -e
By Google search, I found a thread on this forum regarding the issue of playing MP4 on browser,
https://devtalk.nvidia.com/default/topic/1024757/jetson-tx2/tx2-h264-encoded-videos-will-not-play-in-web-browsers/
Apparently the “level” values are different, of which is level=120 in my MP4, versus level=31 in NASA video. The symptom matches what was described in the article.
Assuming the setting of “level” is the culprit, it’s still not clear to me how to fix the problem though. Could anyone elaborate the procedure in further details?
Many thanks in advance!