|
import gradio as gr |
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
from matplotlib.animation import FuncAnimation |
|
from matplotlib.colors import to_hex |
|
import librosa |
|
import tempfile |
|
|
|
def check_rgba(string:str): |
|
if '#' in string: |
|
return string |
|
else: |
|
clean_str_list = string.split("(")[1].split(")")[0].split(",") |
|
clean_list = [float(value.strip()) / 255 if idx != 3 else float(value.strip()) / 1 for idx, value in enumerate(clean_str_list)] |
|
hex = to_hex(clean_list, keep_alpha=True) |
|
return hex |
|
|
|
def extract_waveform_animation(audio_file, window_seconds, waveform_color, background_color): |
|
y, sr = librosa.load(audio_file, sr=None) |
|
duration = librosa.get_duration(y=y, sr=sr) |
|
FPS = 1 |
|
fig, ax = plt.subplots() |
|
line, = ax.plot([], [], lw=2, color=check_rgba(waveform_color)) |
|
window_length = int(window_seconds * sr) |
|
x_vals = np.linspace(0, duration, num=len(y)) |
|
ax.set_axis_off() |
|
bg_color = check_rgba(background_color) |
|
fig.set_facecolor(bg_color) |
|
|
|
def init(): |
|
ax.set_xlim(0, window_seconds) |
|
ax.set_ylim(np.min(y), np.max(y)) |
|
return line, |
|
|
|
def update(frame): |
|
|
|
start = frame * sr |
|
end = start + window_length |
|
window = y[start:end] |
|
|
|
|
|
ax.set_xlim(frame, frame + window_seconds) |
|
|
|
|
|
line.set_data(x_vals[start:end], window) |
|
return line, |
|
|
|
total_frames = int(duration) * FPS |
|
ani = FuncAnimation(fig, update, frames=range(total_frames), |
|
init_func=init, interval=window_seconds, blit=False) |
|
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix='.gif') as tmpfile: |
|
ani.save(tmpfile.name, writer='ffmpeg', fps=FPS) |
|
video_path = tmpfile.name |
|
|
|
return video_path |
|
|
|
|
|
iface = gr.Interface( |
|
fn=extract_waveform_animation, |
|
inputs=[ |
|
gr.Audio(type="filepath"), |
|
gr.Slider(1, 10, value=5, step=1, label="Window Size (seconds)"), |
|
gr.ColorPicker(label="Waveform color", value="#0021e4"), |
|
gr.ColorPicker(label="Background color", value="#00FFFF00") |
|
], |
|
outputs=gr.Image(), |
|
description="Scroll through audio waveform with a moving window." |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |