ipyaudio 0.1.11__py3-none-any.whl → 0.1.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. ipyaudio/_frontend.py +1 -1
  2. ipyaudio/_version.py +1 -1
  3. ipyaudio/configs/recorder.json +1 -1
  4. ipyaudio/labextension/package.json +1 -1
  5. ipyaudio/labextension/static/270.9d58710e0ffc6e1c0316.js +1 -0
  6. ipyaudio/labextension/static/58.1d71425dd409ae479079.js +1 -0
  7. ipyaudio/labextension/static/third-party-licenses.json +2 -2
  8. ipyaudio/nbextension/index.js +1 -1
  9. ipyaudio/nbextension/index.js.map +1 -1
  10. ipyaudio/player.py +23 -28
  11. ipyaudio/recorder.py +45 -36
  12. ipyaudio/timer.py +57 -0
  13. ipyaudio/utils.py +16 -32
  14. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/package.json +1 -1
  15. ipyaudio-0.1.15.data/data/share/jupyter/labextensions/ipyaudio/static/270.9d58710e0ffc6e1c0316.js +1 -0
  16. ipyaudio-0.1.15.data/data/share/jupyter/labextensions/ipyaudio/static/58.1d71425dd409ae479079.js +1 -0
  17. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/third-party-licenses.json +2 -2
  18. ipyaudio-0.1.15.data/data/share/jupyter/nbextensions/ipyaudio/index.js +3 -0
  19. ipyaudio-0.1.15.data/data/share/jupyter/nbextensions/ipyaudio/index.js.map +1 -0
  20. {ipyaudio-0.1.11.dist-info → ipyaudio-0.1.15.dist-info}/METADATA +2 -2
  21. ipyaudio-0.1.15.dist-info/RECORD +46 -0
  22. ipyaudio/labextension/static/424.ca45437f3ff02b14458c.js +0 -1
  23. ipyaudio/labextension/static/58.0e2f3d700c41688625fe.js +0 -1
  24. ipyaudio-0.1.11.data/data/share/jupyter/labextensions/ipyaudio/static/424.ca45437f3ff02b14458c.js +0 -1
  25. ipyaudio-0.1.11.data/data/share/jupyter/labextensions/ipyaudio/static/58.0e2f3d700c41688625fe.js +0 -1
  26. ipyaudio-0.1.11.data/data/share/jupyter/nbextensions/ipyaudio/index.js +0 -3
  27. ipyaudio-0.1.11.data/data/share/jupyter/nbextensions/ipyaudio/index.js.map +0 -1
  28. ipyaudio-0.1.11.dist-info/RECORD +0 -45
  29. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/etc/jupyter/nbconfig/notebook.d/ipyaudio.json +0 -0
  30. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/install.json +0 -0
  31. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/122.3700f0454aee82938e32.js +0 -0
  32. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/509.a9d6860fe38ae60aa71f.js +0 -0
  33. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/570.97f2a8196b7f1703e636.js +0 -0
  34. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/570.97f2a8196b7f1703e636.js.LICENSE.txt +0 -0
  35. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/labextensions/ipyaudio/static/style.js +0 -0
  36. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/nbextensions/ipyaudio/extension.js +0 -0
  37. {ipyaudio-0.1.11.data → ipyaudio-0.1.15.data}/data/share/jupyter/nbextensions/ipyaudio/index.js.LICENSE.txt +0 -0
  38. {ipyaudio-0.1.11.dist-info → ipyaudio-0.1.15.dist-info}/WHEEL +0 -0
  39. {ipyaudio-0.1.11.dist-info → ipyaudio-0.1.15.dist-info}/licenses/LICENSE.txt +0 -0
ipyaudio/player.py CHANGED
@@ -6,7 +6,6 @@
6
6
 
7
7
  import asyncio
8
8
  import json
9
- import time
10
9
  from importlib.resources import files
11
10
  from pathlib import Path
12
11
  from types import AsyncGeneratorType, GeneratorType
@@ -14,14 +13,16 @@ from typing import Optional, Union
14
13
 
15
14
  import numpy as np
16
15
  import torch
16
+ from audiolab import encode
17
17
  from IPython.display import display
18
- from ipywidgets import DOMWidget, Label, ValueWidget, VBox, register
18
+ from ipywidgets import HTML, DOMWidget, ValueWidget, VBox, register
19
19
  from lhotse import Recording
20
20
  from lhotse.cut.base import Cut
21
- from traitlets import Bool, Dict, Float, Int, Unicode
21
+ from traitlets import Bool, Dict, Int, Unicode
22
22
 
23
23
  from ._frontend import module_name, module_version
24
- from .utils import encode, merge_dicts
24
+ from .timer import Timer
25
+ from .utils import merge_dicts, table
25
26
 
26
27
 
27
28
  @register
@@ -42,8 +43,6 @@ class Player(DOMWidget, ValueWidget):
42
43
  rate = Int(16000).tag(sync=True)
43
44
  is_streaming = Bool(False).tag(sync=True)
44
45
  is_done = Bool(False).tag(sync=True)
45
- latency = Int(0).tag(sync=True)
46
- rtf = Float(0).tag(sync=True)
47
46
 
