MP3 recording

This commit is contained in:
N-Pex 2021-12-14 13:14:51 +01:00
parent 44b8c2ef73
commit 54c8b6597d
4 changed files with 50 additions and 45 deletions

28
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "keanuapp-weblite", "name": "keanuapp-weblite",
"version": "0.1.19", "version": "0.1.21",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -7775,6 +7775,14 @@
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
"integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==" "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA=="
}, },
"lamejs": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/lamejs/-/lamejs-1.2.1.tgz",
"integrity": "sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ==",
"requires": {
"use-strict": "1.0.1"
}
},
"launch-editor": { "launch-editor": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz",
@ -8111,6 +8119,14 @@
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"dev": true "dev": true
}, },
"mic-recorder-to-mp3": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/mic-recorder-to-mp3/-/mic-recorder-to-mp3-2.2.2.tgz",
"integrity": "sha512-xDkOaHbojW3bdKOGn9CI5dT+Mc0RrfczsX/Y1zGJp3FUB4zei5ZKFnNm7Nguc9v910wkd7T3csnCTq5EtCF3Zw==",
"requires": {
"lamejs": "^1.2.0"
}
},
"micromatch": { "micromatch": {
"version": "3.1.10", "version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@ -10949,11 +10965,6 @@
"resolve": "^1.1.6" "resolve": "^1.1.6"
} }
}, },
"recordrtc": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz",
"integrity": "sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ=="
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -13015,6 +13026,11 @@
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
"dev": true "dev": true
}, },
"use-strict": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz",
"integrity": "sha1-C7gNlPSaSgUZK4Sox9NOlfGn46A="
},
"util": { "util": {
"version": "0.11.1", "version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "keanuapp-weblite", "name": "keanuapp-weblite",
"version": "0.1.21", "version": "0.1.22",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
@ -26,10 +26,10 @@
"material-design-icons-iconfont": "^6.1", "material-design-icons-iconfont": "^6.1",
"matrix-js-sdk": "^15.2.0", "matrix-js-sdk": "^15.2.0",
"md-gum-polyfill": "^1.0.0", "md-gum-polyfill": "^1.0.0",
"mic-recorder-to-mp3": "^2.2.2",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"qrcode": "^1.4.4", "qrcode": "^1.4.4",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"recordrtc": "^5.6.2",
"roboto-fontface": "*", "roboto-fontface": "*",
"v-emoji-picker": "^2.3.1", "v-emoji-picker": "^2.3.1",
"vue": "^2.6.11", "vue": "^2.6.11",

View file

@ -1,6 +1,6 @@
{ {
"name": "keanuapp-weblite", "name": "keanuapp-weblite",
"version": "0.1.20", "version": "0.1.21",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
@ -26,10 +26,10 @@
"material-design-icons-iconfont": "^6.1", "material-design-icons-iconfont": "^6.1",
"matrix-js-sdk": "^15.2.0", "matrix-js-sdk": "^15.2.0",
"md-gum-polyfill": "^1.0.0", "md-gum-polyfill": "^1.0.0",
"mic-recorder-to-mp3": "^2.2.2",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"qrcode": "^1.4.4", "qrcode": "^1.4.4",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"recordrtc": "^5.6.2",
"roboto-fontface": "*", "roboto-fontface": "*",
"v-emoji-picker": "^2.3.1", "v-emoji-picker": "^2.3.1",
"vue": "^2.6.11", "vue": "^2.6.11",

View file

@ -150,8 +150,9 @@ const State = {
import util from "../plugins/utils"; import util from "../plugins/utils";
import VoiceRecorderLock from "./VoiceRecorderLock"; import VoiceRecorderLock from "./VoiceRecorderLock";
require("md-gum-polyfill"); require("md-gum-polyfill");
import RecordRTC from "recordrtc"; import MicRecorder from "mic-recorder-to-mp3";
import ysFixWebmDuration from "fix-webm-duration"; import ysFixWebmDuration from "fix-webm-duration";
//import { duration } from "dayjs";
export default { export default {
name: "VoiceRecorder", name: "VoiceRecorder",
@ -161,19 +162,19 @@ export default {
props: { props: {
show: { show: {
type: Boolean, type: Boolean,
default: function () { default: function() {
return false; return false;
}, },
}, },
ptt: { ptt: {
type: Boolean, type: Boolean,
default: function () { default: function() {
return false; return false;
}, },
}, },
micButtonRef: { micButtonRef: {
type: Object, type: Object,
default: function () { default: function() {
return null; return null;
}, },
}, },
@ -328,25 +329,13 @@ export default {
}, },
startRecording() { startRecording() {
var constraints = { // Start recording. Browser will request permission to use your microphone.
audio: { this.recorder = new MicRecorder({
// channelCount: 1, bitRate: 128,
// sampleRate: 16000, });
echoCancellation: false, this.recorder
autoGainControl: true, .start()
noiseSuppression: true, .then(() => {
volume: 1.0,
},
video: false,
};
navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
this.recorder = RecordRTC(stream, {
type: "audio",
mimeType: "audio/webm",
});
this.recorder.startRecording();
this.state = State.RECORDING; this.state = State.RECORDING;
this.recordStartedAt = Date.now(); this.recordStartedAt = Date.now();
this.startRecordTimer(); this.startRecordTimer();
@ -363,7 +352,7 @@ export default {
this.state = State.INITIAL; this.state = State.INITIAL;
if (this.recorder) { if (this.recorder) {
this.recorder.stopRecording(); this.recorder.stopRecording();
this.recorder.destroy(); //this.recorder.destroy();
this.recorder = null; this.recorder = null;
} }
this.stopRecordTimer(); this.stopRecordTimer();
@ -391,25 +380,25 @@ export default {
this.$emit("file", { file: this.recordedFile }); this.$emit("file", { file: this.recordedFile });
}, },
getFile(send) { getFile(send) {
const duration = Date.now() - this.recordStartedAt; //const duration = Date.now() - this.recordStartedAt;
this.recorder.stopRecording(() => { this.recorder
this.correctMetadata(this.recorder.getBlob(), duration).then((blob) => { .stop()
.getMp3()
.then(([buffer, blob]) => {
// do what ever you want with buffer and blob
// Example: Create a mp3 file and play
this.recordedFile = new File( this.recordedFile = new File(
[blob], buffer,
util.formatRecordStartTime(this.recordStartedAt) + ".webm", util.formatRecordStartTime(this.recordStartedAt) + ".mp3",
{ {
type: blob.type, type: blob.type,
lastModified: Date.now(), lastModified: Date.now(),
} }
); );
//const player = new Audio(URL.createObjectURL(this.recordedFile));
//player.play();
if (send) { if (send) {
//console.log("send");
this.send(); this.send();
} }
}); });
});
}, },
startRecordTimer() { startRecordTimer() {
this.stopRecordTimer(); this.stopRecordTimer();
@ -436,7 +425,7 @@ export default {
async correctMetadata(blob, duration) { async correctMetadata(blob, duration) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
ysFixWebmDuration(blob, duration, function (fixedBlob) { ysFixWebmDuration(blob, duration, function(fixedBlob) {
const b = new Blob([fixedBlob], { type: blob.type }); const b = new Blob([fixedBlob], { type: blob.type });
resolve(b); resolve(b);
}); });