2012-02-08 16 views
6

Quiero representar un archivo de audio en una imagen con un tamaño máximo de 180 × 180 píxeles.Generar miniatura para archivo de audio arbitrario

Quiero generar esta imagen para que de alguna manera proporcione una representación del archivo de audio, piénselo como la forma de onda de SoundCloud (gráfico de amplitud)?.

Screenshot of Soundcloud's player

Me pregunto si alguno de ustedes tiene algo para esto. He estado buscando un poco, principalmente "visualización de audio" y "thumbnailing de audio", pero no he encontrado nada útil.

Primero posted this to ux.stackexchange.com, este es mi intento de llegar a los programadores que trabajan en esto.

+0

¿Desea hacer una herramienta para hacer esto o quiere una solución preexistente? – Koof

+0

Eso no es un espectrograma, es un gráfico de amplitud. Los espectrogramas de audio son tres-d: generalmente el tiempo en el eje x, la frecuencia en y, y la amplitud representada por el color. –

+0

Gracias Josh Caswell, como ve, no estaba seguro del nombre de esta representación de una forma de onda. – joar

Respuesta

2

Echa un vistazo a esta entrada de blog sobre wav2png.py.

3

También podría dividir el audio en trozos y medir el RMS (una medida de la intensidad). digamos que quieres una imagen de 180 píxeles de ancho.

Voy a usar pydub, un contenedor de peso ligero que escribí alrededor de la lib std wave modeule:

from pydub import AudioSegment 

# first I'll open the audio file 
sound = AudioSegment.from_mp3("some_song.mp3") 

# break the sound 180 even chunks (or however 
# many pixels wide the image should be) 
chunk_length = len(sound)/180 

loudness_of_chunks = [] 
for i in range(180): 
    start = i * chunk_length 
    end = chunk_start + chunk_length 

    chunk = sound[start:end] 
    loudness_of_chunks.append(chunk.rms) 

el bucle se puede representar como la siguiente lista de comprensión, sólo quería que quede claro :

loudness_of_chunks = [ 
    sound[ i*chunk_length : (i+1)*chunk_length ].rms 
    for i in range(180)] 

Ahora lo único que queda por hacer es escalar el RMS a una escala de 0 - 180 (ya que desea que la imagen sea 180px de altura)

max_rms = max(loudness_of_chunks) 

scaled_loudness = [ (loudness/max_rms) * 180 for loudness in loudness_of_chunks] 

Voy a dejar el dibujo de los píxeles reales para usted, no estoy muy experimentado con PIL o Imagemagick:/

+0

Convierte 'max_rms' en un flotador primero. Ayuda. – Remco

1

Sobre la base de la respuesta de Jiaaro (gracias por escribir pydub!), Y construido para web2py aquí está mis dos centavos:

def generate_waveform(): 
    img_width = 1170 
    img_height = 140 
    line_color = 180 
    filename = os.path.join(request.folder,'static','sounds','adg3.mp3') 


    # first I'll open the audio file 
    sound = pydub.AudioSegment.from_mp3(filename) 

    # break the sound 180 even chunks (or however 
    # many pixels wide the image should be) 
    chunk_length = len(sound)/img_width 

    loudness_of_chunks = [ 
     sound[ i*chunk_length : (i+1)*chunk_length ].rms 
     for i in range(img_width) 
    ] 
    max_rms = float(max(loudness_of_chunks)) 
    scaled_loudness = [ round(loudness * img_height/ max_rms) for loudness in loudness_of_chunks] 

    # now convert the scaled_loudness to an image 
    im = Image.new('L',(img_width, img_height),color=255) 
    draw = ImageDraw.Draw(im) 
    for x,rms in enumerate(scaled_loudness): 
     y0 = img_height - rms 
     y1 = img_height 
     draw.line((x,y0,x,y1), fill=line_color, width=1) 
    buffer = cStringIO.StringIO() 
    del draw 
    im = im.filter(ImageFilter.SMOOTH).filter(ImageFilter.DETAIL) 
    im.save(buffer,'PNG') 
    buffer.seek(0) 
    return response.stream(buffer, filename=filename+'.png') 
Cuestiones relacionadas