2017-07-01 42 views
1

我是Laravel和vue.js的新手。我正在嘗試使用getNavigatorMedia和MediaRecorder。在測試它捕獲媒體流時,它似乎沒有傳入我在數據對象中創建的屬性,因爲它們保持爲空。我試圖在實際方法中創建變量,但這不起作用。vue.js/laravel無法設置屬性'ondataavailable'爲空

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(\t 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"> 
 
    \t <i class="stop icon" v-show="isRecording"></i> 
 
     <span v-show="isRecording">Stop recording</span> 
 
    \t <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>

回答

0

Javascript本質上是異步的,這意味着稍後在腳本中的邏輯不會等待先前的邏輯完成。發生什麼事是你試圖綁定到MediaRecorder之前,Vue屬性audioRecorder甚至是一個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'); 
}