Reproducir audio con Python

107

¿Cómo puedo reproducir audio (sería como un sonido de 1 segundo) desde un script de Python?

Sería mejor si fuera independiente de la plataforma, pero primero debe funcionar en una Mac.

Sé que podría ejecutar el afplay file.mp3comando desde Python, pero ¿es posible hacerlo en Python sin formato? También sería mejor si no dependiera de bibliotecas externas.

Josh Hunt
fuente
Pyglet tiene la capacidad de reproducir audio a través de una biblioteca externa llamada AVbin . Pyglet es un contenedor ctypes de llamadas al sistema nativo en cada plataforma que admite. Desafortunadamente, no creo que nada en la biblioteca estándar reproduzca audio.
technomalogical
Si necesita una biblioteca de audio portátil de Python, pruebe PyAudio . Ciertamente tiene un puerto mac. En cuanto a los archivos mp3: ciertamente es factible en Python "sin procesar", solo que me temo que tendrías que codificar todo tú mismo :). Si puede pagar una biblioteca externa, he encontrado una muestra de PyAudio - PyLame aquí.
Grzegorz Gacek

Respuestas:

17

Puede encontrar información sobre el audio de Python aquí: http://wiki.python.org/moin/Audio/

No parece que pueda reproducir archivos .mp3 sin bibliotecas externas. Puede convertir su archivo .mp3 a .wav u otro formato, o usar una biblioteca como PyMedia .

Jeremy Ruten
fuente
12
Pero, ¿cómo reproduzco un .wavarchivo?
theonlygusti
@theonlygusti Vea aquí , por ejemplo.
Anderson Green
42

Probablemente, su mejor opción sea utilizar pygame / SDL . Es una biblioteca externa, pero tiene un gran soporte en todas las plataformas.

pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()

Puede encontrar documentación más específica sobre el soporte del mezclador de audio en la documentación de pygame.mixer.music

TML
fuente
2
Para mí, esto no funcionó. Quiero decir, estaba sonando pero sin sonido. Agregué time.sleep(5)al final y funcionó. Python 3.6 en Windows 8.1
Nagabhushan SN
¡Paquete de fuego! ¡Gracias!
Сергей Зеленчук
No funciona en fedora con estándar ".wav", ".mp3" y ".ogg" (No se puede abrir el archivo 'nombre de archivo.formato')
Calvin-Ruiz
1
@ Calvin-Ruiz Acabo de confirmar que puedo usar el código anterior en FC31 para reproducir archivos MP3 y Ogg. Creo que tiene un problema mayor que probablemente necesite un conocimiento detallado de su plataforma.
TML
18

Eche un vistazo a Simpleaudio , que es una biblioteca relativamente reciente y liviana para este propósito:

> pip install simpleaudio

Luego:

import simpleaudio as sa

wave_obj = sa.WaveObject.from_wave_file("path/to/file.wav")
play_obj = wave_obj.play()
play_obj.wait_done()

Asegúrese de utilizar archivos PCM de 16 bits sin comprimir.

Erwin Mayer
fuente
Bien, gracias - útil para juegos que necesitan reproducir efectos de sonido cortos y es compatible con Python 3.
Thomas Perl
18

Pruebe PlaySound, que es un módulo de función única multiplataforma de Pure Python sin dependencias para reproducir sonidos.

Instalar a través de pip:

$ pip install playsound

Una vez que lo haya instalado, puede usarlo así:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
yehan jaya
fuente
36
Leer esto me emocionó mucho. Mis ojos literalmente se llenaron de lágrimas de felicidad. No esperaba ese tipo de reacción de mi parte. (Se vincularon a un módulo que hice)
ArtOfWarfare
+1 para playsound. Acabo de probar un par de soluciones aquí, y esta funcionó más fácilmente para mí. Desafortunadamente, la pygamesolución no funcionó para mí, durante una breve prueba.
Trevor Sullivan
13

En pydub , hemos optado recientemente por usar ffplay (a través de subproceso) del conjunto de herramientas ffmpeg, que internamente usa SDL.

Funciona para nuestros propósitos, principalmente para facilitar la prueba de los resultados del código pydub en modo interactivo, pero tiene sus desventajas, como hacer que aparezca un nuevo programa en el dock en Mac.

He vinculado la implementación anterior, pero sigue una versión simplificada:

import subprocess

def play(audio_file_path):
    subprocess.call(["ffplay", "-nodisp", "-autoexit", audio_file_path])

La -nodispbandera evita que ffplay muestre una nueva ventana, y la -autoexitbandera hace que ffplay salga y devuelva un código de estado cuando el archivo de audio finaliza la reproducción.

edit : pydub ahora usa pyaudio para la reproducción cuando está instalado y recurre a ffplay para evitar las desventajas que mencioné. El enlace anterior también muestra esa implementación.

Jiaaro
fuente
1
Pydub parece que tiene bastante potencial como biblioteca contenedora; lo estoy instalando ahora.
Shadow
1
Maldito PyDub se ve bien y todavía está muy activo.
corysimmons
13

Perdón por la respuesta tardía, pero creo que este es un buen lugar para anunciar mi biblioteca ...

AFAIK, la biblioteca estándar tiene solo un módulo para reproducir audio: ossaudiodev . Lamentablemente, esto solo funciona en Linux y FreeBSD.

ACTUALIZACIÓN: También existe winsound , pero obviamente esto también es específico de la plataforma.

Para algo más independiente de la plataforma, deberá utilizar una biblioteca externa.

Mi recomendación es el módulo del dispositivo de sonido (pero cuidado, yo soy el autor).

El paquete incluye la biblioteca PortAudio precompilada para Mac OS X y Windows, y se puede instalar fácilmente con:

pip install sounddevice --user

Puede reproducir sonido de matrices NumPy, pero también puede usar búferes Python simples (si NumPy no está disponible).

Para reproducir una matriz NumPy, eso es todo lo que necesita (asumiendo que los datos de audio tienen una frecuencia de muestreo de 44100 Hz):

import sounddevice as sd
sd.play(myarray, 44100)

Para obtener más detalles, consulte la documentación .

No puede leer / escribir archivos de sonido, necesitará una biblioteca separada para eso.

Matías
fuente
¡Excelente! Justo lo que necesitaba para hacer un programa de demostración de clase sobre olas.
Bill N
5

Puede ver esto: http://www.speech.kth.se/snack/

s = Sound() 
s.read('sound.wav') 
s.play()
user1926182
fuente
3
Parece tan limpio, desearía que hubiera un paquete de pepitas para esto. La facilidad de instalación es clave
Jonathan
4

La respuesta de Aaron parece ser 10 veces más complicada de lo necesario. Solo haz esto si solo necesitas una respuesta que funcione en OS X:

from AppKit import NSSound

sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_('/path/to/file.wav', True)
sound.play()

Una cosa ... esto vuelve de inmediato. Por lo tanto, es posible que desee hacer esto también, si desea que la llamada se bloquee hasta que el sonido termine de reproducirse.

from time import sleep

sleep(sound.duration())

Editar: tomé esta función y la combiné con variantes para Windows y Linux. El resultado es un módulo multiplataforma de Python puro sin dependencias llamado PlaySound . Lo he subido a pypi.

pip install playsound

Entonces ejecútelo así:

from playsound import playsound
playsound('/path/to/file.wav', block = False)

Los archivos MP3 también funcionan en OS X. WAV debería funcionar en todas las plataformas. No sé qué otras combinaciones de plataforma / formato de archivo funcionan o no; todavía no las he probado.

ArtOfWarfare
fuente
Aparece el siguiente error: "No se puede convertir el objeto 'bytes' en str implícitamente" en Python 3.5 (Windows).
Erwin Mayer
@ErwinMayer - ¿Estás hablando del playsoundmódulo que escribí? No lo he probado en nada más nuevo que Python 2.7.11 ... Ciertamente puedo buscar arreglar esto en 3.5 ...
ArtOfWarfare
En efecto. Debe deberse a las diferencias de Python 3.
Erwin Mayer
AppKit es una dependencia.
Chris Larson
2
@ArtOfWarfare Eso simplemente no es cierto. Se instala con el sistema python, pero no con la mayoría de las distribuciones, incluidas las distribuciones oficiales de python.org. La mayoría de las personas que conozco que usan Python instalan una de las distribuciones para superar las restricciones de SIP. Para obtener AppKit para la mayoría de las distribuciones, un usuario necesita instalar pip pyobjc. Lo que lo convierte definitivamente en una dependencia.
Chris Larson
3

Este es el mejor y más fácil que he encontrado. Es compatible con Linux / pulseaudio, Mac / coreaudio y Windows / WASAPI.

import soundfile as sf
import soundcard as sc

default_speaker = sc.default_speaker()
samples, samplerate = sf.read('bell.wav')

