mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-19 12:00:39 +08:00
Stream works now (#2351)
* changes * changes * lazy load streaming deps * lazy load streaming deps * cleanup * fix last chunks of streaming * add changelog * add changelog * add changelog * add changelog * updated streaming demo * renamed sst * changes Co-authored-by: pngwn <hello@pngwn.io> Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
This commit is contained in:
parent
b59c45160d
commit
ac378d0875
@ -15,6 +15,7 @@ You can now see gradio's release history directly on the website, and also keep
|
||||
3. Catch the permission exception on the audio component by [@Ian-GL](https://github.com/Ian-GL) in [PR 2330](https://github.com/gradio-app/gradio/pull/2330)
|
||||
4. Fix image_classifier_interface_load demo by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2365](https://github.com/gradio-app/gradio/pull/2365)
|
||||
5. Fix combining adjacent components without gaps by introducing `gr.Row(variant="compact")` by [@aliabid94](https://github.com/aliabid94) in [PR 2291](https://github.com/gradio-app/gradio/pull/2291) This comes with deprecation of the following arguments for `Component.style`: `round`, `margin`, `border`.
|
||||
6. Fix audio streaming, which was previously choppy in [PR 2351](https://github.com/gradio-app/gradio/pull/2351). Big thanks to [@yannickfunk](https://github.com/yannickfunk) for the proposed solution.
|
||||
|
||||
## Documentation Changes:
|
||||
|
||||
|
@ -1,20 +1,27 @@
|
||||
import gradio as gr
|
||||
import numpy as np
|
||||
import time
|
||||
|
||||
def add_to_stream(audio, instream):
|
||||
time.sleep(1)
|
||||
if audio is None:
|
||||
return gr.update(), instream
|
||||
if instream is None:
|
||||
ret = audio
|
||||
else:
|
||||
ret = (audio[0], np.concatenate((instream[1], audio[1])))
|
||||
return ret, ret
|
||||
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
inp = gr.Audio(source="microphone")
|
||||
out = gr.Audio()
|
||||
stream = gr.State()
|
||||
clear = gr.Button("Clear")
|
||||
|
||||
def add_to_stream(audio, instream):
|
||||
if audio is None:
|
||||
return gr.update(), instream
|
||||
if instream is None:
|
||||
ret = audio
|
||||
else:
|
||||
ret = (audio[0], np.concatenate((instream[1], audio[1])))
|
||||
return ret, ret
|
||||
inp.stream(add_to_stream, [inp, stream], [out, stream])
|
||||
clear.click(lambda: [None, None, None], None, [inp, out, stream])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
@ -1 +1,2 @@
|
||||
deepspeech==0.8.2
|
||||
torch
|
||||
transformers
|
||||
|
@ -1,47 +1,27 @@
|
||||
from deepspeech import Model
|
||||
from transformers import pipeline
|
||||
import gradio as gr
|
||||
import scipy.io.wavfile
|
||||
import numpy as np
|
||||
import time
|
||||
|
||||
model_file_path = "deepspeech-0.8.2-models.pbmm"
|
||||
lm_file_path = "deepspeech-0.8.2-models.scorer"
|
||||
beam_width = 100
|
||||
lm_alpha = 0.93
|
||||
lm_beta = 1.18
|
||||
p = pipeline("automatic-speech-recognition")
|
||||
|
||||
model = Model(model_file_path)
|
||||
model.enableExternalScorer(lm_file_path)
|
||||
model.setScorerAlphaBeta(lm_alpha, lm_beta)
|
||||
model.setBeamWidth(beam_width)
|
||||
def transcribe(audio, state=""):
|
||||
time.sleep(2)
|
||||
text = p(audio)["text"]
|
||||
state += text + " "
|
||||
return state, state
|
||||
|
||||
|
||||
def reformat_freq(sr, y):
|
||||
if sr not in (
|
||||
48000,
|
||||
16000,
|
||||
): # Deepspeech only supports 16k, (we convert 48k -> 16k)
|
||||
raise ValueError("Unsupported rate", sr)
|
||||
if sr == 48000:
|
||||
y = (
|
||||
((y / max(np.max(y), 1)) * 32767)
|
||||
.reshape((-1, 3))
|
||||
.mean(axis=1)
|
||||
.astype("int16")
|
||||
)
|
||||
sr = 16000
|
||||
return sr, y
|
||||
|
||||
|
||||
def transcribe(speech, stream):
|
||||
_, y = reformat_freq(*speech)
|
||||
if stream is None:
|
||||
stream = model.createStream()
|
||||
stream.feedAudioContent(y)
|
||||
text = stream.intermediateDecode()
|
||||
return text, stream
|
||||
|
||||
demo = gr.Interface(transcribe, ["microphone", "state"], ["text", "state"], live=True)
|
||||
demo = gr.Interface(
|
||||
fn=transcribe,
|
||||
inputs=[
|
||||
gr.Audio(source="microphone", type="filepath", streaming=True),
|
||||
"state"
|
||||
],
|
||||
outputs=[
|
||||
"textbox",
|
||||
"state"
|
||||
],
|
||||
live=True
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
|
||||
|
@ -423,7 +423,7 @@ class Streamable(Block):
|
||||
api_name: AnyStr = None,
|
||||
status_tracker: Optional[StatusTracker] = None,
|
||||
scroll_to_output: bool = False,
|
||||
show_progress: bool = True,
|
||||
show_progress: bool = False,
|
||||
queue: Optional[bool] = None,
|
||||
preprocess: bool = True,
|
||||
postprocess: bool = True,
|
||||
|
@ -690,7 +690,7 @@ class TabbedInterface(Blocks):
|
||||
"""
|
||||
A TabbedInterface is created by providing a list of Interfaces, each of which gets
|
||||
rendered in a separate tab.
|
||||
Demos: sst_or_tts
|
||||
Demos: stt_or_tts
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
@ -28,7 +28,7 @@ def copy_all_demos(source_dir: str, dest_dir: str):
|
||||
"model3D",
|
||||
"reset_components",
|
||||
"reverse_audio",
|
||||
"sst_or_tts",
|
||||
"stt_or_tts",
|
||||
"stream_audio",
|
||||
"stream_frames",
|
||||
"zip_files",
|
||||
|
@ -34,7 +34,7 @@ export default defineConfig(({ mode }) => {
|
||||
|
||||
build: {
|
||||
target: "esnext",
|
||||
minify: false,
|
||||
minify: production,
|
||||
outDir: `../../../gradio/templates/${is_cdn ? "cdn" : "frontend"}`
|
||||
},
|
||||
define: {
|
||||
|
@ -11,6 +11,8 @@
|
||||
"@gradio/atoms": "workspace:^0.0.1",
|
||||
"@gradio/icons": "workspace:^0.0.1",
|
||||
"@gradio/upload": "workspace:^0.0.1",
|
||||
"extendable-media-recorder": "^7.0.2",
|
||||
"extendable-media-recorder-wav-encoder": "^7.0.76",
|
||||
"svelte-range-slider-pips": "^2.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,15 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onDestroy, createEventDispatcher } from "svelte";
|
||||
import { onDestroy, createEventDispatcher, tick } from "svelte";
|
||||
import { Upload, ModifyUpload } from "@gradio/upload";
|
||||
import { BlockLabel } from "@gradio/atoms";
|
||||
import { Music } from "@gradio/icons";
|
||||
// @ts-ignore
|
||||
import Range from "svelte-range-slider-pips";
|
||||
|
||||
import type { IBlobEvent, IMediaRecorder } from "extendable-media-recorder";
|
||||
|
||||
export let value: null | { name: string; data: string } = null;
|
||||
export let label: string;
|
||||
export let show_label: boolean;
|
||||
@ -29,13 +31,34 @@
|
||||
// export let type: "normal" | "numpy" = "normal";
|
||||
|
||||
let recording = false;
|
||||
let recorder: MediaRecorder;
|
||||
let recorder: IMediaRecorder;
|
||||
let mode = "";
|
||||
let audio_chunks: Array<Blob> = [];
|
||||
let audio_blob;
|
||||
let header: Uint8Array | undefined = undefined;
|
||||
let pending_stream: Array<Uint8Array> = [];
|
||||
let submit_pending_stream_on_pending_end: boolean = false;
|
||||
let player;
|
||||
let inited = false;
|
||||
let crop_values = [0, 100];
|
||||
const STREAM_TIMESLICE = 500;
|
||||
const NUM_HEADER_BYTES = 44;
|
||||
let audio_chunks: Array<Blob> = [];
|
||||
let audio_blob;
|
||||
let module_promises:
|
||||
| [
|
||||
Promise<typeof import("extendable-media-recorder")>,
|
||||
Promise<typeof import("extendable-media-recorder-wav-encoder")>
|
||||
];
|
||||
|
||||
function get_modules() {
|
||||
module_promises = [
|
||||
import("extendable-media-recorder"),
|
||||
import("extendable-media-recorder-wav-encoder")
|
||||
];
|
||||
}
|
||||
|
||||
if (streaming) {
|
||||
get_modules();
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
change: AudioData;
|
||||
@ -57,8 +80,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
const dispatch_blob = async (
|
||||
blobs: Array<Uint8Array> | Blob[],
|
||||
event: "stream" | "change"
|
||||
) => {
|
||||
let audio_blob = new Blob(blobs, { type: "audio/wav" });
|
||||
value = {
|
||||
data: await blob_to_data_url(audio_blob),
|
||||
name
|
||||
};
|
||||
dispatch(event, value);
|
||||
};
|
||||
|
||||
async function prepare_audio() {
|
||||
let stream: MediaStream | null;
|
||||
|
||||
try {
|
||||
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
} catch (err) {
|
||||
@ -73,38 +109,67 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (stream === null) {
|
||||
return;
|
||||
if (stream == null) return;
|
||||
|
||||
if (streaming) {
|
||||
const [{ MediaRecorder, register }, { connect }] = await Promise.all(
|
||||
module_promises
|
||||
);
|
||||
|
||||
await register(await connect());
|
||||
|
||||
recorder = new MediaRecorder(stream, { mimeType: "audio/wav" });
|
||||
|
||||
async function handle_chunk(event: IBlobEvent) {
|
||||
let buffer = await event.data.arrayBuffer();
|
||||
let payload = new Uint8Array(buffer);
|
||||
if (!header) {
|
||||
header = new Uint8Array(buffer.slice(0, NUM_HEADER_BYTES));
|
||||
payload = new Uint8Array(buffer.slice(NUM_HEADER_BYTES));
|
||||
}
|
||||
if (pending) {
|
||||
pending_stream.push(payload);
|
||||
} else {
|
||||
let blobParts = [header].concat(pending_stream, [payload]);
|
||||
dispatch_blob(blobParts, "stream");
|
||||
pending_stream = [];
|
||||
}
|
||||
}
|
||||
recorder.addEventListener("dataavailable", handle_chunk);
|
||||
} else {
|
||||
recorder = new MediaRecorder(stream);
|
||||
|
||||
recorder.addEventListener("dataavailable", (event) => {
|
||||
audio_chunks.push(event.data);
|
||||
});
|
||||
|
||||
recorder.addEventListener("stop", async () => {
|
||||
recording = false;
|
||||
await dispatch_blob(audio_chunks, "change");
|
||||
audio_chunks = [];
|
||||
});
|
||||
}
|
||||
|
||||
recorder = new MediaRecorder(stream);
|
||||
|
||||
recorder.addEventListener("dataavailable", (event) => {
|
||||
audio_chunks.push(event.data);
|
||||
});
|
||||
|
||||
recorder.addEventListener("stop", async () => {
|
||||
if (!streaming) {
|
||||
recording = false;
|
||||
}
|
||||
audio_blob = new Blob(audio_chunks, { type: "audio/wav" });
|
||||
audio_chunks = [];
|
||||
value = {
|
||||
data: await blob_to_data_url(audio_blob),
|
||||
name
|
||||
};
|
||||
dispatch(streaming ? "stream" : "change", value);
|
||||
});
|
||||
inited = true;
|
||||
}
|
||||
|
||||
$: if (submit_pending_stream_on_pending_end && pending === false) {
|
||||
submit_pending_stream_on_pending_end = false;
|
||||
if (header && pending_stream) {
|
||||
let blobParts: Array<Uint8Array> = [header].concat(pending_stream);
|
||||
pending_stream = [];
|
||||
dispatch_blob(blobParts, "stream");
|
||||
}
|
||||
}
|
||||
|
||||
async function record() {
|
||||
recording = true;
|
||||
|
||||
if (!inited) await prepare_audio();
|
||||
|
||||
if (recorder) {
|
||||
recording = true;
|
||||
audio_chunks = [];
|
||||
|
||||
header = undefined;
|
||||
if (streaming) {
|
||||
recorder.start(STREAM_TIMESLICE);
|
||||
} else {
|
||||
recorder.start();
|
||||
}
|
||||
}
|
||||
@ -115,10 +180,13 @@
|
||||
}
|
||||
});
|
||||
|
||||
const stop = () => {
|
||||
const stop = async () => {
|
||||
recorder.stop();
|
||||
if (streaming) {
|
||||
recording = false;
|
||||
if (pending) {
|
||||
submit_pending_stream_on_pending_end = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -177,20 +245,6 @@
|
||||
|
||||
export let dragging = false;
|
||||
$: dispatch("drag", dragging);
|
||||
|
||||
if (streaming) {
|
||||
window.setInterval(() => {
|
||||
if (
|
||||
recording &&
|
||||
recorder &&
|
||||
recorder.state === "recording" &&
|
||||
pending === false
|
||||
) {
|
||||
stop();
|
||||
record();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
<BlockLabel {show_label} Icon={Music} label={label || "Audio"} />
|
||||
|
182
ui/pnpm-lock.yaml
generated
182
ui/pnpm-lock.yaml
generated
@ -146,11 +146,15 @@ importers:
|
||||
'@gradio/atoms': workspace:^0.0.1
|
||||
'@gradio/icons': workspace:^0.0.1
|
||||
'@gradio/upload': workspace:^0.0.1
|
||||
extendable-media-recorder: ^7.0.2
|
||||
extendable-media-recorder-wav-encoder: ^7.0.76
|
||||
svelte-range-slider-pips: ^2.0.1
|
||||
dependencies:
|
||||
'@gradio/atoms': link:../atoms
|
||||
'@gradio/icons': link:../icons
|
||||
'@gradio/upload': link:../upload
|
||||
extendable-media-recorder: 7.0.2
|
||||
extendable-media-recorder-wav-encoder: 7.0.76
|
||||
svelte-range-slider-pips: 2.0.2
|
||||
|
||||
packages/button:
|
||||
@ -435,6 +439,13 @@ packages:
|
||||
regenerator-runtime: 0.13.9
|
||||
dev: false
|
||||
|
||||
/@babel/runtime/7.19.0:
|
||||
resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.9
|
||||
dev: false
|
||||
|
||||
/@cloudflare/workers-types/3.14.1:
|
||||
resolution: {integrity: sha512-B1/plF62pt+H2IJHvApK8fdOJAVsvojvacuac8x8s+JIyqbropMyqNqHTKLm3YD8ZFLGwYeFTudU+PQ7vGvBdA==}
|
||||
dev: true
|
||||
@ -965,6 +976,14 @@ packages:
|
||||
resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=}
|
||||
dev: false
|
||||
|
||||
/automation-events/4.0.21:
|
||||
resolution: {integrity: sha512-VJdSzclxoBVAqE4UAwmqPLHAM3EI2iYhZ2MADdQnjFlW/GE17B47aQ6y9JE9up2bf8f7I5RfqGhJM464jPMzww==}
|
||||
engines: {node: '>=12.20.1'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/autoprefixer/10.4.2_postcss@8.4.6:
|
||||
resolution: {integrity: sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@ -1057,6 +1076,15 @@ packages:
|
||||
dependencies:
|
||||
fill-range: 7.0.1
|
||||
|
||||
/broker-factory/3.0.68:
|
||||
resolution: {integrity: sha512-QrbDJ/7YwZ2+TuSreT8WMKrssIO3VjywMu5C5Jq+pJ+OkIVIXhUkxdBhNX2mmRXlzkU+jVXz8uMyRP+2uAgx8w==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
fast-unique-numbers: 6.0.21
|
||||
tslib: 2.4.0
|
||||
worker-factory: 6.0.69
|
||||
dev: false
|
||||
|
||||
/browserslist/4.19.1:
|
||||
resolution: {integrity: sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
@ -1200,6 +1228,16 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
dev: false
|
||||
|
||||
/compilerr/9.0.21:
|
||||
resolution: {integrity: sha512-H6ZnGHPBiwVdWt8GbAPuQK4mmtRTJ5yucysgFFhGxmPoLCAmaMSxtvHNzhAAGNqBRZOTsGjkwT8clNw6CJcGgQ==}
|
||||
engines: {node: '>=12.20.1'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
dashify: 2.0.0
|
||||
indefinite-article: 0.0.2
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/concat-map/0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
@ -1352,6 +1390,11 @@ packages:
|
||||
d3-array: 3.1.1
|
||||
dev: false
|
||||
|
||||
/dashify/2.0.0:
|
||||
resolution: {integrity: sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/debug/4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
@ -1935,6 +1978,44 @@ packages:
|
||||
/estree-walker/2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
/extendable-media-recorder-wav-encoder-broker/7.0.70:
|
||||
resolution: {integrity: sha512-nnVAxiLBdf0PLDXP/8+bKYYRs2PmoJMoJzpcDGOra8GsHIPS+ytmS+85DUFSYGxaxohrhovgN0jVXSyjJ6hQSQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
broker-factory: 3.0.68
|
||||
extendable-media-recorder-wav-encoder-worker: 8.0.69
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/extendable-media-recorder-wav-encoder-worker/8.0.69:
|
||||
resolution: {integrity: sha512-8RJgKYTTHkzDoCWrnPMMqX+TyJpwzP9lwqxQWDpa9J5J1DP0SybgoYWP8Dtty/R5xT344lU+NKo7g1661i7Ujg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
tslib: 2.4.0
|
||||
worker-factory: 6.0.69
|
||||
dev: false
|
||||
|
||||
/extendable-media-recorder-wav-encoder/7.0.76:
|
||||
resolution: {integrity: sha512-HLeyR9R0mUPOo7zG3d3GRWltNaSYUjyUZGQ8amRjuQVkZFXszmOIAAUVBq3fou0Z3V1mAEo+mXnCqbEfYtgZXQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
extendable-media-recorder-wav-encoder-broker: 7.0.70
|
||||
extendable-media-recorder-wav-encoder-worker: 8.0.69
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/extendable-media-recorder/7.0.2:
|
||||
resolution: {integrity: sha512-rZAvRaAJgMyQUMWMrgSB1U1o9nNXaguVAwNVOnt396tRlfZtBbHxraygqjPQXNs6kb1H4XcG/RLTn+hfZJx2Xg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
media-encoder-host: 8.0.78
|
||||
multi-buffer-data-view: 3.0.21
|
||||
recorder-audio-worklet: 5.1.29
|
||||
standardized-audio-context: 25.3.32
|
||||
subscribable-things: 2.1.7
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/fast-glob/3.2.11:
|
||||
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
@ -1945,6 +2026,14 @@ packages:
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.4
|
||||
|
||||
/fast-unique-numbers/6.0.21:
|
||||
resolution: {integrity: sha512-MW8UAAypyhNtbnMlSch9EiEAuiMo1y6O02WzI5mcHAzvirdIm/hXMVp4QH9ijWnU1xzW23GXk6Bf+5B1kv9hzw==}
|
||||
engines: {node: '>=12.20.1'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/fastq/1.13.0:
|
||||
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
|
||||
dependencies:
|
||||
@ -2174,6 +2263,10 @@ packages:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
|
||||
/indefinite-article/0.0.2:
|
||||
resolution: {integrity: sha512-Au/2XzRkvxq2J6w5uvSSbBKPZ5kzINx5F2wb0SF8xpRL8BP9Lav81TnRbfPp6p+SYjYxwaaLn4EUwI3/MmYKSw==}
|
||||
dev: false
|
||||
|
||||
/inflight/1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
dependencies:
|
||||
@ -2412,6 +2505,34 @@ packages:
|
||||
semver: 6.3.0
|
||||
dev: true
|
||||
|
||||
/media-encoder-host-broker/7.0.70:
|
||||
resolution: {integrity: sha512-ixixE9auojgUHEIQHYvJ75vPxetkHreIfxK20SQ4ZoZSO/vRj4+up72rETMbj2e0UO7xnDJqADsx+sfkoV2eVA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
broker-factory: 3.0.68
|
||||
fast-unique-numbers: 6.0.21
|
||||
media-encoder-host-worker: 9.0.70
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/media-encoder-host-worker/9.0.70:
|
||||
resolution: {integrity: sha512-ttZAvG0osaOTl6C1OMIzZzFQ/ZIBiRDHyrfcM0d+ZF65tAjLtA53vWoINcgwRBEwc4P62y9a12pbujB1ZdCU6Q==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
extendable-media-recorder-wav-encoder-broker: 7.0.70
|
||||
tslib: 2.4.0
|
||||
worker-factory: 6.0.69
|
||||
dev: false
|
||||
|
||||
/media-encoder-host/8.0.78:
|
||||
resolution: {integrity: sha512-kobfdkFcfp8w2SkPY8ISHzG6L7o8tgtIvXtK5/j1hfZGZxqf0sxxXEzU9WFm9jNKnlgko6RSZhPzD24w60I4zQ==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
media-encoder-host-broker: 7.0.70
|
||||
media-encoder-host-worker: 9.0.70
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/memorystream/0.3.1:
|
||||
resolution: {integrity: sha1-htcJCzDORV1j+64S3aUaR93K+bI=}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@ -2499,6 +2620,14 @@ packages:
|
||||
/ms/2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
|
||||
/multi-buffer-data-view/3.0.21:
|
||||
resolution: {integrity: sha512-K/v5mjWMbJEgiZzn6Pr7+jKoKuChY6GdQEeiKNWhIi0QILXzJmUvuho85z6AYYh38Ua2kGY/5E3qs2ceoZ8chA==}
|
||||
engines: {node: '>=12.20.1'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/nanoid/3.2.0:
|
||||
resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
@ -2980,6 +3109,26 @@ packages:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
||||
/recorder-audio-worklet-processor/4.2.15:
|
||||
resolution: {integrity: sha512-5QTJKukH8JcQR1f2FqZsQ1QD2aoc6/+tM0WPv8sqEI4THzbiMfH4VuWF3BfdL2F9mRjLo81nFC9OShCj87wMhg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/recorder-audio-worklet/5.1.29:
|
||||
resolution: {integrity: sha512-HCuB5c50UdRSm8DubnRYIzfNo+eNPfdCAWlSO9jag3lt9vnAJpg6u4DBBb/psXOk7PsHaRsHkZTdg96RSybawA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
broker-factory: 3.0.68
|
||||
fast-unique-numbers: 6.0.21
|
||||
recorder-audio-worklet-processor: 4.2.15
|
||||
standardized-audio-context: 25.3.32
|
||||
subscribable-things: 2.1.7
|
||||
tslib: 2.4.0
|
||||
worker-factory: 6.0.69
|
||||
dev: false
|
||||
|
||||
/regenerator-runtime/0.13.9:
|
||||
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==}
|
||||
dev: false
|
||||
@ -3063,6 +3212,10 @@ packages:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
dev: false
|
||||
|
||||
/rxjs-interop/2.0.0:
|
||||
resolution: {integrity: sha512-ASEq9atUw7lualXB+knvgtvwkCEvGWV2gDD/8qnASzBkzEARZck9JAyxmY8OS6Nc1pCPEgDTKNcx+YqqYfzArw==}
|
||||
dev: false
|
||||
|
||||
/sade/1.8.1:
|
||||
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
||||
engines: {node: '>=6'}
|
||||
@ -3210,6 +3363,14 @@ packages:
|
||||
resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==}
|
||||
dev: false
|
||||
|
||||
/standardized-audio-context/25.3.32:
|
||||
resolution: {integrity: sha512-TtnRZGzHaTowIrEPo7w7WK74TrrY885NpplFpD79h85YuUAUBrUGifHlh8GK11oyZHfwDtCV29yFPfIHWotrXg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
automation-events: 4.0.21
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/string-width/4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@ -3265,6 +3426,14 @@ packages:
|
||||
dependencies:
|
||||
min-indent: 1.0.1
|
||||
|
||||
/subscribable-things/2.1.7:
|
||||
resolution: {integrity: sha512-z8CMs8i0KSz69Lk83db40io5OEEq4TeuB/g6Z8tpSzmG20oNAL+C2Uys7XAOvcU4Iqrvvc/gcdFLRn6bi1Gb/w==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
rxjs-interop: 2.0.0
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/supports-color/5.5.0:
|
||||
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||
engines: {node: '>=4'}
|
||||
@ -3633,6 +3802,10 @@ packages:
|
||||
/tslib/2.3.1:
|
||||
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||
|
||||
/tslib/2.4.0:
|
||||
resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
|
||||
dev: false
|
||||
|
||||
/type-detect/4.0.8:
|
||||
resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
|
||||
engines: {node: '>=4'}
|
||||
@ -3801,6 +3974,15 @@ packages:
|
||||
string-width: 4.2.3
|
||||
dev: true
|
||||
|
||||
/worker-factory/6.0.69:
|
||||
resolution: {integrity: sha512-vut3DexCAyRicCuvfUAhOAlt7s4segcDutnqAH/ybxbpYzDu4qLfkmpEzfinbGCkPffTzXq64XulaSdqVG3Ncw==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.19.0
|
||||
compilerr: 9.0.21
|
||||
fast-unique-numbers: 6.0.21
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/worktop/0.8.0-next.14:
|
||||
resolution: {integrity: sha512-RZgqHu1w/JcUdWOE/BUEAzarrUUHh39eWkLdX8XpA6MfgLJF6X5Vl26CV7/wcm4O/UpZvHMGJUtB9eYTqDjc9g==}
|
||||
engines: {node: '>=12'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user