H5 Audio ES6版 系列教程之一

EER發表於2018-03-16

js 實現原生 Audio 初探版

再也不用擔心面試問到H5用到哪些新元素了,大神如我 小弟用js原生實現了 抄了 Audio,Video還會遠嗎?

本專案基於 ES6+scss+webpack 開發的原生 JS 版 H5 Audio ,此次分享的目的是讓前端對 H5 的 Audio 有更深的瞭解,同時對現代前端技術也有個大致的瞭解,最終可以基於 vuereact 開發一個 H5 版的 網易音樂,QQ 音樂...

由於工作中有音訊方面的需求,所以該專案也是自己作為迭代的記錄。意味著,這將是一個系列教程。

預覽地址,訪問可能會比較慢。 gitHub地址

教程

實現原生音訊無外乎兩個部分

首先要先了解 Aduio 的屬性和方法。

關於 Audio 元素的介紹,推薦 MDN

UI

首先原生 audio 元素是必不可少的,我們也可以直接新增 controls 屬性來使用瀏覽器實現的 UI。

<audio id="myaudio" src="/static/test.mp3" controls></audio>
複製程式碼

基礎的 DOM 結構應該包括:

  • 播放按鈕
  • 進度條
  • 聲音控制
  • 當前時間/總時長

總體結構建議使用語義化元素,樣式類名命名參考BEM。音訊建議考慮 視覺障礙者 ,可引入 無障礙

這邊簡單講一下進度條的實現。通過 input 型別中 rangeprogress 可以大大降低 DOM 結構複雜度及提高語義化。

其中涉及到改瀏覽器原生樣式讀者可自行谷歌。也可以參考本專案原始碼

<div class="myaudio__controls">
    <button type="button" data-myaudio="play"></button>
    <span class="myaudio__progress">
        <input class="myaudio__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-myaudio="seek">
        <progress class="myaudio__progress--played" max="100" value="0" role="presentation"></progress>
        <progress class="myaudio__progress--buffer" max="100" value="20.43"></progress>
    </span>
    <span class="myaudio__time--current">00:00</span>
    <span class="myaudio__time--duration">00:20</span>

    <button type="button" data-myaudio="mute"></button>

    <span class="myaudio__volume">
        <input class="myaudio__volume--input" type="range" min="0" max="10" value="10" data-myaudio="volume">
        <progress class="myaudio__volume--display" max="10" value="10" role="presentation">
        </progress>
    </span>
</div>
複製程式碼

Event

事件與 DOM 元素密不可分,而音訊主要分兩個方向去監聽事件。使用者自定義的 DOM 元素事件監聽,Audio 原生事件監聽。涉及的知識點是 addEventListenter自定義事件

本次 Audio 外掛基於 Es6 的 class 開發。最終可以直接通過 例項化來生成一個 audio 物件

我們先從配置檔案來大致瞭解下開發一個 Audio 所用到的配置項。

export default {
  // 配置對應功能
  controls: ['play', 'progress', 'current-time', 'duration', 'mute', 'volume'],

  // 基於iconfont,SVG版,如需替換圖片,
  // 可直接匯入自己的iconfont檔案,修改對應圖片類名即可
  icon: {
    play: 'icon-bofang',
    pause: 'icon-bofangzanting',
    muted: 'icon-jingyin',
    volume: 'icon-shengyin'
  },

  // 配置是否自動播放
  autoplay: false,

  // 聲音控制相關
  volumeMin: 0,
  volumeMax: 10,
  volume: 10,

  // 播放器HTML結構
  html: '',

  // Debugger 相關
  logPrefix: '日誌:',
  debug: true,

  // 整體思路是通過控制全域性狀態類名,來設定對應樣式
  classes: {
    setup: 'myaudio--setup',
    ready: 'myaudio--ready',
    stopped: 'myaudio--stopped',
    playing: 'myaudio--playing',
    muted: 'myaudio--muted',
    loading: 'myaudio--loading',
    hover: 'myaudio--hover',
    isIos: 'myaudio--is-ios',
    isTouch: 'myaudio--is-touch'
  },

  // 狀態儲存相關
  storage: {
    enabled: true,
    key: 'myaudio'
  },

  // 選擇器相關
  selectors: {
    container: '.myaudio',
    controls: {
      container: null,
      wrapper: '.myaudio__controls'
    },
    labels: '[data-myaudio]',
    buttons: {
      seek: '[data-myaudio="seek"]',
      play: '[data-myaudio="play"]',
      pause: '[data-myaudio="pause"]',
      mute: '[data-myaudio="mute"]'
    },
    volume: {
      input: '[data-myaudio="volume"]',
      display: '.myaudio__volume--display'
    },
    progress: {
      container: '.myaudio__progress',
      buffer: '.myaudio__progress--buffer',
      played: '.myaudio__progress--played'
    },
    currentTime: '.myaudio__time--current',
    duration: '.myaudio__time--duration'
  },

  // 主要功能涉及以下 5 個事件
  // 事件相關
  listeners: {
    seek: null,
    play: null,
    pause: null,
    mute: null,
    volume: null
  }
};
複製程式碼

從配置檔案可以大概瞭解總體思路。下次分享將從原始碼解析的角度進一步講解 Audio 原生實現。

其他分享

以下推薦閱讀,讀者可選讀:

快速執行

在前端的世界裡,所碼即所得。當我想要了解一個專案的時候,我會直接執行看效果。

接下來,假設你已經具備一定的前端工程化開發經驗。

cd ~/Desktop
git clone https://github.com/leer0911/myAudio.git
cd myAudio
npm i
npm run dev
複製程式碼

參考

感謝 plyr,可以說本教程是對它的一次原始碼解析。

相關文章