vue.js /laravel 无法设置 属性 'ondataavailable' 为 null

vue.js /laravel Cannot set property 'ondataavailable' of null

我是 Laravel 和 vue.js 的新手。我正在尝试使用 getNavigatorMedia 和 MediaRecorder。在测试中它正在捕获媒体流,但似乎流没有传递到我在数据对象中创建的属性中,因为它们仍然为空。我尝试在实际方法中创建变量,但这不起作用。

Attached please find my code and below is the reported error. If anyone could point me in the right direction it would be much appreciated.

Uncaught TypeError: Cannot set property 'ondataavailable' of null
    at VueComponent.toggleRecording (record:104)
    at Proxy.boundFn (vue.js:167)
    at click (eval at makeFunction (vue.js:9252), <anonymous>:2:152)
    at HTMLButtonElement.invoker (vue.js:1732)


<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre><code>     <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.3.4/vue-resource.js" type="text/javascript"> </script>
    <script src ="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
    <script>

    Vue.component('record', {
    template: '#record-template',


      data: function () {
            return {
                isRecording: false,
                audioRecorder: null,
                recordingData: [],
                dataUrl: ''
            };
        },
    methods:
        {
          //method to start and stop the recording process
            toggleRecording: function() {
              var that = this;
              this.isRecording = !this.isRecording;

              if (this.isRecording) {
                  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
                  navigator.getUserMedia({
                          audio: true,
                          video: false
                      }, function(stream) {
                          that.stream = stream;
                          that.audioRecorder = new MediaRecorder(stream, {
                              mimeType: 'audio/webm;codecs=opus',
                              audioBitsPerSecond : 96000
                          });

                          that.audioRecorder.start();

                          console.log('Media recorder started');

                      }, function(error) {
                          alert(JSON.stringify( error));
                  });
              }
              else {
                  this.audioRecorder.stop();
              }

                  this.audioRecorder.ondataavailable = function(event) {
                    that.recordingData.push(event.data);

                  }
                  this.audioRecorder.onstop = function(event) {
                    console.log('Data available after MediaRecorder.stop() called');
                    // var audio = document.createElement('audio');
                    // audio.controls = true;

                    var blob = new Blob(that.recordingData, { type: 'audio/ogg'});
                    that.dataUrl = window.URL.createObjectURL(blob);
                    // audio.src = dataUrl;
                    console.log("recorder stopped");
                  }

            },

            //method to remove a recording that was saved previously
            removeRecording: function() {
              this.isRecording = false;
              this.recordingData = [];
              this.dataUrl = '';

            },
            //method to  start and stop the playback process
            togglePlay: function() {
              var audioElement = document.getElementById("audio");
              if (audioElement.paused === false) {
                  audioElement.pause();
              } else {
                  audioElement.play();
              }
              // var handleSuccess = function(stream) {
                // if (window.URL) {
                //   audioElement.src = window.URL.createObjectURL(stream);
                // } else {
                //   audioElement.src = stream;
                // }




            },
            //method to submit the recording to the API using  vue-resource
            submitRecording: function() {
            }
        },


    });


     new Vue({
        el: '#app'


    });

    </script>
    <div id="app">
    <h1>Test</h1>
    <record>
    </record>
    </div>

    <template id="record-template">
    <div>

    <button class="button red-button" v-on:click.stop.prevent="toggleRecording">
     <i class="stop icon" v-show="isRecording"></i>
      <span v-show="isRecording">Stop recording</span>
     <i class="record icon" v-show="!isRecording"></i>
      <span v-show="!isRecording">Start recording</span>
    </button>

    <button id="remove-recording" class="remove-recording" v-if="dataUrl.length > 0" v-on:click.stop.prevent="removeRecording">
        <i class="remove icon"></i> Delete recording
    </button>


    <button id="send-recording" class="button green-button" v-if="dataUrl.length > 0">
        <i class="send icon"></i> Send recording
    </button>


    <button class="button green-button" v-if="dataUrl.length > 0" v-on:click.stop.prevent="togglePlay">
        <i class="play icon"></i> Play recording
    </button>
    </div>
    <audio id="audio" preload="auto" v-model="dataUrl"></audio>


    </template>

Javascript 本质上是异步的,这意味着脚本中后面的逻辑不会等待前面的逻辑完成。发生的事情是您试图在 Vue 属性 audioRecorder 甚至是 MediaRecorder 对象之前绑定到 MediaRecorder。

尝试在流回调中移动事件绑定。这还需要您将 属性 范围从 this 更改为 that 用于那些绑定

function(stream) {
  that.stream = stream;
  that.audioRecorder = new MediaRecorder(stream, {
      mimeType: 'audio/webm;codecs=opus',
      audioBitsPerSecond : 96000
  });

  // event bindings
  that.audioRecorder.ondataavailable = function(event) {
    that.recordingData.push(event.data);
  }

  that.audioRecorder.onstop = function(event) {
    console.log('Data available after MediaRecorder.stop() called');
    // var audio = document.createElement('audio');
    // audio.controls = true;

    var blob = new Blob(that.recordingData, { type: 'audio/ogg'});
    that.dataUrl = window.URL.createObjectURL(blob);
    // audio.src = dataUrl;
    console.log("recorder stopped");
  }

  that.audioRecorder.start();

  console.log('Media recorder started');
}