clement-pages commited on
Commit
7615d1a
·
1 Parent(s): df60b7b

add source selection

Browse files
sourceviewer/frontend/player/AudioPlayer.svelte CHANGED
@@ -7,20 +7,14 @@
7
  import { skip_audio, process_audio } from "../shared/utils";
8
  import WaveformControls from "../shared/WaveformControls.svelte";
9
  import { Empty } from "@gradio/atoms";
10
- import { resolve_wasm_src } from "@gradio/wasm/svelte";
11
  import type { FileData } from "@gradio/client";
12
  import type { WaveformOptions, Segment } from "../shared/types";
13
  import { createEventDispatcher } from "svelte";
14
 
15
  export let value: null | {"segments": Segment[], "sources_file": FileData}= null;
16
- $: url = value?.sources_file.url;
17
  export let label: string;
18
  export let root: string;
19
  export let i18n: I18nFormatter;
20
- export let dispatch_blob: (
21
- blobs: Uint8Array[] | Blob[],
22
- event: "stream" | "change" | "stop_recording"
23
- ) => Promise<void> = () => Promise.resolve();
24
  export let interactive = false;
25
  export let editable = true;
26
  export let waveform_settings: Record<string, any>;
@@ -39,6 +33,10 @@
39
 
40
  let colors: string[] = ["red", "green", "blue", "yellow", "magenta", "cyan"];
41
 
 
 
 
 
42
  let trimDuration = 0;
43
 
44
  let show_volume_slider = false;
@@ -52,11 +50,16 @@
52
  }>();
53
 
54
  const create_waveform = (): void => {
 
 
 
 
 
55
  waveform = WaveSurfer.create({
56
  container: container,
 
57
  ...waveform_settings
58
  });
59
- waveform.load(root + `/file=${value.sources_file.path}`)
60
  };
61
 
62
  $: if (container !== undefined) {
@@ -67,9 +70,17 @@
67
  }
68
 
69
  $: waveform?.on("decode", (duration: any) => {
 
 
70
  audio_duration = duration;
71
  durationRef && (durationRef.textContent = format_time(duration));
 
 
72
 
 
 
 
 
73
  if(!wsRegion){
74
  wsRegion = waveform.registerPlugin(RegionsPlugin.create())
75
  value.segments.forEach(segment => {
@@ -81,8 +92,8 @@
81
  resize: false,
82
  color: colors[segment.channel % colors.length],
83
  });
84
- console.log(region.color)
85
- const regionHeight = 100 / waveform.getDecodedData().numberOfChannels;
86
  region.element.style.cssText += `height: ${regionHeight}% !important;`
87
  });
88
  }
@@ -115,35 +126,6 @@
115
  dispatch("play");
116
  });
117
 
118
- const handle_trim_audio = async (
119
- start: number,
120
- end: number
121
- ): Promise<void> => {
122
- mode = "";
123
- const decodedData = waveform?.getDecodedData();
124
- if (decodedData)
125
- await process_audio(
126
- decodedData,
127
- start,
128
- end,
129
- waveform_settings.sampleRate
130
- ).then(async (trimmedBlob: Uint8Array) => {
131
- await dispatch_blob([trimmedBlob], "change");
132
- waveform?.destroy();
133
- container.innerHTML = "";
134
- });
135
- dispatch("edit");
136
- };
137
-
138
- async function load_audio(data: string): Promise<void> {
139
- await resolve_wasm_src(data).then((resolved_src) => {
140
- if (!resolved_src || value?.sources_file.is_stream) return;
141
- return waveform?.load(resolved_src);
142
- });
143
- }
144
-
145
- $: url && load_audio(url);
146
-
147
  onMount(() => {
148
  window.addEventListener("keydown", (e) => {
149
  if (!waveform || show_volume_slider) return;
@@ -186,6 +168,23 @@
186
  </div>
187
  </div>
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  {#if waveform}
190
  <WaveformControls
191
  {waveform}
 
7
  import { skip_audio, process_audio } from "../shared/utils";
8
  import WaveformControls from "../shared/WaveformControls.svelte";
9
  import { Empty } from "@gradio/atoms";
 
10
  import type { FileData } from "@gradio/client";
11
  import type { WaveformOptions, Segment } from "../shared/types";
12
  import { createEventDispatcher } from "svelte";
13
 
14
  export let value: null | {"segments": Segment[], "sources_file": FileData}= null;
 
15
  export let label: string;
16
  export let root: string;
17
  export let i18n: I18nFormatter;
 
 
 
 
18
  export let interactive = false;
19
  export let editable = true;
20
  export let waveform_settings: Record<string, any>;
 
33
 
34
  let colors: string[] = ["red", "green", "blue", "yellow", "magenta", "cyan"];
35
 
36
+ let audioDecoded: boolean = false;
37
+ let audioContext: AudioContext | undefined;
38
+ let mediaNode: MediaElementAudioSourceNode | undefined;
39
+ let splitter: ChannelSplitterNode | undefined;
40
  let trimDuration = 0;
41
 
42
  let show_volume_slider = false;
 
50
  }>();
51
 
52
  const create_waveform = (): void => {
53
+ const audio = new Audio(root + `/file=${value.sources_file.path}`)
54
+ audio.crossOrigin = "anonymous"
55
+
56
+ audioContext = new AudioContext();
57
+
58
  waveform = WaveSurfer.create({
59
  container: container,
60
+ media: audio,
61
  ...waveform_settings
62
  });
 
63
  };
64
 
65
  $: if (container !== undefined) {
 
70
  }
71
 
72
  $: waveform?.on("decode", (duration: any) => {
73
+ audioDecoded = true;
74
+ const numChannels = waveform.getDecodedData().numberOfChannels;
75
  audio_duration = duration;
76
  durationRef && (durationRef.textContent = format_time(duration));
77
+
78
+ mediaNode = audioContext.createMediaElementSource(waveform.getMediaElement() );
79
 
80
+ splitter = audioContext.createChannelSplitter(numChannels);
81
+ mediaNode.connect(splitter);
82
+
83
+ // add diarization annotation on each source:
84
  if(!wsRegion){
85
  wsRegion = waveform.registerPlugin(RegionsPlugin.create())
86
  value.segments.forEach(segment => {
 
92
  resize: false,
93
  color: colors[segment.channel % colors.length],
94
  });
95
+
96
+ const regionHeight = 100 / numChannels;
97
  region.element.style.cssText += `height: ${regionHeight}% !important;`
98
  });
99
  }
 
126
  dispatch("play");
127
  });
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  onMount(() => {
130
  window.addEventListener("keydown", (e) => {
131
  if (!waveform || show_volume_slider) return;
 
168
  </div>
169
  </div>
170
 
171
+ {#if audioDecoded}
172
+ {#each [...Array(waveform.getDecodedData().numberOfChannels).keys()] as channelIdx}
173
+ <label>
174
+ <input
175
+ type="radio"
176
+ name="channels"
177
+ value={`${channelIdx}`}
178
+ on:change={(ev) => {
179
+ splitter.disconnect()
180
+ splitter.connect(audioContext.destination, Number(ev.target.value), 0);
181
+ }}
182
+ />
183
+ {channelIdx}
184
+ </label>
185
+ {/each}
186
+ {/if}
187
+
188
  {#if waveform}
189
  <WaveformControls
190
  {waveform}