More work on audio recording
Issue #95. Use a post processing step to fix chromium bug of not having a valid cues section in the metadata (=browser did not know length of audio!). Also, set more constraints in the call to getUserMedia to fix Android problem of really sh*tty audio in the default mode (More info on github.com slash processing/p5.js-sound/issues/346
This commit is contained in:
parent
b6ac6ec881
commit
b8aeb02b50
3 changed files with 833 additions and 140 deletions
884
package-lock.json
generated
884
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,7 @@
|
|||
"raw-loader": "^4.0.2",
|
||||
"recordrtc": "^5.6.2",
|
||||
"roboto-fontface": "*",
|
||||
"ts-ebml": "^2.0.2",
|
||||
"v-emoji-picker": "^2.3.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ import util from "../plugins/utils";
|
|||
import VoiceRecorderLock from "./VoiceRecorderLock";
|
||||
require("md-gum-polyfill");
|
||||
import RecordRTC from "recordrtc";
|
||||
import {Decoder, tools, Reader} from 'ts-ebml';
|
||||
|
||||
export default {
|
||||
name: "VoiceRecorder",
|
||||
|
|
@ -321,15 +322,23 @@ export default {
|
|||
},
|
||||
|
||||
startRecording() {
|
||||
var constraints = {
|
||||
audio: {
|
||||
channelCount: 1,
|
||||
sampleRate: 16000,
|
||||
echoCancellation: false,
|
||||
autoGainControl: true,
|
||||
noiseSuppression: true,
|
||||
volume: 1.0,
|
||||
},
|
||||
video: false,
|
||||
};
|
||||
navigator.mediaDevices
|
||||
.getUserMedia({
|
||||
video: false,
|
||||
audio: true,
|
||||
})
|
||||
.getUserMedia(constraints)
|
||||
.then((stream) => {
|
||||
this.recorder = RecordRTC(stream, {
|
||||
type: "audio",
|
||||
mimeType: "audio/webm"
|
||||
mimeType: "audio/webm",
|
||||
});
|
||||
this.recorder.startRecording();
|
||||
this.state = State.RECORDING;
|
||||
|
|
@ -373,27 +382,29 @@ export default {
|
|||
this.recordingTime = String.fromCharCode(160); // nbsp;
|
||||
},
|
||||
send() {
|
||||
//console.log("Send:", this.recordedFile);
|
||||
this.$emit("file", { file: this.recordedFile });
|
||||
// const player = new Audio(URL.createObjectURL(file));
|
||||
// player.play();
|
||||
},
|
||||
getFile(send) {
|
||||
this.recorder.stopRecording(function ()
|
||||
{
|
||||
const blob = this.recorder.getBlob();
|
||||
this.recordedFile = new File(
|
||||
[blob],
|
||||
util.formatRecordStartTime(this.recordStartedAt) + ".webm",
|
||||
{
|
||||
type: blob.type,
|
||||
lastModified: Date.now()
|
||||
}
|
||||
);
|
||||
if (send) {
|
||||
this.send();
|
||||
}
|
||||
}.bind(this));
|
||||
this.recorder.stopRecording(
|
||||
function () {
|
||||
this.correctMetadata(this.recorder.getBlob()).then((blob) => {
|
||||
this.recordedFile = new File(
|
||||
[blob],
|
||||
util.formatRecordStartTime(this.recordStartedAt) + ".webm",
|
||||
{
|
||||
type: blob.type,
|
||||
lastModified: Date.now(),
|
||||
}
|
||||
);
|
||||
//const player = new Audio(URL.createObjectURL(this.recordedFile));
|
||||
//player.play();
|
||||
if (send) {
|
||||
//console.log("send");
|
||||
this.send();
|
||||
}
|
||||
});
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
startRecordTimer() {
|
||||
this.stopRecordTimer();
|
||||
|
|
@ -411,6 +422,37 @@ export default {
|
|||
this.recordTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* There is an issue with browsers not setting correct metadata in the generated webm file.
|
||||
* See here: https://bugs.chromium.org/p/chromium/issues/detail?id=642012
|
||||
* Use es-embl to try to update the cues section.
|
||||
*/
|
||||
async correctMetadata(blob) {
|
||||
try {
|
||||
const decoder = new Decoder();
|
||||
const reader = new Reader();
|
||||
reader.logging = true;
|
||||
reader.logGroup = "Raw WebM file";
|
||||
reader.drop_default_duration = false;
|
||||
const webMBuf = await blob.arrayBuffer();
|
||||
const elms = decoder.decode(webMBuf);
|
||||
elms.forEach((elm) => {
|
||||
reader.read(elm);
|
||||
});
|
||||
reader.stop();
|
||||
const refinedMetadataBuf = tools.makeMetadataSeekable(
|
||||
reader.metadatas,
|
||||
reader.duration,
|
||||
reader.cues
|
||||
);
|
||||
const body = webMBuf.slice(reader.metadataSize);
|
||||
return new Blob([refinedMetadataBuf, body], { type: blob.type });
|
||||
} catch (err) {
|
||||
console.err(err);
|
||||
return blob;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue