mirror of
https://github.com/gradio-app/gradio.git
synced 2024-12-21 02:19:59 +08:00
e8b2d8b2f8
* Fix a bug that caused the sample rate of audio to be 8000 Hz after trimming and a bug that caused volume amplification and clipping each time trimming was performed * Fix format * add changeset * add sample_rate param to waveform_options * add changeset * set WaveformOptions defaults * formatting * formatting * add changeset * audio * changes * add changeset * tweak sample rate logic + docstring * Tweak docstring * formatting * linting * type tweak * remove redundant None check * tweak waveform lifecycle * fix test --------- Co-authored-by: tsukumi <tsukumijima@users.noreply.github.com> Co-authored-by: Hannah <hannahblair@users.noreply.github.com> Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com> Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
import type WaveSurfer from "wavesurfer.js";
|
|
import { audioBufferToWav } from "./audioBufferToWav";
|
|
|
|
export interface LoadedParams {
|
|
autoplay?: boolean;
|
|
}
|
|
|
|
export function blob_to_data_url(blob: Blob): Promise<string> {
|
|
return new Promise((fulfill, reject) => {
|
|
let reader = new FileReader();
|
|
reader.onerror = reject;
|
|
reader.onload = () => fulfill(reader.result as string);
|
|
reader.readAsDataURL(blob);
|
|
});
|
|
}
|
|
|
|
export const process_audio = async (
|
|
audioBuffer: AudioBuffer,
|
|
start?: number,
|
|
end?: number,
|
|
waveform_sample_rate?: number
|
|
): Promise<Uint8Array> => {
|
|
const audioContext = new AudioContext({
|
|
sampleRate: waveform_sample_rate || audioBuffer.sampleRate
|
|
});
|
|
const numberOfChannels = audioBuffer.numberOfChannels;
|
|
const sampleRate = waveform_sample_rate || audioBuffer.sampleRate;
|
|
|
|
let trimmedLength = audioBuffer.length;
|
|
let startOffset = 0;
|
|
|
|
if (start && end) {
|
|
startOffset = Math.round(start * sampleRate);
|
|
const endOffset = Math.round(end * sampleRate);
|
|
trimmedLength = endOffset - startOffset;
|
|
}
|
|
|
|
const trimmedAudioBuffer = audioContext.createBuffer(
|
|
numberOfChannels,
|
|
trimmedLength,
|
|
sampleRate
|
|
);
|
|
|
|
for (let channel = 0; channel < numberOfChannels; channel++) {
|
|
const channelData = audioBuffer.getChannelData(channel);
|
|
const trimmedData = trimmedAudioBuffer.getChannelData(channel);
|
|
for (let i = 0; i < trimmedLength; i++) {
|
|
trimmedData[i] = channelData[startOffset + i];
|
|
}
|
|
}
|
|
|
|
return audioBufferToWav(trimmedAudioBuffer);
|
|
};
|
|
|
|
export function loaded(
|
|
node: HTMLAudioElement,
|
|
{ autoplay }: LoadedParams = {}
|
|
): void {
|
|
async function handle_playback(): Promise<void> {
|
|
if (!autoplay) return;
|
|
node.pause();
|
|
await node.play();
|
|
}
|
|
}
|
|
|
|
export const skip_audio = (waveform: WaveSurfer, amount: number): void => {
|
|
if (!waveform) return;
|
|
waveform.skip(amount);
|
|
};
|
|
|
|
export const get_skip_rewind_amount = (
|
|
audio_duration: number,
|
|
skip_length?: number | null
|
|
): number => {
|
|
if (!skip_length) {
|
|
skip_length = 5;
|
|
}
|
|
return (audio_duration / 100) * skip_length || 5;
|
|
};
|