html5 audio总结

前言

 

  html5中对音频,视频播放原生支持.最近作了一个音乐播放器,得益于快过年了,才能抽出一点时间来总结一下.总的来讲,html5对audio的支持很是强大, 难怪flash要死.浏览器上装播放插件的时代已经接近尾声了.目前大多数浏览器都支持了大部分经常使用的api,ie8及其之前除外(万恶的ie啊).css

  HTML5 音频虽然很健壮,但有其局限性,这主要取决于它的实现。对于音乐播放器(点唱机播放器)或简单的声音效果,它颇有效,可是对于声音密集的应用程序如游戏,它的表现不是很理想。因此有了Web Audio API (Chrome) 和 Audio Data API (Firefox) 无需任何浏览器插件便可进行合成和动态处理音频的能力来帮助人们解决特性缺失的问题.Web Audio与audio标签不一样,它给了开发者对音频数据进行处理、分析的能力,例如混音、过滤等,相似于对音频数据进行PS。通常的网站应用应该是用不倒这些API中的,可是一些游戏引擎或者在线音乐编辑等类型的网站应该用获得。请参考文章最后的参考资料.html

 

兼容状况

 

可见除了ie6,7,8 和opera,其余都支持了.其中安卓在2.1就已经支持了.audio的兼容性仍是不错的,固然这只是audio标签.JavaScript接口的支持状况就各不相同了,可能会遇到坑.html5

 

API

原本想贴上audio的api,后来发现太多了,就放弃了.有不少都是不经常使用的.咱们这里就讨论几个经常使用的api和属性.ios

详情请参考w3c http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp git

总结的过程当中也发现audio和video的api是如出一辙的.这也方便了广大开发者的学习使用.github

 

重要方法

  • 这3个方法是最基础的了,看方法名就知道是干吗用的了.其中load方法,通常是在改变audio的一些属性后,须要从新加载的状况下使用.

 

重要属性

  • autoplay 设置是否自动播放音频/视频,ios的Safari下不能自动播放,须要和用户交互后才能播放,这是个坑,后面会详细说.
  • buffered 会返回一个TimeRanges对象,包含一个起点和终点时间,若是用户拖动音频/视频,则有多个buffer区间,能够经过index访问指定buffer区间.

 

  • currentTime 是很是重要的一个属性了,能够返回当前的播放位置(以秒计),同时也能够设置播放位置,跳跃播放音频.

 

  • played 返回已经播放部分的TimeRanges对象,能够用于作一些计算

 

  • seekable 表示用户当前能够跳跃观看的以缓冲部分区间
  • src 音频/视频资源地址

 

  • volume 控制音量

 

重要事件

  • 加载过程的事件流对咱们作一些特殊处理是颇有帮助的

 

  • canplay 加载ok,能够播放时触发,通常逻辑都从这里开始
  • canplaythrough 当所有加载完毕时触发

 

  • 正在下载时触发,配合buffered属性更新加载进度条的逻辑就能够放在这里

 

  • 用户跳跃播放时触发

 

  • 当前播放位置改变时触发,更新播放时间,同步歌词的逻辑均可以放在这里

 

封装audio

  从audio提供的api来讲,已经很是强大和完善了.若是是在移动端,咱们彻底能够尽量的使用原生api,不必使用第三方库.我简单封装了一下audio,尽量的保持原生api的最大灵活性前提下,减小咱们的代码量.web

js代码chrome

;(function(){

    var _init = function(){
        var audio = this.audio = document.createElement('audio');
        for( var prop in this.audioProp ){
            audio[prop]  = this.audioProp[prop];
        }
        document.body.appendChild(audio);
    };

    var _bindEvt = function(){
        var audio  = this.audio,
            audioEvt = this.audioEvt;
        for( var func in audioEvt ){
            audio.addEventListener(func,audioEvt[func].bind(this),false);
        }
    };

    var _extend = function(o1,o2){
        for(var attr in o2)    {
            o1[attr] = o2[attr];
        }
        return o1;
    };

    /*
     *   构造函数
     */
    function Constructor(opton){
        opton =    _extend({
            audioProp : {

            },
            audioEvt : {
            
            },
            cssSelector : {
                
            }
        
        },opton);

        _extend(this,opton);
        _init.call(this);
        _bindEvt.call(this);
    }

    _extend(Constructor.prototype,{
        /*
         *   播放
         *     second 指定当前的播放时间 
         */
        play : function(second){
            second && (this.audio.currentTime = second);
            this.audio.play();        
        },

        /*
         *   暂停
         *   second 指定当前的播放时间
         */
        pause : function(second){
            second && (this.audio.currentTime = second);
            this.audio.pause();    
        },


        /*
         *   时间格式化
         *     00:00
         */
        timeFormat : function timeFormat(number) {
            var minute = parseInt(number / 60);
            var second = parseInt(number % 60);
            minute = minute >= 10 ? minute : "0" + minute;
            second = second >= 10 ? second : "0" + second;
            return minute + ":" + second;
        }
    
    });


    //兼容amd,cmd,原生js接口
    if(typeof module !== 'undefined' && typeof exports === 'object' && define.cmd){
        module.exports = Constructor;    
    }else if(typeof define === 'function' && define.amd){
        define(function(){
            return Constructor;    
        });
    }else{
        window.APlayer = Constructor;    
    }

})();