default_speaker.play(samples, samplerate=samplerate)

Consulte https://github.com/bastibe/PySoundFile y https://github.com/bastibe/SoundCard para conocer toneladas de otras funciones súper útiles.

n00p
fuente
Solo un aviso para cualquiera que quiera esto (como yo). Todas las bibliotecas y sus dependencias tardan una eternidad en construirse en una Raspberry Pi 1B +, ​​especialmente numpy.
pojda
PD: esto no funcionó para raspberry pi "NotImplementedError: SoundCard aún no es compatible con linux2", y no pudo encontrar una manera de solucionarlo. Voy con os.system ("mpg123 file.mp3")
pojda
Ah, eso apesta. Supongo que Raspberry Pi es un entorno algo especial. Quizás si publicaste un problema en el rastreador de problemas, podrías solucionarlo o solucionarlo.
n00p
Pensándolo bien, quizás el problema es que está utilizando un kernel antiguo o una versión antigua de Python. Con las versiones más nuevas de Python, ese error no debería verse así, creo.
n00p
Está ejecutando Raspbian, que es básicamente una bifurcación Debian Stretch. Me di por vencido y fui por el sistema os.system, que funciona bien en la atmósfera. ¡Gracias por ayudarme!
Pojda
2

Es posible reproducir audio en OS X sin bibliotecas de terceros utilizando un análogo del siguiente código. Los datos de audio sin procesar se pueden ingresar con wave_wave.writeframes. Este código extrae 4 segundos de audio del archivo de entrada.

import wave
import io
from AppKit import NSSound


wave_output = io.BytesIO()
wave_shell = wave.open(wave_output, mode="wb")
file_path = 'SINE.WAV'
input_audio = wave.open(file_path)
input_audio_frames = input_audio.readframes(input_audio.getnframes())

wave_shell.setnchannels(input_audio.getnchannels())
wave_shell.setsampwidth(input_audio.getsampwidth())
wave_shell.setframerate(input_audio.getframerate())

seconds_multiplier = input_audio.getnchannels() * input_audio.getsampwidth() * input_audio.getframerate()

wave_shell.writeframes(input_audio_frames[second_multiplier:second_multiplier*5])

wave_shell.close()

wave_output.seek(0)
wave_data = wave_output.read()
audio_stream = NSSound.alloc()
audio_stream.initWithData_(wave_data)
audio_stream.play()
Aaron
fuente
Esto es mucho más complicado de lo necesario: preguntaron cómo simplemente reproducir un sonido, no cómo manipularlo y luego reproducirlo. Mi respuesta recorta el 90% innecesario de esta respuesta y deja exactamente lo que quería el autor de la pregunta: reproducir un sonido de un archivo en OS X usando Python. stackoverflow.com/a/34984200/901641
ArtOfWarfare
2

Pruebe PySoundCard, que utiliza PortAudio para la reproducción, que está disponible en muchas plataformas. Además, reconoce dispositivos de sonido "profesionales" con muchos canales.

Aquí un pequeño ejemplo del Léame:

from pysoundcard import Stream

"""Loop back five seconds of audio data."""

fs = 44100
blocksize = 16
s = Stream(samplerate=fs, blocksize=blocksize)
s.start()
for n in range(int(fs*5/blocksize)):
    s.write(s.read(blocksize))
s.stop()
Stefan Balke
fuente
Aunque son interesantes, se desaconsejan las respuestas de solo enlace. Como mínimo, debe incluir en su respuesta un breve ejemplo de cómo usarlo. Eso también protege su respuesta de perder todo su valor, en caso de que se cambie el nombre del repositorio y el enlace cuelgue.
espectros
2

También en OSX, desde SO , usando el comando afplay de OSX :

import subprocess
subprocess.call(["afplay", "path/to/audio/file"])

ACTUALIZACIÓN: Todo lo que esto hace es especificar cómo hacer lo que el OP quería evitar hacer en primer lugar. Supongo que publiqué esto aquí porque lo que OP quería evitar era la información que estaba buscando. ¡Ups!

