| 4 min read

Detecting browser compatibility for HTML5 video and audio

原文链接 https://www.nomensa.com/blog/2011/detecting-browser-compatibility-html5-video-and-audio

近期接触播放器项目,所以对 video 除了基本的 api 的了解,还需要做好对应的兼容性。Chrome 最早在 11年开始了对于 video 的支持,不同的浏览器当时对于格式支持也是不同。

  • 浏览器对于 video 元素的支持情况*
    目前对于

其中对于 MPEG-4/H.264 的支持还是比较广泛的

至于大家比较关心的 webm ,在移动端和 safari 上支持还不是特别理想。

而最新的 HEVC/H.265 的支持情况浏览器方便的支持还是非常不理想。

好在 video 提供了一些列方法让我们能够探测到是否能够对给出的文件进行正常播放。

判断 mimeType

我们需要根据我们视频的类型然后去进行格式的判断以及其获取它的编码格式。

var get_mime = function(filetype) {
    var mimetype = '';
    var media_container = 'video';
    switch (filetype) {
        case 'mp4':
            mimetype = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
            break;
        case 'ogg':
            mimetype = 'video/ogg; codecs="theora, vorbis"';
            break;
        case 'webm':
            mimetype = 'video/webm; codecs="vp8, vorbis"';
            break;
        case 'mp3':
            mimetype = 'audio/mpeg';
            media_container = 'audio';
            break;
    }
    return {
        'mimetype': mimetype,
        'container': media_container
    };
};

上面的代码会根据传入的类型进行判断,我们会手动进行 mime type 的设置,然后返回对应的编码器。通过这些信息我们便可以进行信息支持度的判断。

判断浏览器支持

接下来根据我们刚刚获取的 mimetype 信息 以及,设置的元素来判断这个资源是否可以播放。

var supports_media = function(mimetype, container) {
    var elem = document.createElement(container);
    if (typeof elem.canPlayType == ‘ function’) {
        var playable = elem.canPlayType(mimetype);
        if ((playable.toLowerCase() == 'maybe') || (playable.toLowerCase() == 'probably')) {
            return true;
        }
    }
    return false;
};

这两个参数分别是:

  • Mimetype 表示 mimetype 以及需什么样的解码器 'video/webm; codecs="vp8, vorbis"'

  • Container 表示播放资源的元素比如 video / audio

通过这两个参数,我们就可以在JS 内存中构建该元素,然后调用 canplay 方法,然后判断是否支持播放。canplay 接受一个 mimetype 的字符串,然后会返回:

  • '' 空字符串(不能播放)
  • 'maybe'
  • 'probably'

如果浏览器可以确定播放的话,它会返回 probably 。而如果不能播放则会返回一个空字符串。

完整的代码

// Define the get_mime function
var get_mime = function(filetype) {
    var mimetype = '';
    var media_container = 'video';
    switch (filetype) {
        case 'mp4':
            mimetype = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
            break;
        case 'ogg':
            mimetype = 'video/ogg; codecs="theora, vorbis"';
            break;
        case 'webm':
            mimetype = 'video/webm; codecs="vp8, vorbis"';
            break;
        case 'mp3':
            mimetype = 'audio/mpeg';
            media_container = 'audio';
            break;
    }
    return {
        'mimetype': mimetype,
        'container': media_container
    };
};

// Check to see if the browser can render the file type
// using HTML5
var supports_media = function(mimetype, container) {
    var elem = document.createElement(container);
    if (typeof elem.canPlayType == ‘ function’) {
        var playable = elem.canPlayType(mimetype);
        if ((playable.toLowerCase() == 'maybe') || (playable.toLowerCase() == 'probably')) {
            return true;
        }
    }
    return false;
};

// When the DOM has loaded check the file extension of each media link
// and serve up appropriate media player
$(document).ready(function() {
    $(‘a.youtube - links’).each(function() {

        var path = $(this).attr(‘href’);

        var extension = path.substring(path.lastIndexOf('.') + 1);

        var extension_info = get_mime(extension);

        if (supports_media(extension_info.mimetype, extension_info.container)) {

            // Serve up an HTML5 Media Player and controls

            serve_html5();

        } else {


            //will not play the file using HTML5

            serve_flash();

        }

    });
});

参考

You Can Speak "Hi" to Me in Those Ways