html代码编程

        var music = new APlayer({
            audioProp : {
                title : '给我一个理由忘记',
                loop : true,
                src : "https://ss1.baidu.com/8aQDcnSm2Q5IlBGlnYG/stat/ogg/xinsui.mp3",
            },
            audioEvt : {
                canplay : function(){
                },
                timeupdate : function(){
                    $('.currentTime').html(this.timeFormat(this.audio.currentTime));  
                }
            }

        });

        $(".play").on("touchend",function(){
            music.play();    
        });
        $(".pause").on("touchend",function(){
            music.pause(5);    
        });

详情能够看个人github   https://github.com/Alan110/desire/tree/master/APlayerapi

 

坑爹集锦

 

编程总不会这么一路顺风,莫名其妙的问题老是不会少的.下面就罗列一下我遇到的坑吧.

  1.  安卓uc浏览器下,对timeupdate事件支持很差,只会不多的触发几回.这是什么概念,就是说咱们基本上不能同步当前的播放时间和进度条了,还有歌词.

    解决方案:暂时没有

  2.  在ios,Safari下,不能自动播放,autoplay,preload属性无效. 或者audio.src='xx' , 加载完后手动调用audio.play()也是不行的.

    缘由: 在ios,Safari下要求与用户交互后才加载歌曲,播放歌曲,如touchstart , touchend , click等事件. 

    解决方案 : 在iphone4下touchstart无效, 目测是由于性能不够没法捕捉. 改用touchend就行了

  3.  ios,Safari同一时间只能播放但音频/视频

    解决方案 : 使用 audio sprite 是知足移动 Safari 中多音效需求的最佳解决方案。与 CSS image sprite 相似,audio sprite 能够将全部的音频综合到一个音频流.要注意的是更改 currentTime 并非百分百正确的。

           将 currentTime 设为 6.5,而实际获得的倒是 6.7 或 6.2。每一个 A sprite 之间须要少许的空间,以免寻找到另外一个 sprite 的尾部。

// audioSprite has already been loaded using a user touch event
var audioSprite = document.getElementById('audio');
var spriteData = {
    meow1: {
        start: 0,
        length: 1.1
    },
    meow2: {
        start: 1.3,
        length: 1.1
    },
    whine: {
        start: 2.7,
        length: 0.8
    },
    purr: {
        start: 5,
        length: 5
    }
};

// play meow2 sprite
audioSprite.currentTime = spriteData.meow2.start;
audioSprite.play();
View Code

    记得播放完毕手,要手动中止

var handler = function() {
    if (this.currentTime >= spriteData.meow2.start + spriteData.meow2.length) {
        this.pause();
    }
};
audioSprite.addEventListener('timeupdate', handler, false);
View Code

 

音频在低版本浏览器中的兼容

 

现代浏览器基本上都支持audio了,老版本的浏览器,如ie8及其之前的.兼容方案可能是用flash来播放音频/视频.在页面中嵌入embed标签,或者object标签,来调用flash插件.

网上找了2段代码,手中无ie浏览器并不肯定是否可用,看到的朋友慎重使用

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="1" height="1">

  <param name="movie" value="flash/music.swf" />

  <param name="quality" value="high" />

  <embed src="flash/music.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="1" height="1"></embed>

</object>
View Code
if(navigator.userAgent.indexOf("Chrome") > -1){
     若是是Chrome:
     <audio src="" type="audio/mp3" autoplay=”autoplay” hidden="true"></audio>
    }else if(navigator.userAgent.indexOf("Firefox")!=-1){
     若是是Firefox:
     <embed src="" type="audio/mp3" hidden="true" loop="false" mastersound></embed>
    }else if(navigator.appName.indexOf("Microsoft Internet Explorer")!=-1 && document.all){
      若是是IE(6,7,8):
      <object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95"><param name="AutoStart" value="1" /><param name="Src" value="" /></object>
    }else if(navigator.appName.indexOf("Opera")!=-1){
       若是是Oprea:
       <embed src="" type="audio/mpeg"   loop="false"></embed>
    }else{
       <embed src="" type="audio/mp3" hidden="true" loop="false" mastersound></embed>
    }
View Code

window.HTMLAudioElement  能够经过这个属性来判断是否支持audio

另一个解决方案就是使用第三方库了,这里推荐一个库jplayer,听说是支持ie7+和其余的浏览器

jplayer中文文档

 

总结

 

过年啦,祝你们新年快乐!  2016年但愿我能成长得更多.

 

参考资料

 

相关文章
相关标签/搜索