MikeiLL
fuente
Funciona muy bien, aunque pausa la ejecución mientras se reproduce. ¿Quizás hay una forma asincrónica de llamar a esto?
Praxiteles
Buenas preguntas @Praxiteles. Posiblemente con enhebrado. ver aquí. Informe si tiene la oportunidad de experimentar con él.
MikeiLL
El PO pidió explícitamente alternativas a esto.
whitey04
El OP está / estaba buscando una alternativa para "ejecutar el comando afplay file.mp3 desde dentro de Python", y el subprocesamiento todavía ocurre dentro de Python, ¿no es así? Me quedo corregido. Pero probablemente no esté de más tener esta pequeña publicación aquí, ya que puede ayudar a otros.
MikeiLL
@ whitey04 (finalmente) veo lo que estás diciendo.
MikeiLL
1

Pypi tiene una lista de módulos para Python en música. Mi favorito sería jython porque tiene más recursos y bibliotecas para música. Como ejemplo de código para tocar una sola nota del libro de texto :

# playNote.py 
# Demonstrates how to play a single note.

from music import *   # import music library
note = Note(C4, HN)   # create a middle C half note 
Play.midi(note)       # and play it!
Kardi Teknomo
fuente
1

Mac OS Probé muchos códigos, pero esto me funciona

import pygame
import time
pygame.mixer.init()
pygame.init()
pygame.mixer.music.load('fire alarm sound.mp3') *On my project folder*
i = 0
while i<10:
    pygame.mixer.music.play(loops=10, start=0.0)
    time.sleep(10)*to protect from closing*
    pygame.mixer.music.set_volume(10)
    i = i + 1
Capitán Django
fuente
1

Instale el playsoundpaquete usando:

pip install playsound

Uso:

from playsound import playsound
playsound("file location\audio.p3")
Harish
fuente
0
Ponga esto en la parte superior de su script de Python que está escribiendo:
import subprocess
Si el archivo wav ESTÁ en el directorio del script de Python:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Si el archivo wav NO ESTÁ en el directorio del script de Python:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Si desea obtener más información sobre aplay:
man aplay
Repugnante
fuente
0

Para reproducir un sonido de notificación con Python, llame a un reproductor de música, como vlc. VLC me pidió que usara su versión de línea de comandos, cvlc, en su lugar.

from subprocess import call
call(["cvlc", "--play-and-exit", "myNotificationTone.mp3"])

Requiere que vlc esté preinstalado en el dispositivo. Probado en Linux (Ubuntu 16.04 LTS); Ejecutando Python 3.5.

amarVashishth
fuente
0

Prueba el dispositivo de sonido

Si no tiene el módulo ingrese pip install sounddeviceen su terminal.

Luego, en su secuencia de comandos de Python preferida (yo uso Juypter), ingrese

import sounddevice as sd

sd.play(audio, sr) jugará lo que quieras a través de Python

La mejor manera de obtener el audio y la frecuencia de muestreo que desea es con el módulo librosa. Ingrese esto en la terminal si no tiene el módulo librosa.

pip install librosa

audio, sr = librosa.load('wave_file.wav')

Cualquiera que sea el archivo wav que desee reproducir, solo asegúrese de que esté en el mismo directorio que su secuencia de comandos de Python. Esto debería permitirle reproducir su archivo wav deseado a través de Python

Saludos, Charlie

PD

Una vez que el audio es un objeto de datos "librosa", Python lo ve como una matriz numerosa. Como experimento, intente jugar una cosa larga (pruebe con 20,000 puntos de datos) de una matriz numérica aleatoria. Python debería jugarlo como ruido blanco. El módulo del dispositivo de sonido también reproduce matrices y listas numerosas.

Charlie Carrera
fuente
hizo esto, pero no está reproduciendo nada. Solo se está saltando la llamada de sd.play
Tobias Kolb
0

En un cuaderno Colab puede hacer:

from IPython.display import Audio
Audio(waveform, Rate=16000)
Axel Bregnsbo
fuente
-1

Si está en OSX, puede usar el módulo "os" o el "subproceso", etc. para llamar al comando "play" de OSX. Desde el shell de OSX, parece

reproducir "bah.wav"

Empieza a reproducirse en aproximadamente medio segundo en mi máquina.

Moondoggy
fuente
1
Me interesaría ver la sintaxis de ambos métodos.
MikeiLL
-1

Simplemente puedes hacerlo con la ayuda de cvlc- lo hice de esta manera:

import os
os.popen2("cvlc /home/maulo/selfProject/task.mp3 --play-and-exit")

/home/maulo/selfProject/task.mp3. Esta es la ubicación de mi archivo mp3. con la ayuda de "--play-and-exit" podrá volver a reproducir el sonido sin finalizar el proceso de vlc.

pyAddict
fuente