base_ui/components/other/MyAudioRecorder.vue

225 lines
6.3 KiB
Vue
Raw Permalink Normal View History

2025-02-01 09:34:55 +00:00
<template>
<div class="my-vue-audio-recorder">
<button
v-if="!recorder"
@click.prevent="record()"
class="btn start-record-btn"
>
<svg class="icon icon-Component-85--1">
<use xlink:href="#icon-Component-85--1"></use>
</svg>
</button>
<button v-else @click.prevent="stop()" class="btn send-record-btn">
<svg class="icon icon-Component-236--1">
<use xlink:href="#icon-Component-236--1"></use>
</svg>
</button>
<button
@click.prevent="cancel()"
class="btn remove-record-btn"
:class="{ recording: recorder }"
>
<svg class="icon icon-Component-295--1">
<use xlink:href="#icon-Component-295--1"></use>
</svg>
</button>
</div>
</template>
<script>
// import "assets/common/js/RecordRTC.js";
/**
* @vue-data {Object|null} [newAudio=null] - صدای جدید
* @vue-data {Object|null} [recorder=null] - ضبط کننده
* @vue-data {Boolean} [saveAudio=false] - نشان میدهد که آیا صدای ضبط شده ذخیره شود یا خیر
* @vue-data {Array} [recordedChunks=[]] - تکههای صدای ضبط شده
*/
export default {
mounted() {
// this.uuid = Math.floor(Math.random() * 100);
// addJsCssFileToDom("/js/RecordRTC.js", "js", this.uuid);
// this.getLocalStream();
},
destroy() {
this.recorder?.removeEventListener("dataavailable", onDataAvailable);
this.recorder?.removeEventListener("stop", onStopRecording);
},
data() {
return {
newAudio: null,
recorder: null,
saveAudio: false,
recordedChunks: [],
};
},
computed: {
// newAudioURL() {
// return URL.createObjectURL(this.newAudio);
// },
},
methods: {
/**
* هنگامی که دادههای صوتی در دسترس هستند، این متد اجرا میشود.
* تکههای ضبط شده را ذخیره کرده و یک رویداد ارسال میکند.
*
* @param {Event} e - رویداد دادههای موجود
*/
onDataAvailable(e) {
this.recordedChunks = [];
this.$emit("onStream");
if (e.data.size > 0) {
this.recordedChunks.push(e.data);
}
},
/**
* توقف ضبط و پردازش جریان رسانهای.
* تکههای ضبط شده را به یک Blob تبدیل کرده و آن را ارسال میکند.
*
* @param {Event} mediaStream2 - رویداد جریان رسانهای
*/
onStopRecording(mediaStream2) {
this.newAudio = new Blob(this.recordedChunks);
this.recorder.stop();
const audioTracks = mediaStream2.target.stream.getAudioTracks();
audioTracks.forEach((element) => {
element.stop();
});
this.recorder = null;
if (this.saveAudio) this.$emit("send", this.newAudio);
},
/**
* شروع ضبط صدا.
* درخواست دسترسی به میکروفون کاربر و شروع ضبط صدا.
*/
async record() {
this.newAudio = null;
try {
const mediaStream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false,
});
// const options = { mimeType: "audio/webm" };
// this.recorder = new MediaRecorder(mediaStream, options);
this.recorder = new MediaRecorder(mediaStream);
this.recorder.start();
this.recorder.addEventListener("dataavailable", this.onDataAvailable);
this.recorder.addEventListener("stop", this.onStopRecording);
} catch (err) {
mySwalToast({
title:
"مرورگر شما از قابلیت ارسال صدا پشتیبانی نمیکند.لطفا مرورگر خود را به آخرین ورژن ارتقا دهید.",
icon: "error",
timer: 7000,
});
}
},
/**
* توقف ضبط و ذخیره فایل صوتی.
*/
stop() {
this.saveAudio = true;
this.recorder.stop();
},
/**
* لغو ضبط بدون ذخیره فایل صوتی.
*/
cancel() {
this.saveAudio = false;
this.recorder.stop();
},
// با استفاده از پلاگین
// getLocalStream() {
// try {
// navigator.mediaDevices
// .getUserMedia({
// video: false,
// audio: true,
// })
// .then(async function (stream) {
// let recorder = RecordRTC(stream, {
// type: "audio",
// });
// recorder.startRecording();
// const sleep = (m) => new Promise((r) => setTimeout(r, m));
// await sleep(3000);
// recorder.stopRecording(function () {
// let blob = recorder.getBlob();
// invokeSaveAsDialog(blob);
// });
// });
// navigator.mediaDevices
// .getUserMedia({ video: false, audio: true })
// .then((stream) => {
// window.localStream = stream; // A
// window.localAudio.srcObject = stream; // B
// window.localAudio.autoplay = true; // C
// })
// .catch((err) => {
// console.error(`you got an error: ${err}`);
// });
// } catch (err) {
// let localStream = new MediaStream();
// let localAudioTrack;
// let localVideoTrack;
// let localVideo;
// const userMediaConstraints = {
// video: true,
// audio: true,
// };
// navigator.mediaDevices = localStream;
// .getUserMedia(userMediaConstraints)
// .then((stream) => {
// localAudioTrack = stream.getAudioTracks()[0];
// localAudioTrack.enabled = true;
// localStream.addTrack(localAudioTrack);
// });
// }
// },
},
};
</script>
<style scoped lang="scss">
// .vue-audio-recorder {
// position: relative;
// background-color: #4db6ac;
// border-radius: 50%;
// width: 64px;
// height: 64px;
// display: inline-block;
// cursor: pointer;
// -webkit-box-shadow: 0 0 0 0 rgba(232,76,61,.7);
// box-shadow: 0 0 0 0 rgba(232,76,61,.7);
// width: 1.9em;
// height: 1.9em;
// padding: 0.5em;
// background-size: 70%;
// background-position: center center;
// background-repeat: no-repeat;
// &.active {
// background-color: #ef5350;
// -webkit-animation: pulse 1.25s cubic-bezier(.66,0,0,1) infinite;
// animation: pulse 1.25s cubic-bezier(.66,0,0,1) infinite;
// }
// }
</style>