48
47
  def __init__(
49
48
  self,
@@ -66,43 +65,39 @@ class Player(DOMWidget, ValueWidget):
66
65
  self.is_streaming = isinstance(audio, (AsyncGeneratorType, GeneratorType))
67
66
  if self.is_streaming and self.verbose:
68
67
  self.duration = 0
69
- self.latency_label = Label()
70
- self.rtf_label = Label()
71
- self.observe(self._on_latency_change, names="latency")
72
- self.observe(self._on_rtf_change, names="rtf")
73
- display(VBox([self, self.latency_label, self.rtf_label]))
68
+ self.html = HTML()
69
+ self.performance = {
70
+ "latency": ["延迟" if self.language == "zh" else "Latency", "0ms"],
71
+ "rtf": ["实时率" if self.language == "zh" else "Real-Time Factor", "0.00"],
72
+ }
73
+ self.html.value = table(self.performance)
74
+ display(VBox([self, self.html]))
74
75
  else:
75
76
  display(self)
76
77
 
77
- def _on_latency_change(self, change):
78
- label = "延迟" if self.language == "zh" else "Latency"
79
- self.latency_label.value = f"{label}: {self.latency} ms"
80
-
81
- def _on_rtf_change(self, change):
82
- label = "实时率" if self.language == "zh" else "Real-Time Factor"
83
- self.rtf_label.value = f"{label}: {self.rtf:.2f}"
84
-
85
- def encode_chunk(self, start, idx, chunk, rate):
78
+ def encode_chunk(self, idx, chunk, rate, timer: Timer):
86
79
  if self.is_streaming and self.verbose:
87
80
  if idx == 0:
88
- self.latency = int((time.time() - start) * 1000)
81
+ self.performance["latency"][1] = f"{int(timer.elapsed() * 1000)}ms"
89
82
  self.duration += chunk.shape[1] / rate
90
- self.rtf = (time.time() - start) / self.duration
91
- self.audio, self.rate = encode(chunk, rate, False)
83
+ if self.duration > 0:
84
+ self.performance["rtf"][1] = round(timer.elapsed() / self.duration, 2)
85
+ self.html.value = table(self.performance)
86
+ self.audio, self.rate = encode(chunk, rate, make_wav=False)
92
87
 
93
- async def async_encode(self, audio: AsyncGeneratorType, rate: int, start: float):
88
+ async def async_encode(self, audio: AsyncGeneratorType, rate: int, timer: Timer):
94
89
  async for idx, chunk in enumerate(audio):
95
- self.encode_chunk(start, idx, chunk, rate)
90
+ self.encode_chunk(idx, chunk, rate, timer)
96
91
 
97
92
  def play(self):
98
- start = time.time()
93
+ timer = Timer(language=self.language)
99
94
  if isinstance(self._audio, (str, Path, np.ndarray, torch.Tensor, Cut, Recording)):
100
95
  # [num_channels, num_samples]
101
96
  self.audio, self.rate = encode(self._audio, self.rate)
102
97
  elif isinstance(self._audio, AsyncGeneratorType):
103
- asyncio.create_task(self.async_encode(self._audio, self.rate, start))
98
+ asyncio.create_task(self.async_encode(self._audio, self.rate, timer))
104
99
  self.is_done = True
105
100
  else:
106
101
  for idx, chunk in enumerate(self._audio):
107
- self.encode_chunk(start, idx, chunk, self.rate)
102
+ self.encode_chunk(idx, chunk, self.rate, timer)
108
103
  self.is_done = True
ipyaudio/recorder.py CHANGED
@@ -13,11 +13,12 @@ import numpy as np
13
13
  from audiolab import StreamReader, Writer, filters
14
14
  from ipydatawidgets import NDArray, array_serialization, shape_constraints
15
15
  from IPython.display import display
16
- from ipywidgets import DOMWidget, Label, ValueWidget, VBox, register
16
+ from ipywidgets import HTML, DOMWidget, ValueWidget, VBox, register
17
17
  from traitlets import Bool, Dict, Int, Unicode
18
18
 
19
19
  from ._frontend import module_name, module_version
20
- from .utils import merge_dicts
20
+ from .timer import Timer
21
+ from .utils import merge_dicts, table
21
22
 
22
23
 
23
24
  @register
@@ -80,56 +81,64 @@ class Recorder(DOMWidget, ValueWidget):
80
81
  self.observe(self._on_completed_change, names="completed")
81
82
  self.observe(self._on_rate_change, names="rate")
82
83
  if self.sync and self.verbose:
83
- self.output_label = Label()
84
- self.rtf_label = Label()
85
- display(VBox([self, self.output_label, self.rtf_label]))
84
+ self.html = HTML()
85
+ self.performance = {
86
+ "state": ["状态" if self.language == "zh" else "State", ""],
87
+ "chunk": ["接收数据" if self.language == "zh" else "Received Data", "0B/0.00KB"],
88
+ "audio": ["解码音频" if self.language == "zh" else "Decoded audio", "0.00s"],
89
+ "latency": ["延迟" if self.language == "zh" else "Latency", "0ms"],
90
+ "rtf": ["实时率" if self.language == "zh" else "Real-Time Factor", 0],
91
+ }
92
+ self.html.value = table(self.performance)
93
+ display(VBox([self, self.html]))
86
94
  else:
87
95
  display(self)
88
96
 
89
97
  def _log_chunk(self, chunk):
90
- chunk_bytes = chunk.shape[0]
91
98
  recieved_bytes = self.stream_reader.bytestream.getbuffer().nbytes
92
- decoded_seconds = self.audio.shape[1] / self.rate
93
- self.output_label.value = "Chunk received" if self.language == "en" else "收到数据"
94
- self.output_label.value += f": {chunk_bytes}B/{recieved_bytes / 1024:.2f}KB ({decoded_seconds:.2f}s)."
95
- label = "实时率" if self.language == "zh" else "Real-Time Factor"
96
- if self.audio.shape[1] > 0:
97
- cost_time = time() - self.start
98
- decoded_seconds = self.audio.shape[1] / self.rate
99
- self.rtf_label.value = f"{label}: {cost_time / decoded_seconds:.2f}"
99
+ decoded_audio_seconds = self.audio.shape[1] / self.rate
100
+ self.performance["chunk"][1] = f"{chunk.shape[0]}B/{recieved_bytes / 1024:.2f}KB"
101
+ self.performance["audio"][1] = f"{decoded_audio_seconds:.2f}s"
102
+ self.performance["latency"][1] = f"{int((self.timer.elapsed() - decoded_audio_seconds) * 1000)}ms"
103
+ if decoded_audio_seconds > 0:
104
+ self.performance["rtf"][1] = round(self.timer.elapsed() / decoded_audio_seconds, 2)
100
105
  else:
101
- self.rtf_label.value = f"{label}: 0.00"
106
+ self.performance["rtf"][1] = 0.00
107
+ self.html.value = table(self.performance)
102
108
 
103
109
  def _on_chunk_change(self, change):
104
110
  # The comm API is a symmetric, asynchronous, `fire and forget` style messaging API.
105
111
  # Sends a message to the frontend to indicate that a chunk has been received.
106
112
  self.send({"msg_type": "chunk_received"})
107
113
 
108
- if self.verbose:
109
- self._log_chunk(change["new"])
110
- self.stream_reader.push(change["new"].tobytes())
111
- for frame, _ in self.stream_reader.pull():
112
- self.audio = np.concatenate((self.audio, frame), axis=1)
113
- self.frame = frame
114
+ if self.sync:
115
+ if self.verbose:
116
+ self._log_chunk(change["new"])
117
+ self.stream_reader.push(change["new"].tobytes())
118
+ for frame, _ in self.stream_reader.pull():
119
+ self.audio = np.concatenate((self.audio, frame), axis=1)
120
+ self.frame = frame
114
121
 
115
122
  def _on_completed_change(self, change):
116
- if self.verbose:
117
- self.output_label.value = "Completed" if self.language == "en" else "完成"
118
123
  if not change["new"]:
119
- if self.verbose:
120
- self.output_label.value = "Start recording." if self.language == "en" else "开始录音."
121
- self.start = time()
122
- self.audio = np.zeros((1, 0), dtype=np.float32)
123
- self.stream_reader.reset()
124
+ if self.sync:
125
+ if self.verbose:
126
+ self.performance["state"][1] = "Start recording" if self.language == "en" else "开始录音"
127
+ self.html.value = table(self.performance)
128
+ self.timer = Timer(language=self.language)
129
+ self.audio = np.zeros((1, 0), dtype=np.float32)
130
+ self.stream_reader.reset()
124
131
  else:
125
- if self.verbose:
126
- self.output_label.value = "End recording." if self.language == "en" else "结束录音."
127
- for frame, _ in self.stream_reader.pull(partial=True):
128
- self.audio = np.concatenate((self.audio, frame), axis=1)
129
- self.frame = frame
130
- if self.writer is not None:
131
- self.writer.write(self.audio)
132
- self.writer.close()
132
+ if self.sync:
133
+ if self.verbose:
134
+ self.performance["state"][1] = "End recording" if self.language == "en" else "结束录音"
135
+ self.html.value = table(self.performance)
136
+ for frame, _ in self.stream_reader.pull(partial=True):
137
+ self.audio = np.concatenate((self.audio, frame), axis=1)
138
+ self.frame = frame
139
+ if self.writer is not None:
140
+ self.writer.write(self.audio)
141
+ self.writer.close()
133
142
 
134
143
  def _on_rate_change(self, change):
135
144
  self.stream_reader.filters = [self.aformat(sample_rates=self.rate)]
ipyaudio/timer.py ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Copyright (c) Zhendong Peng.
5
+ # Distributed under the terms of the Modified BSD License.
6
+
7
+ import logging
8
+ import time
9
+
10
+ logging.basicConfig(level=logging.INFO)
11
+
12
+
13
+ class Timer:
14
+ def __init__(self, name=None, auto_start=True, language="en", verbose=False):
15
+ self.name = name
16
+ self.language = language
17
+ self.verbose = verbose
18
+ self.start_time = None
19
+ self.end_time = None
20
+ self.cost_label = "Cost time" if self.language == "en" else "耗时"
21
+ self.unit = "s" if self.language == "en" else "秒"
22
+ self.error_label = "Timer not started" if self.language == "en" else "计时器尚未开始"
23
+ if auto_start:
24
+ self.start()
25
+
26
+ def __enter__(self):
27
+ self.start_time = time.perf_counter()
28
+ return self
29
+
30
+ def __exit__(self, exc_type, exc_val, exc_tb):
31
+ self.end_time = time.perf_counter()
32
+ elapsed = self.end_time - self.start_time
33
+ if self.name:
34
+ logging.info(f"[{self.name}] {self.cost_label}: {elapsed:.6f} {self.unit}")
35
+ else:
36
+ logging.info(f"{self.cost_label}: {elapsed:.6f} {self.unit}")
37
+
38
+ def __str__(self):
39
+ return (
40
+ f"[{self.name}] {self.cost_label}: {self.elapsed():.6f} {self.unit}"
41
+ if self.name
42
+ else f"{self.cost_label}: {self.elapsed():.6f} {self.unit}"
43
+ )
44
+
45
+ def start(self):
46
+ self.start_time = time.perf_counter()
47
+ self.end_time = None
48
+
49
+ def elapsed(self):
50
+ if self.start_time is None:
51
+ raise RuntimeError(self.error_label)
52
+ end_time = self.end_time or time.perf_counter()
53
+ elapsed = end_time - self.start_time
54
+
55
+ if self.verbose:
56
+ logging.info(self.str())
57
+ return elapsed
ipyaudio/utils.py CHANGED
@@ -4,39 +4,19 @@
4
4
  # Copyright (c) Zhendong Peng.
5
5
  # Distributed under the terms of the Modified BSD License.
6
6
 
7
- import base64
8
- from pathlib import Path
9
- from typing import Optional, Union
7
+ from jinja2 import Template
10
8
 
11
- import numpy as np
12
- import torch
13
- from audiolab import filters, load_audio
14
- from IPython.display import Audio
15
- from lhotse import Recording
16
- from lhotse.cut.base import Cut
17
-
18
-
19
- def encode(
20
- audio: Union[str, Path, np.ndarray, torch.Tensor, Cut, Recording],
21
- rate: Optional[int] = None,
22
- make_wav: bool = True,
23
- ):
24
- """Transform an audio to a PCM bytestring"""
25
- if isinstance(audio, (str, Path)):
26
- aformat = filters.aformat(sample_fmts="flt", sample_rates=rate, channel_layouts="mono")
27
- audio, rate = load_audio(audio, filters=[aformat])
28
- if isinstance(audio, (Cut, Recording)):
29
- if rate is not None:
30
- audio = audio.resample(rate)
31
- rate = audio.sampling_rate
32
- audio = audio.load_audio()
33
- if make_wav:
34
- return Audio(audio, rate=rate).src_attr(), rate
35
- if audio.dtype == np.int16:
36
- audio = audio.astype(np.float32) / 32768
37
- # float32 to int16 bytes (Do not normalize for streaming chunks)
38
- audio, _ = Audio._validate_and_normalize_with_numpy(np.clip(audio, -1, 1), False)
39
- return base64.b64encode(audio).decode("ascii"), rate
9
+ template = """<table class="table table-bordered border-black">
10
+ <tr class="table-active">
11
+ {%- for key in dict.keys() %}
12
+ <th>{{ dict[key][0] }}</th>
13
+ {%- endfor %}
14
+ </tr>
15
+ {%- for key in dict.keys() %}
16
+ <td>{{ dict[key][1] }}</td>
17
+ {%- endfor %}
18
+ </tr>
19
+ </table>"""
40
20
 
41
21
 
42
22
  def merge_dicts(d1, d2):
@@ -46,3 +26,7 @@ def merge_dicts(d1, d2):
46
26
  else:
47
27
  d1[k] = d2[k]
48
28
  return d1
29
+
30
+
31
+ def table(dict: dict[str, list[str, str]]):
32
+ return Template(template).render(dict=dict)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ipyaudio",
3
- "version": "0.1.11",
3
+ "version": "0.1.15",
4
4
  "description": "A Custom Jupyter Widget Library",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkipyaudio=self.webpackChunkipyaudio||[]).push([[270],{311:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27none%27 stroke=%27%23212529%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3e%3cpath d=%27m2 5 6 6 6-6%27/%3e%3c/svg%3e"},319:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(s,a){function r(e){try{l(n.next(e))}catch(e){a(e)}}function o(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,o)}l((n=n.apply(e,t||[])).next())}))},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.RecorderView=t.RecorderModel=void 0;const a=s(i(5364)),r=i(3459),o=i(3983),l=i(1797),c=s(i(1136)),u=s(i(8020));i(6378),i(1463);class d extends o.DOMWidgetModel{defaults(){return Object.assign(Object.assign({},super.defaults()),{_model_name:d.model_name,_model_module:d.model_module,_model_module_version:d.model_module_version,_view_name:d.view_name,_view_module:d.view_module,_view_module_version:d.view_module_version,chunk:new Uint8Array(0),rate:16e3,end:!1})}}t.RecorderModel=d,d.serializers=Object.assign(Object.assign({},o.DOMWidgetModel.serializers),{chunk:r.simplearray_serialization}),d.model_name="RecorderModel",d.model_module=l.MODULE_NAME,d.model_module_version=l.MODULE_VERSION,d.view_name="RecorderView",d.view_module=l.MODULE_NAME,d.view_module_version=l.MODULE_VERSION;class h extends o.DOMWidgetView{constructor(){super(...arguments),this._chunks=new c.default,this._isFirstChunk=!0,this._isCompleted=!1}_sendChunk(){var e;return n(this,void 0,void 0,(function*(){if(this._chunks.length>0){const t=yield this._chunks.dequeue(1e3+(null!==(e=this._recorder.timeSlice)&&void 0!==e?e:20));t.length>0&&(this.model.set("chunk",{array:t,shape:[t.length]}),this.model.save_changes())}else this._isCompleted&&(this.model.set("completed",!0),this.model.save_changes())}))}render(){super.render(),this.displayed.then((()=>n(this,void 0,void 0,(function*(){const e=this.model.get("language");this._recorder=u.default.create((0,a.default)({},this.model.get("config"),{language:e}),(0,a.default)({},this.model.get("player_config"),{language:e})),this.el.appendChild(this._recorder.el),this.model.on("msg:custom",(e=>n(this,void 0,void 0,(function*(){"chunk_received"===e.msg_type&&this._sendChunk()})))),this._recorder.onRecordStart((()=>{this._isCompleted=!1,this._isFirstChunk=!0,this.model.set("completed",!1),this.model.set("rate",this._recorder.sampleRate),this.model.save_changes()})),this._recorder.onRecordChunk((e=>n(this,void 0,void 0,(function*(){this._chunks.enqueue(new Uint8Array(yield e.arrayBuffer())),this.model.get("sync")&&this._isFirstChunk&&(this._isFirstChunk=!1,this._sendChunk())})))),this._recorder.onRecordEnd((e=>n(this,void 0,void 0,(function*(){this._isCompleted=!0,this.model.get("sync")||(this.model.set("completed",!0),this.model.save_changes())}))))}))))}}t.RecorderView=h},644:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3e%3cpath d=%27M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0%27/%3e%3c/svg%3e"},1136:function(e,t){var i=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(s,a){function r(e){try{l(n.next(e))}catch(e){a(e)}}function o(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,o)}l((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(){this.queue=[],this.resolveDequeue=null,this.waitingDequeue=null}mergeAllChunks(){if(0===this.queue.length)return new Uint8Array(0);let e=0;for(const t of this.queue)e+=t.length;const t=new Uint8Array(e);let i=0;for(const e of this.queue)t.set(e,i),i+=e.length;return t}enqueue(e){if(this.queue.push(e),this.resolveDequeue){const e=this.mergeAllChunks();this.resolveDequeue(e),this.queue.length=0,this.resolveDequeue=null,this.waitingDequeue=null}}dequeue(e=0){return i(this,void 0,void 0,(function*(){if(this.queue.length>0){const e=this.mergeAllChunks();return this.queue.length=0,e}if(!this.waitingDequeue&&(this.waitingDequeue=new Promise((e=>{this.resolveDequeue=e})),e>0)){const t=setTimeout((()=>{this.resolveDequeue&&(this.resolveDequeue(new Uint8Array(0)),this.resolveDequeue=null,this.waitingDequeue=null)}),e);this.waitingDequeue.then((()=>{t&&clearTimeout(t)})).catch((()=>{t&&clearTimeout(t)}))}return this.waitingDequeue}))}get length(){return this.queue.length}}},1368:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3e%3cpath d=%27M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708%27/%3e%3c/svg%3e"},1451:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27none%27 stroke=%27%23052c65%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3e%3cpath d=%27m2 5 6 6 6-6%27/%3e%3c/svg%3e"},1463:(e,t,i)=>{i.r(t),i.d(t,{default:()=>v});var n=i(5072),s=i.n(n),a=i(7825),r=i.n(a),o=i(7659),l=i.n(o),c=i(5056),u=i.n(c),d=i(540),h=i.n(d),m=i(1113),p=i.n(m),g=i(4930),_={};_.styleTagTransform=p(),_.setAttributes=u(),_.insert=l().bind(null,"head"),_.domAPI=r(),_.insertStyleElement=h(),s()(g.A,_);const v=g.A&&g.A.locals?g.A.locals:void 0},1797:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MODULE_NAME=t.MODULE_VERSION=void 0;const n=i(8330);t.MODULE_VERSION=n.version,t.MODULE_NAME=n.name},2247:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27rgba%2833, 37, 41, 0.75%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e"},3385:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e"},4274:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e"},4364:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(s,a){function r(e){try{l(n.next(e))}catch(e){a(e)}}function o(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,o)}l((n=n.apply(e,t||[])).next())}))},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.PlayerView=t.PlayerModel=void 0;const a=s(i(5364)),r=i(3983),o=i(1797),l=s(i(9155));i(6378),i(1463);class c extends r.DOMWidgetModel{defaults(){return Object.assign(Object.assign({},super.defaults()),{_model_name:c.model_name,_model_module:c.model_module,_model_module_version:c.model_module_version,_view_name:c.view_name,_view_module:c.view_module,_view_module_version:c.view_module_version})}}t.PlayerModel=c,c.serializers=Object.assign({},r.DOMWidgetModel.serializers),c.model_name="PlayerModel",c.model_module=o.MODULE_NAME,c.model_module_version=o.MODULE_VERSION,c.view_name="PlayerView",c.view_module=o.MODULE_NAME,c.view_module_version=o.MODULE_VERSION;class u extends r.DOMWidgetView{render(){super.render(),this.displayed.then((()=>n(this,void 0,void 0,(function*(){const e={isStreaming:this.model.get("is_streaming"),language:this.model.get("language")};this._player=l.default.create((0,a.default)({},this.model.get("config"),e)),this.el.appendChild(this._player.el),this.model.on("change:audio",(()=>{this._player.sampleRate=this.model.get("rate"),this._player.load(this.model.get("audio"))})),this.model.on("change:is_done",(()=>{this._player.setDone()}))}))))}}t.PlayerView=u},4718:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e"},4914:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%236ea8fe%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708%27/%3e%3c/svg%3e"},4930:(e,t,i)=>{i.d(t,{A:()=>o});var n=i(1601),s=i.n(n),a=i(6314),r=i.n(a)()(s());r.push([e.id,".waveform {\n background-color: black;\n cursor: pointer;\n position: relative;\n width: 100%;\n}\n\n.duration, .time {\n background: rgba(0, 0, 0, 0.75);\n color: #DDDD;\n font-size: 11px;\n position: absolute;\n bottom: 0;\n z-index: 11;\n}\n\n.duration {\n right: 0;\n}\n\n.time {\n left: 0;\n}\n",""]);const o=r},5372:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23dc3545%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23dc3545%27 stroke=%27none%27/%3e%3c/svg%3e"},5419:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27m6 10 3 3 6-6%27/%3e%3c/svg%3e"},5531:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3e%3cpath fill=%27none%27 stroke=%27%23343a40%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%272%27 d=%27m2 5 6 6 6-6%27/%3e%3c/svg%3e"},5782:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%2386b7fe%27/%3e%3c/svg%3e"},5967:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23000%27%3e%3cpath d=%27M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414%27/%3e%3c/svg%3e"},6366:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27rgba%28255, 255, 255, 0.55%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e"},7115:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3e%3cpath fill=%27none%27 stroke=%27%23dee2e6%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%272%27 d=%27m2 5 6 6 6-6%27/%3e%3c/svg%3e"},7154:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280, 0, 0, 0.25%29%27/%3e%3c/svg%3e"},7997:(e,t)=>{function i(e){const t=e.numFrames,i=e.numChannels||2,n=e.sampleRate||44100,s=e.isFloat?4:2,a=e.isFloat?3:1,r=i*s,o=n*r,l=t*r,c=new ArrayBuffer(44),u=new DataView(c);let d=0;function h(e){for(let t=0;t<e.length;t++)u.setUint8(d+t,e.charCodeAt(t));d+=e.length}function m(e){u.setUint32(d,e,!0),d+=4}function p(e){u.setUint16(d,e,!0),d+=2}return h("RIFF"),m(l+36),h("WAVE"),h("fmt "),m(16),p(a),p(i),m(n),m(o),p(r),p(8*s),h("data"),m(l),new Uint8Array(c)}function n(e,t){if(!e)return new Uint8Array;let n,s;e instanceof ArrayBuffer?(n=i({isFloat:!1,numChannels:t.numChannels,sampleRate:t.sampleRate,numFrames:e.byteLength/Int16Array.BYTES_PER_ELEMENT}),s=new Uint8Array(e)):(n=i({isFloat:!1,numChannels:e.numberOfChannels,sampleRate:e.sampleRate,numFrames:e.length}),s=new Uint8Array(function(e){const{numberOfChannels:t,length:i}=e,n=new Int16Array(i*t);for(let s=0;s<t;s++){const a=e.getChannelData(s),r=a instanceof Float32Array;for(let e=0;e<i;e++)n[e*t+s]=r?32767*a[e]:a[e]}return n}(e).buffer));const a=new Uint8Array(n.length+s.length);return a.set(n,0),a.set(s,n.length),a}Object.defineProperty(t,"__esModule",{value:!0}),t.createObjectURL=t.formatTime=t.createElement=void 0,t.createElement=(e,t,i="")=>{const n=document.createElement(e);return n.className=t,n.innerHTML=i,n},t.formatTime=e=>`${Math.floor(e/60)}:${("0"+Math.round(e)%60).slice(-2)}`,t.createObjectURL=(e,t={numChannels:1,sampleRate:44100})=>{let i;return i=e instanceof AudioBuffer?n(e,{numChannels:e.numberOfChannels,sampleRate:e.sampleRate}):n(e,t),URL.createObjectURL(new Blob([i],{type:"audio/wav"}))}},8020:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(s,a){function r(e){try{l(n.next(e))}catch(e){a(e)}}function o(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,o)}l((n=n.apply(e,t||[])).next())}))},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(i(423)),r=s(i(8429)),o=s(i(9155)),l=i(7997);class c{constructor(e,t){this.el=(0,l.createElement)("div","lm-Widget"),this._container=(0,l.createElement)("div","waveform"),this._currentTime=(0,l.createElement)("div","time","0:00"),this._container.append(this._currentTime),this._config=e,this._player=o.default.create(t)}get sampleRate(){return this._wavesurfer.options.sampleRate}get timeSlice(){var e;return null===(e=this._config.recordOptions)||void 0===e?void 0:e.mediaRecorderTimeslice}set sampleRate(e){this._wavesurfer.options.sampleRate=e,this._player.sampleRate=e}createWaveSurfer(){this._wavesurfer=a.default.create(Object.assign(Object.assign({},this._config.options),{container:this._container}))}createRateSelect(){this._rateSelect=(0,l.createElement)("select","form-select-sm d-inline-block me-3 my-3 w-25"),[8e3,16e3,22050,24e3,44100,48e3].forEach((e=>{const t=document.createElement("option");t.value=e.toString(),t.text=`${e} Hz`,16e3===e&&(t.selected=!0),this._rateSelect.appendChild(t)}))}createMicSelect(){this._micSelect=(0,l.createElement)("select","form-select-sm d-inline-block me-3 my-3 w-50"),navigator.mediaDevices.getUserMedia({audio:!0,video:!1}).then((e=>{r.default.getAvailableAudioDevices().then((e=>{e.forEach((e=>{const t=document.createElement("option");t.value=e.deviceId,t.text=e.label||e.deviceId,this._micSelect.appendChild(t)}))}))})).catch((e=>{const t="zh"===this._config.language?"访问麦克风失败":"Error accessing the microphone: ";throw new Error(t+e.message)}))}createPauseButton(){this._pauseButton=(0,l.createElement)("button","btn btn-outline-danger me-3 my-3",'<i class="fa fa-pause"></i>'),this._pauseButton.disabled=!0,this._pauseButton.onclick=()=>{this._recorder.isRecording()?(this._recorder.pauseRecording(),this._pauseButton.innerHTML='<i class="fa fa-play"></i>',this._container.style.display="none",this._player.el.style.display="block"):(this._recorder.resumeRecording(),this._pauseButton.innerHTML='<i class="fa fa-pause"></i>',this._container.style.display="block",this._player.el.style.display="none")}}createRecordButton(){this._recordButton=(0,l.createElement)("button","btn btn-danger me-3 my-3",'<i class="fa fa-microphone"></i>'),this._recordButton.onclick=()=>{this._recorder.isRecording()||this._recorder.isPaused()?(this._recorder.stopRecording(),this._container.style.display="none",this._player.el.style.display="block"):(this._wavesurfer.options.normalize=!1,this.sampleRate=parseInt(this._rateSelect.value),this._recorder.startRecording({deviceId:this._micSelect.value}).then((()=>{this._pauseButton.disabled=!1,this._rateSelect.disabled=!0,this._micSelect.disabled=!0,this._pauseButton.innerHTML='<i class="fa fa-pause"></i>',this._recordButton.innerHTML='<i class="fa fa-stop"></i>',this._container.style.display="block",this._player.el.style.display="none"})))}}onRecordStart(e){this._recorder.on("record-start",(()=>{e()}))}onRecordChunk(e){this._recorder.on("record-data-available",(t=>{e(t)}))}onRecordEnd(e){this._recorder.on("record-end",(t=>n(this,void 0,void 0,(function*(){this._player.load(URL.createObjectURL(t)),this._recordButton.disabled=!0,this._pauseButton.disabled=!0,yield e(t),this._recordButton.disabled=!1,this._pauseButton.disabled=!0,this._rateSelect.disabled=!1,this._micSelect.disabled=!1,this._pauseButton.innerHTML='<i class="fa fa-play"></i>',this._recordButton.innerHTML='<i class="fa fa-microphone"></i>'}))))}createRecorder(){this._wavesurfer.toggleInteraction(!1),this._recorder=this._wavesurfer.registerPlugin(r.default.create(this._config.recordOptions)),this.createRateSelect(),this.createMicSelect(),this.createPauseButton(),this.createRecordButton(),this._container.style.display="none",this._player.el.style.display="none",this.el.append(this._recordButton,this._pauseButton,this._rateSelect,this._micSelect,this._container,this._player.el),this._recorder.on("record-pause",(e=>{this._player.load(URL.createObjectURL(e))})),this._recorder.on("record-progress",(e=>{this._currentTime.textContent=(0,l.formatTime)(e/1e3)}))}static create(e,t){const i=new c(e,t);return i.createWaveSurfer(),i.createRecorder(),i}}t.default=c},8078:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(s,a){function r(e){try{l(n.next(e))}catch(e){a(e)}}function o(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,o)}l((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.PCMPlayer=void 0;const s=i(7997);class a{constructor(e){this._isDone=!1,this._isPlaying=!0,this._samples=new Int16Array(0),this._allSamples=new Int16Array(0),this._options=Object.assign({channels:1,sampleRate:16e3,flushTime:100,language:"en"},e),this.playButton=(0,s.createElement)("button","btn btn-danger me-3 my-3",'<i class="fa fa-pause"></i>'),this.playButton.onclick=()=>{this._isPlaying=!this._isPlaying,this._isPlaying?this.play():this.pause(),this.playButton.innerHTML=`<i class="fa fa-${this._isPlaying?"pause":"play"}"></i>`},this._interval=window.setInterval(this.flush.bind(this),this._options.flushTime),this._audioCtx=new(window.AudioContext||window.webkitAudioContext),this._gainNode=this._audioCtx.createGain(),this._gainNode.gain.value=1,this._gainNode.connect(this._audioCtx.destination),this._startTime=this._audioCtx.currentTime}set sampleRate(e){this._options.sampleRate=e}setDone(){this._isDone=!0}feed(e){const t=atob(e),i=new ArrayBuffer(t.length),n=new Uint8Array(i);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);const s=new Int16Array(i);this._samples=new Int16Array([...this._samples,...s]),this._allSamples=new Int16Array([...this._allSamples,...s])}get url(){return(0,s.createObjectURL)(this._allSamples.buffer,{numChannels:this._options.channels,sampleRate:this._options.sampleRate})}flush(){if(!this._samples.length)return;const e=this._isDone,t=this._audioCtx.createBufferSource(),i=this._samples.length/this._options.channels,n=this._audioCtx.createBuffer(this._options.channels,i,this._options.sampleRate);for(let e=0;e<this._options.channels;e++){const t=n.getChannelData(e);let s=e;for(let e=0;e<i;e++)t[e]=this._samples[s]/32768,s+=this._options.channels}this._startTime=Math.max(this._startTime,this._audioCtx.currentTime),t.buffer=n,t.connect(this._gainNode),t.start(this._startTime),t.onended=()=>{this.playButton.disabled=!!e},this._startTime+=n.duration,this._samples=new Int16Array(0)}play(){return n(this,void 0,void 0,(function*(){yield this._audioCtx.resume()}))}pause(){return n(this,void 0,void 0,(function*(){yield this._audioCtx.suspend()}))}volume(e){this._gainNode.gain.value=e}destroy(){this._interval&&clearInterval(this._interval),this._samples=new Int16Array(0),this._audioCtx.close()}}t.PCMPlayer=a,t.default=a},8330:e=>{e.exports=JSON.parse('{"name":"ipyaudio","version":"0.1.15","description":"A Custom Jupyter Widget Library","keywords":["jupyter","jupyterlab","jupyterlab-extension","widgets"],"files":["lib/**/*.js","dist/*.js","css/*.css"],"homepage":"https://github.com/pengzhendong/ipyaudio","bugs":{"url":"https://github.com/pengzhendong/ipyaudio/issues"},"license":"BSD-3-Clause","author":{"name":"Zhendong Peng","email":"pzd17@tsinghua.org.cn"},"main":"lib/index.js","types":"./lib/index.d.ts","repository":{"type":"git","url":"git+https://github.com/pengzhendong/ipyaudio.git"},"scripts":{"build":"jlpm run build:lib && jlpm run build:nbextension && jlpm run build:labextension:dev","build:prod":"jlpm run build:lib && jlpm run build:nbextension && jlpm run build:labextension","build:labextension":"jupyter labextension build .","build:labextension:dev":"jupyter labextension build --development True .","build:lib":"tsc","build:nbextension":"webpack","clean":"jlpm run clean:lib && jlpm run clean:nbextension && jlpm run clean:labextension","clean:lib":"rimraf lib","clean:labextension":"rimraf ipyaudio/labextension","clean:nbextension":"rimraf ipyaudio/nbextension/static/index.js","lint":"eslint . --ext .ts,.tsx --fix","lint:check":"eslint . --ext .ts,.tsx","prepack":"jlpm run build:lib","test":"jest","watch":"npm-run-all -p \\"watch:*\\"","watch:lib":"tsc -w","watch:nbextension":"webpack --watch --mode=development","watch:labextension":"jupyter labextension watch ."},"dependencies":{"@jupyter-widgets/base":"^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6","bootstrap":"^5.3.3","jupyter-dataserializers":"^3.0.1","lodash.merge":"^4.6.2"},"devDependencies":{"@babel/core":"^7.23.7","@babel/preset-env":"^7.23.8","@jupyter-widgets/base-manager":"^1.0.7","@jupyterlab/builder":"^4.0.11","@lumino/application":"^2.3.0","@lumino/widgets":"^2.3.1","@types/jest":"^29.5.11","@types/webpack-env":"^1.18.4","@typescript-eslint/eslint-plugin":"^6.19.1","@typescript-eslint/parser":"^6.19.1","acorn":"^8.11.3","css-loader":"^6.9.1","eslint":"^8.56.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.3","fs-extra":"^11.2.0","identity-obj-proxy":"^3.0.0","jest":"^29.7.0","mkdirp":"^3.0.1","npm-run-all":"^4.1.5","prettier":"^3.2.4","rimraf":"^5.0.5","source-map-loader":"^5.0.0","style-loader":"^3.3.4","ts-jest":"^29.1.2","ts-loader":"^9.5.1","typescript":"~5.3.3","wavesurfer.js":"^7.9.1","webpack":"^5.90.0","webpack-cli":"^5.1.4"},"devDependenciesComments":{"@jupyterlab/builder":"pinned to the latest JupyterLab 3.x release","@lumino/application":"pinned to the latest Lumino 1.x release","@lumino/widgets":"pinned to the latest Lumino 1.x release"},"jupyterlab":{"extension":"lib/plugin","outputDir":"ipyaudio/labextension/","sharedPackages":{"@jupyter-widgets/base":{"bundled":false,"singleton":true}}},"packageManager":"yarn@4.8.1"}')},8661:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%23198754%27 d=%27M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1%27/%3e%3c/svg%3e"},8734:e=>{e.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%28255, 255, 255, 0.25%29%27/%3e%3c/svg%3e"},9155:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const s=n(i(423)),a=n(i(980)),r=n(i(8659)),o=n(i(8541)),l=n(i(1427)),c=n(i(3875)),u=n(i(8078)),d=i(7997);class h{constructor(e){this.el=(0,d.createElement)("div","lm-Widget"),this._container=(0,d.createElement)("div","waveform"),this._duration=(0,d.createElement)("div","duration","0:00"),this._currentTime=(0,d.createElement)("div","time","0:00"),this._container.append(this._duration,this._currentTime),this.el.append(this._container),this._config=e}get url(){return this._config.isStreaming?this._pcmPlayer.url:(0,d.createObjectURL)(this._wavesurfer.getDecodedData())}set sampleRate(e){this._config.isStreaming&&(this._pcmPlayer.sampleRate=e),this._wavesurfer.options.sampleRate=e}load(e){this._config.isStreaming?(this._pcmPlayer.feed(e),this._wavesurfer.load(this.url)):this._wavesurfer.load(e)}setDone(){this._pcmPlayer.setDone()}createPCMPlayer(){this._config.isStreaming&&(this._pcmPlayer=new u.default({channels:1,sampleRate:this._config.options.sampleRate}),this.el.append(this._pcmPlayer.playButton))}createDownloadButton(){this._downloadButton=(0,d.createElement)("button","btn btn-success my-3");const e="zh"===this._config.language?"下载":"Download";this._downloadButton.innerHTML=`${e} <i class="fa fa-download"></i>`,this.el.append(this._downloadButton),this._downloadButton.onclick=()=>{const e=document.createElement("a");e.href=this.url,e.download="audio.wav",e.click()}}static createPlugins(e){var t;const i={hover:()=>{var t;return a.default.create(null===(t=e.pluginOptions)||void 0===t?void 0:t.hover)},minimap:()=>{var t,i;return r.default.create(Object.assign(Object.assign({},null===(t=e.pluginOptions)||void 0===t?void 0:t.minimap),{plugins:[a.default.create(Object.assign(Object.assign({},null===(i=e.pluginOptions)||void 0===i?void 0:i.hover),{lineWidth:1}))]}))},spectrogram:()=>{var t;return o.default.create(null===(t=e.pluginOptions)||void 0===t?void 0:t.spectrogram)},timeline:()=>{var t;return l.default.create(null===(t=e.pluginOptions)||void 0===t?void 0:t.timeline)},zoom:()=>{var t;return c.default.create(null===(t=e.pluginOptions)||void 0===t?void 0:t.zoom)}};return Array.from(null!==(t=e.plugins)&&void 0!==t?t:[]).map((e=>{var t;return null===(t=i[e])||void 0===t?void 0:t.call(i)})).filter(Boolean)}createWaveSurfer(){this._wavesurfer=s.default.create(Object.assign(Object.assign({},this._config.options),{container:this._container,plugins:h.createPlugins(this._config)})),this._wavesurfer.on("interaction",(()=>this._wavesurfer.playPause())),this._wavesurfer.on("decode",(e=>this._duration.textContent=(0,d.formatTime)(e))),this._wavesurfer.on("timeupdate",(e=>this._currentTime.textContent=(0,d.formatTime)(e)))}static create(e){const t=new h(e);return t.createWaveSurfer(),t.createPCMPlayer(),t.createDownloadButton(),t}}t.default=h}}]);