mime-chat/src/components/inputitem/helpers/audiocontrol.ts
Andrew Gundersen b08061d080 more changes
2021-05-31 10:01:04 -05:00

138 lines
3.6 KiB
TypeScript

import useMitt from "@/modules/mitt";
import { useIpc } from '@/modules/ipc';
import { showRecIcon, hideRecIcon } from "./animations";
import { onMounted, onUnmounted, ref, Ref } from "vue";
import keyboardNameMap from "../keyBoardMaps/keyboardNameMap";
import { renderMessage, clientMessage } from '@/modules/message';
import { AudioData } from "@/types";
function arrayBufferToBase64 (buffer: any) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
export default function useAudioInputController (typing: Ref) {
let mediaRecorder: any;
let buffer = '';
let sampleRate = 44100; // default
let channels = 1;
// For sending messages.
const { post, invoke } = useIpc();
const { emitter } = useMitt();
const recording = ref(false);
// initiate media recorder
if (navigator.mediaDevices) {
console.log("Initializing media recorder.");
const usrOptions: any = {
audio: true,
video: false
}
navigator.mediaDevices.getUserMedia(usrOptions).then((stream: any) => {
const context = new AudioContext();
const source = context.createMediaStreamSource(stream);
const processor = context.createScriptProcessor(1024, 1, 1);
source.connect(processor);
processor.connect(context.destination);
processor.onaudioprocess = (e: AudioProcessingEvent) => {
if (recording.value) {
const data = e.inputBuffer.getChannelData(0).buffer;
buffer += arrayBufferToBase64(data);
sampleRate = e.inputBuffer.sampleRate;
} else buffer = '';
};
});
}
//---Callbacks-----------------------------------------------
const onKeyDown = (e: KeyboardEvent) => {
const cmd = keyboardNameMap[e.keyCode];
// Start recording on space bar.
if (cmd == "SPACE" && !typing.value && !recording.value) {
console.log("INPT:Starting record, filling buffer.")
recording.value = true;
showRecIcon();
}
}
const onKeyUp = async (e: KeyboardEvent) => {
const cmd = keyboardNameMap[e.keyCode];
// Stop recording on space up.
if (cmd == "SPACE" && recording.value) {
// get audio from buffer then stop recording
console.log("INPT:Stopping record.")
recording.value = false;
hideRecIcon()
// render a place holder message
const message = renderMessage(
"",
"",
"",
"sf"
);
emitter.emit("self-message", message);
// send audio to backend
const audio: AudioData = {
content: buffer,
channels: channels,
fs: sampleRate
}
console.log("INPT:Sending audio to backend");
post("client-message", clientMessage("", audio, message.uid));
}
}
//-----------------------------------------------------------
onMounted(() => {
window.addEventListener("keydown", onKeyDown);
window.addEventListener("keyup", onKeyUp);
})
onUnmounted(() => {
window.removeEventListener("keydown", onKeyDown);
window.removeEventListener("keyup", onKeyUp);
});
return {
recording
}
}