前述:最近解决的一个疑难杂症,是关于audio自动播放与监听audio加载完成在ios上的兼容性问题,其表现为pc,安卓谷歌浏览器正常,ios微信,谷歌浏览器不正常。

需求:在音频加载前放置一个全局loading,音频加载完成后取消loading,并自动播放;项目为vue前端项目,兼容pc,移动端。

解决方案1(失败): 

that.audioTimer=setTimeout(function(){
   that.audioLoading = that.$loading({
            lock: true,
            text: '音频加载中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          });
        },200);
        //兼容谷歌浏览器
        audioElement.addEventListener("progress", function() {
          //关闭loading并让audio.paly()
        });
        audioElement.addEventListener("canplay", function() {
          //关闭loading并让audio.paly()
        });
        //兼容微信浏览器
        document.addEventListener("WeixinJSBridgeReady", function () {
          alert("微信")
          //关闭loading并让audio.paly()
        }, false)

问题在于addEventListener("canplay")与(“progress”)在ios微信浏览器不兼容,而在微信浏览器上类似上述的兼容微信浏览器代码根本难以实现,并且兼容这些浏览器需要写很多重复的代码,复用性不高;

解决方案2(成功): 

思路,用全局自定义方法get请求替换监听音频加载是否完成方案;

第一步,封装axios get方法

import axios from 'axios'
import { Loading } from 'element-ui'

const get = function(path, callback){
  //配置路径
  let fainalPath = path;
  if(path.indexOf("http") < 0){
    fainalPath = "http://" + Host + path;
  }

  //延时Loading
  let getloadtimer = null;
  let getloading = null;
  getloadtimer = setTimeout(function(){
    getloading = Loading.service({
      lock: true,
      text: '资源加载中...',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
    });
  },200);
  //网络不稳定Loading
  let setIntvar = null;
  let setIntvarnum = 0;
  let netLoading = null;
  setIntvar = setInterval(function(){
    if(setIntvarnum>=10){
      if(getloading != null) {
        getloading.close();
      }
      netLoading = Loading.service({
        lock: true,
        text: '网络环境不稳定,请您刷新或者重新登录...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
    }else {
      setIntvarnum += 1
    }
  },1000);
  //网络请求
  axios.get(fainalPath
    ,{headers: {
      'Content-Type':'application/json;charset=UTF-8',
      'Accept':'application/json'
    }})
    .then(function (response) {
      closeAll(getloadtimer,setIntvar,getloading,netLoading);
      callback(response)
    })
    .catch(function (error) {
      closeAll(getloadtimer,setIntvar,getloading,netLoading);
      if (error.response) {
        console.log(error.response.data);
        console.log(error.response.status);
        tipError(error.response.data.code,error.response.status,path)
      }
    })
};
<audio id="playButton" :src="audioSrc" :autoplay="autoplay" @ended="audioEnd"></audio>

第二步:在vue页面中,监听数据变幻,并加载音频;

watch: {
      'response': 'renderData'
    }

response是父组件传来的数据;renderData是子组件的数据初始化方法;在renderData里做下面的方法。

let audioSrc = "http://xxxx.com/测试.mp3";
          let audioElement = document.getElementById('playButton');
          api.get(audioSrc,function(response){
            //audioElement.load();
            audioElement.play();
          })

第三步:当你点击音频时不需要重复加载,它会从cache里去拿;

choiceAudio (id) {
  this.isEnded = 'pause';
  let audioSrc = "http:/xxxx"+ id +".mp3";
  document.getElementById('playButton').setAttribute('src', audioSrc);
  document.getElementById('playButton').load();
  document.getElementById('playButton').play();
},

总结:经过方案二,在pc,安卓,ios里都能正常运行,完美!

Logo

前往低代码交流专区

更多推荐