{"version":3,"sources":["webpack:///./src/views/recorder/lib/encoder.ts","webpack:///./src/views/recorder/lib/devices.ts","webpack:///./node_modules/core-js/modules/es.array-buffer.constructor.js","webpack:///./src/views/recorder/lib/backup_recorder.ts"],"names":["min","Math","max","setString","view","offset","str","len","length","i","setUint8","charCodeAt","Encoder","numSamples","numChannels","sampleRate","dataViews","buffer","nCh","this","DataView","ArrayBuffer","ch","x","setInt16","push","dataSize","setUint32","setUint16","unshift","blob","Blob","type","cleanup","selectDevice","id","LocalStorage","setInputDevice","setVideoInputDevice","getInputDevice","getVideoInputDevice","getDevices","navigator","mediaDevices","enumerateDevices","console","log","inputDevice","constraints","video","audio","channelCount","echoCancellation","deviceId","undefined","getUserMedia","stream","getTracks","forEach","t","stop","warn","devices","deviceType","inputDevices","filter","device","kind","map","name","label","error","$","global","arrayBufferModule","setSpecies","ARRAY_BUFFER","NativeArrayBuffer","forced","onupdate","isRecording","bufferSize","isPause","duration","savedDuration","exact","encoder","_micCaptured","track","input","disconnect","processor","context","currentTime","close","finish","now","Date","record","recordedAt","toISOString","title","toLocaleString","window","AudioContext","webkitAudioContext","analyzer","createAnalyser","createMediaStreamSource","createScriptProcessor","fftSize","smoothingTimeConstant","connect","destination","onaudioprocess","ev","sample","inputBuffer","getChannelData","encode","Uint8Array","frequencyBinCount","getByteFrequencyData","sum","reduce","cum","curr","vol"],"mappings":"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","file":"assets/js/chunk-6c1c781d.8663af53.js","sourcesContent":["const min = Math.min,\r\n max = Math.max;\r\n\r\nconst setString = function (view: any, offset: any, str: any) {\r\n const len = str.length;\r\n for (let i = 0; i < len; ++i) view.setUint8(offset + i, str.charCodeAt(i));\r\n};\r\n\r\nexport class Encoder {\r\n numSamples = 0;\r\n numChannels = 1;\r\n sampleRate = 48000;\r\n dataViews: DataView[] = [];\r\n constructor() {}\r\n\r\n encode(buffer: [Float32Array]) {\r\n const len = buffer[0].length,\r\n nCh = this.numChannels,\r\n view = new DataView(new ArrayBuffer(len * nCh * 2));\r\n let offset = 0;\r\n for (let i = 0; i < len; ++i)\r\n for (let ch = 0; ch < nCh; ++ch) {\r\n const x = buffer[ch][i] * 0x7fff;\r\n view.setInt16(offset, x < 0 ? max(x, -0x8000) : min(x, 0x7fff), true);\r\n offset += 2;\r\n }\r\n this.dataViews.push(view);\r\n this.numSamples += len;\r\n }\r\n\r\n finish() {\r\n const dataSize = this.numChannels * this.numSamples * 2,\r\n view = new DataView(new ArrayBuffer(44));\r\n setString(view, 0, \"RIFF\");\r\n view.setUint32(4, 36 + dataSize, true);\r\n setString(view, 8, \"WAVE\");\r\n setString(view, 12, \"fmt \");\r\n view.setUint32(16, 16, true);\r\n view.setUint16(20, 1, true);\r\n view.setUint16(22, this.numChannels, true);\r\n view.setUint32(24, this.sampleRate, true);\r\n view.setUint32(28, this.sampleRate * 4, true);\r\n view.setUint16(32, this.numChannels * 2, true);\r\n view.setUint16(34, 16, true);\r\n setString(view, 36, \"data\");\r\n view.setUint32(40, dataSize, true);\r\n this.dataViews.unshift(view);\r\n const blob = new Blob(this.dataViews, { type: \"audio/wav\" });\r\n this.cleanup();\r\n return blob;\r\n }\r\n\r\n cleanup() {\r\n this.dataViews = [];\r\n }\r\n}\r\n","import LocalStorage from \"@/core/utils/LocalStorage\";\r\n\r\ntype DeviceType = \"video\" | \"audio\";\r\nexport interface Device {\r\n id: string;\r\n name: string;\r\n}\r\n\r\nexport const selectDevice = (id: string, type: DeviceType = \"audio\") => {\r\n if (type === \"audio\") LocalStorage.setInputDevice(id);\r\n else LocalStorage.setVideoInputDevice(id);\r\n};\r\n\r\nexport const getInputDevice = (type: DeviceType = \"audio\") => {\r\n return type === \"audio\"\r\n ? LocalStorage.getInputDevice()\r\n : LocalStorage.getVideoInputDevice();\r\n};\r\n\r\nexport const getDevices = async (\r\n type: DeviceType = \"audio\",\r\n): Promise => {\r\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\r\n console.log(\"enumerateDevices() not supported.\");\r\n return [];\r\n }\r\n\r\n const inputDevice = getInputDevice();\r\n const constraints: MediaStreamConstraints =\r\n type === \"audio\"\r\n ? {\r\n video: false,\r\n audio: {\r\n channelCount: 1,\r\n echoCancellation: false,\r\n deviceId: inputDevice || undefined,\r\n },\r\n }\r\n : {\r\n audio: false,\r\n video: {\r\n deviceId: inputDevice || undefined,\r\n },\r\n };\r\n\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia(constraints);\r\n stream.getTracks().forEach(t => t.stop());\r\n } catch (error) {\r\n console.warn(\r\n `Warning: Access to ${\r\n type === \"audio\" ? \"microphone\" : \"camera\"\r\n } denied.`,\r\n error,\r\n );\r\n }\r\n\r\n try {\r\n const devices = await navigator.mediaDevices.enumerateDevices();\r\n const deviceType: MediaDeviceKind =\r\n type === \"audio\" ? \"audioinput\" : \"videoinput\";\r\n\r\n const inputDevices = devices\r\n .filter(device => device.kind === deviceType)\r\n .map(device => ({\r\n id: device.deviceId,\r\n name: device.label || `Unknown device (${type})`,\r\n }));\r\n\r\n if (!inputDevice && inputDevices.length > 0)\r\n selectDevice(inputDevices[0].id, type);\r\n\r\n console.log(`Found devices (${type}):`, inputDevices);\r\n\r\n return inputDevices;\r\n } catch (error) {\r\n console.error(\"Error while listing devices:\", error);\r\n return [];\r\n }\r\n};\r\n","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar arrayBufferModule = require('../internals/array-buffer');\nvar setSpecies = require('../internals/set-species');\n\nvar ARRAY_BUFFER = 'ArrayBuffer';\nvar ArrayBuffer = arrayBufferModule[ARRAY_BUFFER];\nvar NativeArrayBuffer = global[ARRAY_BUFFER];\n\n// `ArrayBuffer` constructor\n// https://tc39.github.io/ecma262/#sec-arraybuffer-constructor\n$({ global: true, forced: NativeArrayBuffer !== ArrayBuffer }, {\n ArrayBuffer: ArrayBuffer\n});\n\nsetSpecies(ARRAY_BUFFER);\n","import { Recording } from \"@/core/models\";\r\nimport { getInputDevice } from \"./devices\";\r\nimport { Encoder } from \"./encoder\";\r\n\r\nexport default class {\r\n isRecording = false;\r\n bufferSize = 4096;\r\n isPause = false;\r\n duration = 0;\r\n savedDuration = 0;\r\n\r\n stream?: MediaStream;\r\n encoder?: Encoder;\r\n context?: AudioContext;\r\n processor?: ScriptProcessorNode;\r\n input?: MediaStreamAudioSourceNode;\r\n analyzer?: AnalyserNode;\r\n onupdate: (vol: number) => void;\r\n\r\n constructor(onupdate: (vol: number) => void = () => {}) {\r\n this.onupdate = onupdate;\r\n }\r\n\r\n async start() {\r\n const inputDevice = getInputDevice();\r\n const constraints: MediaStreamConstraints = {\r\n video: false,\r\n audio: {\r\n channelCount: 1,\r\n echoCancellation: false,\r\n deviceId: inputDevice ? { exact: inputDevice } : undefined,\r\n },\r\n };\r\n\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia(constraints);\r\n this.stream = stream;\r\n this.encoder = new Encoder();\r\n this._micCaptured(stream);\r\n } catch (error) {\r\n console.log(\"Mic error\", error);\r\n }\r\n }\r\n\r\n async stop() {\r\n this.stream?.getTracks().forEach((track: MediaStreamTrack) => track.stop());\r\n\r\n this.input?.disconnect();\r\n this.processor?.disconnect();\r\n this.duration = this.context?.currentTime || this.savedDuration;\r\n this.context?.close();\r\n\r\n const blob = this.encoder?.finish();\r\n if (!blob) return;\r\n\r\n const now = new Date();\r\n const record = {\r\n blob: blob,\r\n recordedAt: now.toISOString(),\r\n title: `Recorded on ${now.toLocaleString()}`,\r\n } as Recording;\r\n\r\n this.savedDuration = 0;\r\n this.duration = 0;\r\n this.isRecording = false;\r\n\r\n return record;\r\n }\r\n\r\n pause() {\r\n this.stream?.getTracks().forEach((track: MediaStreamTrack) => track.stop());\r\n this.input?.disconnect();\r\n this.processor?.disconnect();\r\n this.duration = this.context?.currentTime || this.savedDuration;\r\n this.context?.close();\r\n\r\n this.savedDuration = this.duration;\r\n this.isPause = true;\r\n }\r\n\r\n _micCaptured(stream: MediaStream) {\r\n // @ts-ignore\r\n this.context = new (window.AudioContext || window.webkitAudioContext)();\r\n this.duration = this.savedDuration;\r\n this.analyzer = this.context.createAnalyser();\r\n this.input = this.context.createMediaStreamSource(stream);\r\n this.processor = this.context.createScriptProcessor(this.bufferSize, 1, 1);\r\n this.stream = stream;\r\n\r\n this.analyzer.fftSize = 64;\r\n this.analyzer.smoothingTimeConstant = 0.3;\r\n\r\n this.input.connect(this.analyzer);\r\n this.analyzer.connect(this.processor);\r\n this.processor.connect(this.context.destination);\r\n this.processor.onaudioprocess = (ev: AudioProcessingEvent) => {\r\n // Toggle if recording\r\n if (!this.isRecording || (this.isRecording && this.isPause)) {\r\n this.isPause = false;\r\n this.isRecording = true;\r\n }\r\n\r\n // encode sample\r\n const sample = ev.inputBuffer.getChannelData(0);\r\n this.encoder?.encode([sample]);\r\n\r\n // get duration\r\n this.duration = this.savedDuration + (this.context?.currentTime || 0);\r\n\r\n // get volume\r\n if (!this.analyzer) return;\r\n const buffer = new Uint8Array(this.analyzer.frequencyBinCount);\r\n this.analyzer.getByteFrequencyData(buffer);\r\n const sum = buffer.reduce((cum, curr) => cum + curr, 0);\r\n const vol = sum / buffer.length;\r\n this.onupdate(vol);\r\n };\r\n\r\n this.input?.connect(this.processor);\r\n this.processor.connect(this.context.destination);\r\n }\r\n}\r\n"],"sourceRoot":""}