Use RecordRTC for voice messaging

This commit is contained in:
N-Pex 2021-03-23 22:24:17 +01:00
parent 6e6bae4caa
commit 2c01a0d05d
3 changed files with 51 additions and 140 deletions

115
package-lock.json generated
View file

@ -18,10 +18,10 @@
"material-design-icons-iconfont": "^5.0.1", "material-design-icons-iconfont": "^5.0.1",
"matrix-js-sdk": "^9.4.1", "matrix-js-sdk": "^9.4.1",
"md-gum-polyfill": "^1.0.0", "md-gum-polyfill": "^1.0.0",
"mic-recorder-to-mp3": "^2.2.2",
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"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",
@ -8145,14 +8145,6 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/lamejs": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/lamejs/-/lamejs-1.2.0.tgz",
"integrity": "sha1-Aln4PbRmYUGntnG4yqY2nZUXfQg=",
"dependencies": {
"use-strict": "1.0.1"
}
},
"node_modules/launch-editor": { "node_modules/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",
@ -8549,17 +8541,6 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/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==",
"dependencies": {
"lamejs": "^1.2.0"
},
"peerDependencies": {
"webrtc-adapter": ">=4.1.1"
}
},
"node_modules/micromatch": { "node_modules/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",
@ -11121,6 +11102,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/recordrtc": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz",
"integrity": "sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ=="
},
"node_modules/regenerate": { "node_modules/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",
@ -11489,19 +11475,6 @@
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz",
"integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g=="
}, },
"node_modules/rtcpeerconnection-shim": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
"integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
"peer": true,
"dependencies": {
"sdp": "^2.6.0"
},
"engines": {
"node": ">=6.0.0",
"npm": ">=3.10.0"
}
},
"node_modules/run-async": { "node_modules/run-async": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -11771,12 +11744,6 @@
"url": "https://opencollective.com/webpack" "url": "https://opencollective.com/webpack"
} }
}, },
"node_modules/sdp": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
"integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==",
"peer": true
},
"node_modules/select": { "node_modules/select": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
@ -13549,11 +13516,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/use-strict": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz",
"integrity": "sha1-C7gNlPSaSgUZK4Sox9NOlfGn46A="
},
"node_modules/util": { "node_modules/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",
@ -14894,20 +14856,6 @@
"webpack": "^4.0.0" "webpack": "^4.0.0"
} }
}, },
"node_modules/webrtc-adapter": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.0.tgz",
"integrity": "sha512-7Bp9OBnx642oJRkom1tNAbeJjUadAq2rh5xLL9YXPw5hVyt2h4hHr5bcoPYDs1stp/mZHSPSQA34YISdnr0DBQ==",
"peer": true,
"dependencies": {
"rtcpeerconnection-shim": "^1.2.15",
"sdp": "^2.12.0"
},
"engines": {
"node": ">=6.0.0",
"npm": ">=3.10.0"
}
},
"node_modules/websocket-driver": { "node_modules/websocket-driver": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
@ -21846,14 +21794,6 @@
"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.0",
"resolved": "https://registry.npmjs.org/lamejs/-/lamejs-1.2.0.tgz",
"integrity": "sha1-Aln4PbRmYUGntnG4yqY2nZUXfQg=",
"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",
@ -22187,14 +22127,6 @@
"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",
@ -24277,6 +24209,11 @@
"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",
@ -24576,15 +24513,6 @@
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz",
"integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g=="
}, },
"rtcpeerconnection-shim": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
"integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
"peer": true,
"requires": {
"sdp": "^2.6.0"
}
},
"run-async": { "run-async": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -24768,12 +24696,6 @@
"ajv-keywords": "^3.5.2" "ajv-keywords": "^3.5.2"
} }
}, },
"sdp": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
"integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==",
"peer": true
},
"select": { "select": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
@ -26236,11 +26158,6 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
}, },
"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",
@ -27300,16 +27217,6 @@
} }
} }
}, },
"webrtc-adapter": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.0.tgz",
"integrity": "sha512-7Bp9OBnx642oJRkom1tNAbeJjUadAq2rh5xLL9YXPw5hVyt2h4hHr5bcoPYDs1stp/mZHSPSQA34YISdnr0DBQ==",
"peer": true,
"requires": {
"rtcpeerconnection-shim": "^1.2.15",
"sdp": "^2.12.0"
}
},
"websocket-driver": { "websocket-driver": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",

View file

@ -19,10 +19,10 @@
"material-design-icons-iconfont": "^5.0.1", "material-design-icons-iconfont": "^5.0.1",
"matrix-js-sdk": "^9.4.1", "matrix-js-sdk": "^9.4.1",
"md-gum-polyfill": "^1.0.0", "md-gum-polyfill": "^1.0.0",
"mic-recorder-to-mp3": "^2.2.2",
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"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,10 @@
<template> <template>
<transition name="grow" mode="out-in"> <transition name="grow" mode="out-in">
<div v-show="show" :class="{'voice-recorder':true,'ptt':ptt,'row':!ptt}" ref="vrroot"> <div
v-show="show"
:class="{ 'voice-recorder': true, ptt: ptt, row: !ptt }"
ref="vrroot"
>
<!-- <div style="background-color:red;height:60px;width:100%"/> --> <!-- <div style="background-color:red;height:60px;width:100%"/> -->
<v-container v-if="!ptt" fluid fill-height> <v-container v-if="!ptt" fluid fill-height>
<v-row align="center" class="mt-3"> <v-row align="center" class="mt-3">
@ -111,7 +115,9 @@
<v-container fluid fill-height> <v-container fluid fill-height>
<v-row align="center"> <v-row align="center">
<v-col> <v-col>
<div class="swipe-info">{{ errorMessage || 'Failed to record audio' }}</div> <div class="swipe-info">
{{ errorMessage || "Failed to record audio" }}
</div>
</v-col> </v-col>
<v-col align="right"> <v-col align="right">
<v-btn icon @click.stop="cancelRecording"> <v-btn icon @click.stop="cancelRecording">
@ -139,7 +145,8 @@ 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";
export default { export default {
name: "VoiceRecorder", name: "VoiceRecorder",
@ -179,7 +186,7 @@ export default {
recordTimer: null, recordTimer: null,
recordingLocked: false, recordingLocked: false,
recordedFile: null, recordedFile: null,
errorMessage: null errorMessage: null,
}; };
}, },
watch: { watch: {
@ -314,14 +321,17 @@ export default {
}, },
startRecording() { startRecording() {
const MicRecorder = require("mic-recorder-to-mp3"); navigator.mediaDevices
// Start recording. Browser will request permission to use your microphone. .getUserMedia({
this.recorder = new MicRecorder({ video: false,
bitRate: 128, audio: true,
}); })
this.recorder .then((stream) => {
.start() this.recorder = RecordRTC(stream, {
.then(() => { 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();
@ -337,7 +347,9 @@ export default {
cancelRecording() { cancelRecording() {
this.state = State.INITIAL; this.state = State.INITIAL;
if (this.recorder) { if (this.recorder) {
this.recorder.stop(); this.recorder.stopRecording();
this.recorder.destroy();
this.recorder = null;
} }
this.stopRecordTimer(); this.stopRecordTimer();
this.recordingTime = String.fromCharCode(160); // nbsp; this.recordingTime = String.fromCharCode(160); // nbsp;
@ -362,33 +374,25 @@ export default {
}, },
send() { send() {
//console.log("Send:", this.recordedFile); //console.log("Send:", this.recordedFile);
this.$emit("file", {file: this.recordedFile}); this.$emit("file", { file: this.recordedFile });
// const player = new Audio(URL.createObjectURL(file)); // const player = new Audio(URL.createObjectURL(file));
// player.play(); // player.play();
}, },
getFile(send) { getFile(send) {
this.recorder this.recorder.stopRecording(function ()
.stop() {
.getMp3() this.recordedFile = new File(
.then(([buffer, blob]) => { [this.recorder.getBlob()],
// do what ever you want with buffer and blob util.formatRecordStartTime(this.recordStartedAt) + ".webm",
// Example: Create a mp3 file and play {
this.recordedFile = new File( type: "audio/webm",
buffer, lastModified: Date.now()
util.formatRecordStartTime(this.recordStartedAt) + ".mp3",
{
type: blob.type,
lastModified: Date.now(),
}
);
if (send) {
this.send();
} }
}) );
.catch((e) => { if (send) {
alert("We could not retrieve your message"); this.send();
console.log(e); }
}); }.bind(this));
}, },
startRecordTimer() { startRecordTimer() {
this.stopRecordTimer(); this.stopRecordTimer();