【问题标题】:Audio Recording Functionality with two buttons, one to start recording, other to stop recording带有两个按钮的录音功能,一个用于开始录音,另一个用于停止录音
【发布时间】:2023-03-22 00:04:01
【问题描述】:

我对 Vue.js 编程非常陌生,我想做的是一个简单的录音机,它可以在单击录制按钮时开始录制音频,并在单击停止按钮时停止录制。停止时应在模板中显示音频文件并将音频存储在 blob 中,该 blob 稍后应存储在本地。

我已经实现了模板如下:

<template>
    <!-- Voice Record Title + Button -->
    <div class="form-group row">
        <label for="Audio" class="col-2 col-form-label labelTop">Audio</label>
        <div class="col-1">
            <button @click="recordAudio()" type="button" id="button_record" class="btn btn-danger">
            </button>
            <button type="button" id="button_stop" class="btn btn-success">
            </button>
            <div id="audio" class="audio" controls>
            </div>
        </div>
    </div>
</template>

脚本包含以下代码:

export default {
    methods: {
        recordAudio() {
            var device = navigator.mediaDevices.getUserMedia({ audio: true });
            var items = [];
            device.then((stream) => {
                var recorder = new MediaRecorder(stream);
                recorder.ondataavailable = (e) => {
                    items.push(e.data);
                    if (recorder.state == "inactive") {
                        var blob = new Blob(items, { type: "audio/*" });
                        var audio = document.getElementById("audio");
                        var mainaudio = document.createElement("audio");
                        mainaudio.setAttribute("controls", "controls");
                        audio.appendChild(mainaudio);
                        mainaudio.innerHTML =
                            '<source src="' +
                            URL.createObjectURL(blob) +
                            '" type="audio/*" />';
                    }
                };
                recorder.start();
                // I do not want a timeout to stop the recording but clicking the stop button to do so
                setTimeout(() => {
                    recorder.stop();
                }, 5000);
            });
        },
    },
};

这听起来可能很简单,但我现在唯一想做的是它会在几秒钟后停止录制而不使用此超时功能,而是在点击button_stop 时停止录制。 我尝试了很多东西,例如使用

直接将事件处理程序设置为button_stop
@click="recorder.stop()" 

也可以:

if (document.getElementById("button_stop").clicked == true) {
                recorder.stop();
                }

还有:

document.getElementById("button_stop").addEventListener("click", recorder.stop());
                if (document.getElementById("button_stop").clicked == true) {
                    recorder.stop();
                }

但这些都没有真正的作用。

由于我通常对 Vue 和 Javascript 很陌生,这真的让我很沮丧。 如果有任何帮助,我将不胜感激。

【问题讨论】:

    标签: javascript vue.js dom-events audio-recording getusermedia


    【解决方案1】:

    您应该能够通过将recorder 分配给组件中的变量来实现此目的,而不仅仅是在您的函数中。这样,您以后可以在单击按钮时调用this.recorder.stop()

    试试:

    data() {
      return {
        recorder: null
      }
    },
    methods: {
        recordAudio() {
          var device = navigator.mediaDevices.getUserMedia({ audio: true });
          device.then((stream) => {
            // use this!
            this.recorder = new MediaRecorder(stream);
            this.recorder.ondataavailable = (e) => {
               // ....
            };
          });
        },
        // called on button click
        stop() {
          this.recorder.stop()
        }
    }
    

    模板:

    <button type="button" id="button_stop" class="btn btn-success" @click="stop">
    

    【讨论】:

    • 非常感谢,已解决!该死的,我真的很感激!
    • 很抱歉再次打扰您,但是您是否也有解决此问题的方法? stackoverflow.com/questions/63493329/…
    • 谢谢你!为我工作得很好!在此之后将发布我的完整组件!
    【解决方案2】:

    这里我的父组件启动了 recordAudio 和 stop 方法。完成录制后,数据将发送到父级以发送到另一个子级并从那里发送到服务器。有点像 whatsapp 语音消息,结果被 psoted 到上面的聊天中。

    <template>
      <!-- Voice Record -->
      <div>
        <v-btn @click="recordAudio()">
          <v-icon> mdi-microphone </v-icon>
        </v-btn>
        <v-btn @click="stop()">
          <v-icon> mdi-stop-circle-outline </v-icon>
        </v-btn>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          recorder: null,
          chunks: [],
          device: null,
          blobObj: null,
        };
      },
    
      created() {
        this.device = navigator.mediaDevices.getUserMedia({ audio: true });
      },
      methods: {
        
        recordAudio() {
          this.device.then((stream) => {
            this.recorder = new MediaRecorder(stream);
            this.recorder.ondataavailable = (e) => {
              this.chunks.push(e.data);
              if (this.recorder.state === "inactive") {
                let blob = new Blob(this.chunks, { type: "audio/wav" });
                // save to blobObj
                this.blobObj = blob;
                this.chunks = [];
                // emit to parent
                this.$emit("send-audio", this.blobObj);
                this.blobObj = null;
              }
            };
            // start
            this.recorder.start();
          });
        },
        stop() {
          // stop
          this.recorder.stop();
        },
      },
    };
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多