Vue框架怎麼使用mediainfo.js來檢測視訊檔案是否有音軌?

yihailin發表於2022-01-21

啥是MediaInfo?

簡而言之,MediaInfo是一個能讀取音訊和視訊檔案並分析和輸出音視訊資訊的工具,能輸出的內容包括視訊資訊,音軌,字幕等。

MediaInfo也可以在web端使用,需要使用到mediainfo.js。mediainfo.js 是MediaInfoLib通過WebAssembly技術封裝來的,也是可以支援檢視音視訊的資訊,
本文重點介紹下vue框架要怎麼使用mediainfo.js。

vue框架使用mediainfo.js

web端可以通過兩種方式來使用mediainfo.js

  • CDN: <script type="text/javascript" src="https://unpkg.com/mediainfo.js/dist/mediainfo.min.js"></script>
  • Bundler: npm install mediainfo.js

因為mediainfo.js依賴於MediaInfoModule.wasm, 目前需要保持mediainfo.jsMediaInfoModule.wasm在同個服務路徑,即web瀏覽器會從同個路徑下去
請求mediainfo.jsMediaInfoModule.wasm
CDN版本已經自動載入了MediaInfoModule.wasm了,需要注意的是通過npm方式載入的,需要在webpack檔案配置下。官網介紹了react和augular怎麼配置MediaInfoModule.wasm,
但是沒有Vue版本的。

假設你用的vue2.0,在專案路徑下的vue.config.js目錄下加入以下配置

  • 使用copy-webpack-plugin將MediaInfoModule.wasm拷貝到構建路徑
const CopyPlugin = require('copy-webpack-plugin')
const wasmFile = resolve('node_modules/mediainfo.js/dist/MediaInfoModule.wasm')
  • 配置webpack plugin
  configureWebpack: {
    plugins: [
      new CopyPlugin([{ from: wasmFile, to: '.' }]),
    ]
  }

注意上面的new CopyPlugin([{ from: wasmFile, to: '.' }])這個是webpack版本比較低的寫法。我按照React/webpack
的寫法會提示copy plugin patterns 需要的引數是array,索引改成了陣列傳入就編譯成功了。版本比較高的應該是

 new CopyPlugin({
      patterns: [
        { from: wasmFile, to: '.' },
        { from: 'CNAME', to: '.' },
      ],
    }),
  • 匯入使用
<template>
  <Content>
    <Upload
      ref="upload"
      :show-upload-list="true"
      :on-success="handleSuccess"
      :format="imageFormat"
      :max-size="imageSize"
      :on-format-error="handleFormatError"
      :on-exceeded-size="handleMaxSize"
      :before-upload="handleBeforeUpload"
      :data="uploadData"
      type="drag"
      action="/api/v1/image_upload"
      style="display: inline-block;width:58px;"
      v-show="showUploadBtn===true"
    >
      <div style="width: 58px;height:58px;line-height: 58px;">
        <Icon type="ios-camera" size="20"></Icon>
      </div>
    </Upload>
  </content>
</template>

import mediainfo  from 'mediainfo.js'

export default {
  ......
  methods: {
    handleBeforeUpload(file) {
      var vm = this
      const getSize = () => file.size
      const readChunk = (chunkSize, offset) =>
      new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = (event) => {
          if (event.target.error) {
            reject(event.target.error)
          }
          resolve(new Uint8Array(event.target.result))
        }
        reader.readAsArrayBuffer(file.slice(offset, offset + chunkSize))
      })
      mediainfo().then((mediainfo) =>{
        mediainfo
        .analyzeData(getSize, readChunk)
        .then((result) => {
          if (result['media'] !== undefined) {
            console.log(result['media'])
            let track = result['media']['track']
            if (track !== undefined) {
              for (let i = 0; i < track.length; i++) {
                if (track[i]['@type'] === 'Audio') {
                  console.log(track[i])
                  this.$Message.warning({
                    content: `當前視訊有音軌`
                  })
                }
              }
            }
          }
        })
        .catch((error) => {
          console.log(`An error occured:\n${error.stack}`)
        })
      })
    }
  }
}

頁面元件用的iview的Upload元件,在回撥方法:before-upload="handleBeforeUpload"裡可以取到file物件,然後分塊讀取檔案內容,
由mediainfo讀取內容後輸出顯示

總結123

  1. 通過mediainfo.js 可以在web頁面線上解析音視訊的引數
  2. vue等web框架需要通過配置webpack配置,在打包時需要通過copy-webpack-plugin外掛拷貝到dist目錄
  3. 在web端需要結合upload等元件使用,取得file物件後使用mediainfo().then((media)=>{//you code})進行分析

參考:

相關文章