遊戲陪玩系統開發,音視訊混流的實現程式碼

雲豹科技程式設計師發表於2021-11-15

遊戲陪玩系統開發過程中,對於音視訊資料的處理會涉及到很多方面,像音視訊編解碼、首屏秒開等,其中音視訊混流也是非常關鍵的一項技術,並且做好音視訊混流才能帶給使用者更好的視聽體驗,接下來我們就一起看看在遊戲陪玩系統原始碼開發中如何將多個音視訊流混合後匯出吧。

主要用的API有:

  • MediaRecorder(提供的用來進行遊戲陪玩系統媒體輕鬆錄製的介面)
  • getUserMedia(捕獲攝像頭、麥克音視訊流)
  • getAudioTracks(從stream流中獲取音訊流集合)
  • addTrack(往stream流中增加媒體流)
  • AudioContext(AudioContext物件,可對遊戲陪玩系統中的音訊進行處理)
  • createBufferSource(該介面是一個音訊源,它由儲存在一個儲存器中的記憶體中音訊資料組成)
  • createMediaStreamDestination(建立一個媒體流的節點)
  • decodeAudioData(可用於非同步解碼音訊檔案中的 ArrayBuffer)

1、建立一個BGM音訊流

  • 用的到介面:AudioContext、createBufferSource、createMediaStreamDestination、decodeAudioData
// 建立AudioContext例項var audioCtx = new AudioContext()// 建立一個音訊源var source = audioCtx.createBufferSource()// 建立一個媒體流節點var track = audioCtx.createMediaStreamDestination()

ok,到這裡為止,我們BGM的關鍵物件都齊全了,不過這些只有容器,沒有最重要的內容。剛剛我們說了decodeAudioData這個api,這個api可以將資料解碼音訊中的ArrayBuffer。

// 獲取BGM的檔案的arraybuffervar request = new XMLHttpRequest();request.open('GET', './music/test.mp3', true);request.responseType = 'arraybuffer';request.onload = function() {
  // 這裡我們通過ajax請求將檔案轉arraybuffer格式
  var audioData = request.response;
  audioCtx.decodeAudioData(audioData, function(buffer) {
    // 這裡的buffer就是解碼過的arraybuffer
    // 將buffer加入音訊源裡
    source.buffer = buffer    // 將音訊輸出到一個媒體流節點上
    source.connect(track)
    // 重複播放BGM
    source.loop = true;
    // 播放緩衝區的音訊資料
    source.start(0)
  })}request.send();

到這裡為止,我們已經將遊戲陪玩系統中BGM的音訊捕獲到了,接下來就是將其合進攝像頭和麥克捕獲的音視訊流內。

2、遊戲陪玩系統捕獲攝像頭音視訊流

navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true}).then(function(stream) {
  // stream這裡就是我們捕獲的攝像頭音視訊流
  // 將BGM內的音訊流提取出來
  var bgmAudioTrack = track.stream.getAudioTracks()[0]
  // 這裡track.stream是重媒體流節點裡的媒體流,getAudioTracks這才是從流內獲取音訊流集合
  // stream新增音訊流
  stream.addTrack(bgmAudioTrack)})

現在我們獲取到的就是混音之後的音視訊了,之後就是將媒體匯出本地了

3、下載多媒體

var start = document.getElementById('start')var stop = document.getElementById('stop')const chunks = null// 建立MediaRecorder例項(這裡可以看之前的文章)var mediaRecorder = new MediaRecorder(stream, {
  audioBitsPerSecond : 128000,
  videoBitsPerSecond : 100000,
  mimeType : 'video/webm;codecs=h264'})start.onclick = function () {
  mediaRecorder.start()
  console.log('開始採集')}stop.onclick = function () {
  mediaRecorder.stop()
  console.log('停止採集')}mediaRecorder.onstop = function (e) {
  var blob = new Blob([chunks], { 'type' : 'video/mp4' })
  let a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = `test.mp4`
  a.click()}mediaRecorder.ondataavailable = function(e) {
  chunks = e.data}

ok,這下就大功告成了。

<!DOCTYPE html><html lang="en"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>音視訊混流</title></head><body>
  <button id="button">開啟攝像頭</button>
  <button id="start">開始採集</button>
  <button id="stop">停止採集</button></body><script>
  var button = document.getElementById('button')
  var start = document.getElementById('start')
  var stop = document.getElementById('stop')
  var audioDom2 = document.querySelector('#audio2')
  var audioCtx = new AudioContext();
  var source = audioCtx.createBufferSource()
  var track = audioCtx.createMediaStreamDestination();
  button.onclick = function () {
    navigator.mediaDevices.getUserMedia({
      audio: true,
      video: true
    })
    .then(function(stream) {
      stream.addTrack(track.stream.getAudioTracks()[0])
      /* 使用這個stream stream */
      var mediaRecorder = new MediaRecorder(stream, {
        audioBitsPerSecond : 128000,
        videoBitsPerSecond : 100000,
        mimeType : 'video/webm;codecs=h264'
      })
      start.onclick = function () {
        mediaRecorder.start()
        console.log('開始採集')
      }
      stop.onclick = function () {
        mediaRecorder.stop()
        console.log('停止採集')
      }
      mediaRecorder.onstop = function (e) {
        var blob = new Blob([chunks], { 'type' : 'video/mp4' })
        let a = document.createElement('a')
        a.href = URL.createObjectURL(blob)
        a.download = `test.mp4`
        a.click()
      }
      mediaRecorder.ondataavailable = function(e) {
        console.log(e)
        chunks = e.data      }
    })
    .catch(function(err) {
      console.log(err)
      /* 處理error */
    });
  }
  function getData() {
    var request = new XMLHttpRequest();
    request.open('GET', './music/test.mp3', true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
      var audioData = request.response;
      audioCtx.decodeAudioData(audioData, function(buffer) {
          source.buffer = buffer;
          source.connect(track)
          source.loop = true;
          source.start(0)
        },
        function(e){"Error with decoding audio data" + e.err});
    }
    request.send();
  }
  getData()</script></html>

以上便是“實現遊戲陪玩系統中音視訊混流的相關程式碼”的相關程式碼,當遊戲陪玩系統實現音視訊混流後,使用者的體驗感會更好,更有利於使用者的留存,希望能給大家帶來幫助。

本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:https://www.cnblogs.com/suyuanli/p/10227235.html


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2842271/,如需轉載,請註明出處,否則將追究法律責任。

相關文章