我试图检测浏览器何时不会播放特定的视频。一个很好的例子就是试图检测Chrome不能播放H.265/HEVC编码的视频。
我试着用视频回退:
<video>
<source [src]="attachmentVideo" type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'>
Browser does not support the HTML5 Video element.
</video>然而,我了解到,只有当浏览器不支持视频时,才能使用回退。因此,对于支持视频的Chrome,不执行回退,但视频将无法播放。
接下来,我试图侦听错误事件。
<video (error)="onError($event)">
<source [src]="attachmentVideo" type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'>
Browser does not support the HTML5 Video element.
</video>但是,我也没有看到错误事件。
为了好玩,我还附加了onplay事件,以确保事件发生。这个事件确实有可能发生。
<video (canplay)="onCanPlay($event)">
<source [src]="attachmentVideo" type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'>
Your browser does not support the HTML5 Video element.
</video>有没有可能没有外部库来检测浏览器是否支持视频和特定的编解码器?
发布于 2022-04-18 15:47:53
要检查是否通过JavaScript支持编解码器,请查看下面的选项对您是否有用:
(即:将所选的代码转换为角度语法/代码)
(1)如果编解码器已知.使用canPlayType检查编解码器的兼容性。
var vid = document.getElementById("myVideoElementID");
if( vid.canPlayType('video/mp4; codecs="hev1"') )
{ alert("can play HVC1 / H.265 "); }
else if( vid.canPlayType('video/mp4; codecs="avc1"') )
{ alert("can play AVC1 / H.264 "); }(2)如果编解码器未知.检查编解码器类型的文件字节(然后执行步骤(1)以确认可玩性)
这意味着获取文件字节的一部分(例如,获取第一个64 at或最后一个64 at,取决于MP4头是在文件的前面还是后面)。
将数据读取到数组中,然后搜索该数组中的stsd部分,这是MP4保存H264数据序列参数集(SPS)的地方,您可以从该部分提取编解码器信息。
( a)找到stsd位置。
( b)从该位置跳过+16字节以查找avc1或hev1。
( c)从+16 pos跳过+91以获得SPS (3个字节)。
下面是一个使用选定(本地)文件的示例,该文件通过FileReader API读入数组。
<!DOCTYPE html>
<html>
<body>
<!-- button Choose MP4 Video -->
<div style="z-index: 1; overflow:hidden; position: absolute; top: 18px; left: 10px; " >
<text> <b> Choose a Video (.MP4) file...</b> <br>
<input type="file" id="choose_video" accept=".mp4" />
</div>
<video id="myVideo" width="640" height="480" controls style="position: absolute; top: 80px; left: 10px; " >
<source src="" type="video/mp4">
</video>
</body>
<script>
var temp_int = 0; var temp_str = ""; var temp_arr = [];
var reader; var path;
var fileBytes; //# is updated to: uint8Array []
var file; //# a File object (using Reader)
//# codec name (is String object)
var str_codec = "-1";
var myvid = document.getElementById( 'myVideo' );
addEventListener("load", on_page_Ready );
function on_page_Ready()
{
//# listener for selecting MP4 file
document.getElementById('choose_video').addEventListener('change', onSelectFile, false);
}
function onSelectFile(evt)
{
file = evt.target.files[0]; //# FileList object
path = (window.URL || window.webkitURL).createObjectURL(file);
reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
fileBytes = new Uint8Array( evt.target.result );
//# extract codec info
get_MP4_Codec( fileBytes );
//# load video data and play ...
myvid.setAttribute("src", path);
myvid.load();
myvid.play();
}
}
}
function get_MP4_Codec (inBA)
{
let idx = 0; //# index (position) in bytes
while(true)
{
//# auto stop if "stsd" not found after 32 kilobytes
if ( (idx > 32000) || (idx >= inBA.length-1) ) { break; }
//# look for starting "s" (is byte value 0x73)
if( inBA[ idx ] == 0x73 ) //# find "s"
{
//# check if next following 3 bytes are the required values
if( (inBA[ idx+1 ] == 0x74) && //# find "t"
(inBA[ idx+2 ] == 0x73) && //# find "s"
(inBA[ idx+3 ] == 0x64) //# find "d"
)
{
//# when found...
//# note the "stsd" position
temp_int = idx;
//# skip forward by 16 bytes to get codec type
//# codec type can be "avc1" or "hev1" or "hvc1"
idx += 16;
str_codec = String.fromCharCode( inBA[ idx+0 ] );
str_codec += String.fromCharCode( inBA[ idx+1 ] );
str_codec += String.fromCharCode( inBA[ idx+2 ] );
str_codec += String.fromCharCode( inBA[ idx+3 ] );
//# need that dot "." also
str_codec += ".";
//# skip forward by 91 bytes to get codec SPS details
//# example"avc1.64001f" the SPS is "64001F"
idx += 91;
temp_str = (inBA[idx].toString(16)).toUpperCase();
str_codec += temp_str.length === 2 ? temp_str : '0' + temp_str;
idx += 1;
temp_str = (inBA[idx].toString(16)).toUpperCase();
str_codec += temp_str.length === 2 ? temp_str : '0' + temp_str;
idx += 1;
temp_str = (inBA[idx].toString(16)).toUpperCase();
str_codec += temp_str.length === 2 ? temp_str : '0' + temp_str;
break;
}
}
idx++;
}
alert("found STSD @ byte pos : " + temp_int +"\n"+ "codec type : " + str_codec );
}
</script>
</html>https://stackoverflow.com/questions/71803915
复制相似问题