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

时间:2017-07-01 12:20:21

标签: javascript php laravel mediarecorder getusermedia

我是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)


     <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>

1 个答案:

答案 0 :(得分:0)

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

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

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');
}