Tocar áudio com Python


107

Como posso reproduzir áudio (seria como um som de 1 segundo) de um script Python?

Seria melhor se fosse independente de plataforma, mas primeiro precisa funcionar em um Mac.

Eu sei que poderia simplesmente executar o afplay file.mp3comando de dentro do Python, mas é possível fazer isso no Python bruto? Eu também seria melhor se não dependesse de bibliotecas externas.


Pyglet tem a capacidade de reproduzir áudio por meio de uma biblioteca externa chamada AVbin . Pyglet é um invólucro ctypes em torno de chamadas de sistema nativas em cada plataforma que suporta. Infelizmente, não acho que nada na biblioteca padrão reproduza áudio.
— tecnomalógico

Se você precisa de uma biblioteca de áudio Python portátil, experimente o PyAudio . Certamente tem uma porta mac. Quanto aos arquivos mp3: certamente é possível em Python "bruto", mas infelizmente você terá que codificar tudo sozinho :). Se você puder pagar por alguma biblioteca externa, encontrei alguns exemplos de PyAudio - PyLame aqui.
— Grzegorz Gacek

Respostas:



42

Provavelmente, sua melhor aposta é usar pygame / SDL . É uma biblioteca externa, mas tem ótimo suporte em várias plataformas.

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

Você pode encontrar documentação mais específica sobre o suporte ao mixer de áudio na documentação do pygame.mixer.music


2
Para mim, isso não estava funcionando. Quer dizer, estava tocando, mas sem som. Eu adicionei time.sleep(5)no final e funcionou. Python 3.6 no Windows 8.1
— Nagabhushan SN de

Pacote de fogo! Obrigado!
— Сергей Зеленчук

Não funciona no Fedora com os padrões ".wav", ".mp3" e ".ogg" (Não é possível abrir o arquivo 'filename.format')
— Calvin-Ruiz

1
@ Calvin-Ruiz Acabei de confirmar que posso usar o código acima no FC31 para reproduzir arquivos MP3 e Ogg. Acho que você tem um problema maior que provavelmente precisa de algum conhecimento detalhado de sua plataforma.
— TML

18

Dê uma olhada em Simpleaudio , que é uma biblioteca relativamente recente e leve para esta finalidade:

> pip install simpleaudio

Então:

import simpleaudio as sa

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

Certifique-se de usar arquivos PCM de 16 bits não compactados.


Legal, obrigado - útil para jogos que precisam reproduzir efeitos sonoros curtos e suporta Python 3.
— Thomas Perl

18

Tente brincar que é um Pure Python, plataforma cruzada, módulo de função única sem dependências para reproduzir sons.

Instale via pip:

$ pip install playsound

Depois de instalar, você pode usá-lo assim:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')

36
Ler isso me deixou tão emocionado. Meus olhos literalmente se encheram de lágrimas de felicidade. Não esperava esse tipo de reação de mim mesmo. (Eles vincularam a um módulo que eu fiz.)
— ArtOfWarfare

1 para playsound. Acabei de testar algumas soluções aqui, e esta funcionou mais fácil para mim. Infelizmente a pygamesolução não funcionou para mim, durante um breve teste.
— Trevor Sullivan

13

No pydub , recentemente optamos por usar ffplay (via subprocesso) do conjunto de ferramentas ffmpeg, que usa SDL internamente.

Funciona para nossos propósitos - principalmente apenas para facilitar o teste dos resultados do código pydub no modo interativo - mas tem suas desvantagens, como fazer com que um novo programa apareça no dock do mac.

Vinculei a implementação acima, mas segue uma versão simplificada:

import subprocess

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

O -nodispsinalizador impede que o ffplay mostre uma nova janela e -autoexitfaz com que o ffplay saia e retorne um código de status quando o arquivo de áudio terminar de tocar.

edit : pydub agora usa pyaudio para reprodução quando está instalado e volta para ffplay para evitar as desvantagens que mencionei. O link acima mostra essa implementação também.


1
Parece que o Pydub tem um grande potencial como uma biblioteca de wrapper - estou instalando agora.
— Shadow

1
O maldito PyDub parece bom e ainda está muito ativo.
— corysimmons

13

Desculpe pelo atraso na resposta, mas acho que este é um bom lugar para divulgar minha biblioteca ...

AFAIK, a biblioteca padrão tem apenas um módulo para reproduzir áudio: ossaudiodev . Infelizmente, isso só funciona no Linux e no FreeBSD.

ATUALIZAÇÃO: também há winound , mas obviamente também é específico da plataforma.

Para algo mais independente de plataforma, você precisará usar uma biblioteca externa.

Minha recomendação é o dispositivo de som módulo de dispositivo de (mas cuidado, eu sou o autor).

O pacote inclui a biblioteca PortAudio pré-compilada para Mac OS X e Windows e pode ser facilmente instalado com:

pip install sounddevice --user

Ele pode reproduzir sons de matrizes NumPy, mas também pode usar buffers Python simples (se NumPy não estiver disponível).

Para reproduzir uma matriz NumPy, isso é tudo que você precisa (assumindo que os dados de áudio tenham uma frequência de amostragem de 44100 Hz):

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

Para mais detalhes, dê uma olhada na documentação .

Ele não pode ler / gravar arquivos de som, você precisará de uma biblioteca separada para isso.


Ótimo! Exatamente o que eu precisava para fazer um programa de demonstração da aula sobre ondas.
— Bill N,


4

A resposta de Aaron parece ser cerca de 10 vezes mais complicada do que o necessário. Faça isso se precisar apenas de uma resposta que funcione no OS X:

from AppKit import NSSound

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

Uma coisa ... isso retorna imediatamente. Portanto, você também pode fazer isso, se quiser que a chamada seja bloqueada até que o som termine de tocar.

from time import sleep

sleep(sound.duration())

Edit: Peguei esta função e combinei com variantes para Windows e Linux. O resultado é um Python puro, módulo de plataforma cruzada sem dependências, chamado playsound . Eu enviei para pypi.

pip install playsound

Em seguida, execute-o assim:

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

Os arquivos MP3 também funcionam no OS X. O WAV deve funcionar em todas as plataformas. Não sei que outras combinações de plataforma / formato de arquivo funcionam ou não - ainda não as experimentei.


Recebo o seguinte erro: "Não é possível converter o objeto 'bytes' em str implicitamente" no Python 3.5 (Windows).
— Erwin Mayer

@ErwinMayer - Você está falando sobre o playsoundmódulo que escrevi? Eu não testei em nada mais recente que o Python 2.7.11 ... Eu certamente posso
— tentar

De fato. Deve ser devido às diferenças do Python 3.
— Erwin Mayer

O AppKit é uma dependência.
— Chris Larson

2
@ArtOfWarfare Isso simplesmente não é verdade. Ele é instalado com o sistema python, mas não com a maioria das distribuições, incluindo as distribuições oficiais de python.org. A maioria das pessoas que conheço que usam python instalam uma das distribuições para superar as restrições SIP. Para obter o AppKit para a maioria das distribuições, um usuário precisa instalar o pyobjc. O que o torna definitivamente uma dependência.
— Chris Larson

3

Este é o iv'e mais fácil e melhor encontrado. Ele suporta Linux / pulseaudio, Mac / coreaudio e 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)

Veja https://github.com/bastibe/PySoundFile e https://github.com/bastibe/SoundCard para toneladas de outros recursos superúteis.


Apenas um aviso para quem está indo para isso (como eu). Todas as bibliotecas e suas dependências levam uma eternidade para serem compiladas em um Raspberry Pi 1B + - especialmente numpy.
— pojda

PS: isso não funcionou para o raspberry pi "NotImplementedError: SoundCard ainda não oferece suporte a linux2" e não conseguiu descobrir uma maneira de consertar. Vou com os.system ("mpg123 file.mp3")
— pojda

Ah, isso é péssimo. Eu acho que o framboesa pi é um ambiente um tanto especial. Talvez se você postar um problema no issuetracker, possa resolvê-lo ou consertá-lo.
— n00p

Pensando melhor, talvez o problema seja que você está usando um kernel antigo ou uma versão antiga do python. Com as versões mais recentes do python, esse erro não deve ser assim, eu acho.
— n00p de

Ele está executando o Raspbian, que é basicamente um fork do Debian Stretch. Desisti e segui o caminho os.system, que está funcionando perfeitamente no atm. Obrigado por me ajudar!
— pojda de

2

É possível reproduzir áudio no OS X sem nenhuma biblioteca de terceiros usando um análogo do código a seguir. Os dados de áudio brutos podem ser inseridos com wave_wave.writeframes. Este código extrai 4 segundos de áudio do arquivo 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()

Isso é muito mais complicado do que o necessário - eles perguntaram como simplesmente tocar um som, não como manipulá-lo e depois tocá-lo. Minha resposta elimina os 90% desnecessários dessa resposta e deixa exatamente o que o autor da pergunta queria - reproduzir um som de um arquivo no OS X usando Python. stackoverflow.com/a/34984200/901641
— ArtOfWarfare

2

Experimente o PySoundCard que usa PortAudio para reprodução, disponível em muitas plataformas. Além disso, reconhece dispositivos de som "profissionais" com muitos canais.

Aqui está um pequeno exemplo do Leiame:

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()

Embora interessantes, respostas apenas com links são desencorajadas. No mínimo, você deve incluir em sua resposta um breve exemplo de como usá-lo. Isso também protege sua resposta de perder todo o seu valor, caso o repositório seja renomeado e o link fique pendente.
— spectras

2

Também no OSX - a partir do SO , usando o comando afplay do OSX :

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

ATUALIZAÇÃO: tudo isso especifica como fazer o que o OP queria evitar fazer em primeiro lugar. Acho que postei isso aqui porque o que OP queria evitar era a informação que eu estava procurando. Opa.


Funciona muito bem, mas faz uma pausa na execução durante a reprodução. Talvez haja uma maneira assíncrona de chamar isso?
— Praxiteles

Boas perguntas @Praxiteles. Possivelmente com rosca. veja aqui. Relate se você tiver a chance de experimentar.
— MikeiLL

O OP pediu explicitamente alternativas para isso.
— whitey04 de

O OP está / estava procurando uma alternativa para "executar o comando afplay file.mp3 de dentro do Python", e o subprocessamento ainda acontece dentro do Python, não é? Eu estou corrigido. Mas provavelmente não faz mal ter este pequeno post aqui, pois pode ajudar outras pessoas.
— MikeiLL

@ whitey04 Eu (finalmente) entendi o que você está dizendo.
— MikeiLL de

1

Pypi tem uma lista de módulos para python na música. Meu favorito seria jython porque ele tem mais recursos e bibliotecas para música. Como exemplo de código para tocar uma única nota do livro :

# 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!

1

Mac OS Eu tentei vários códigos, mas isso funciona comigo

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

1

Instale o playsoundpacote usando:

pip install playsound

Uso:

from playsound import playsound
playsound("file location\audio.p3")

0
Coloque isso no topo do seu script Python que você está escrevendo:
import subprocess
Se o arquivo wav estiver no diretório do script Python:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Se o arquivo wav NÃO ESTÁ no diretório do script Python:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Se você quiser saber mais sobre aplay:
man aplay

0

Para reproduzir um som de notificação usando python, chame um reprodutor de música, como vlc. O VLC me pediu para usar sua versão de linha de comando, cvlc, em vez disso.

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

Requer que o vlc esteja pré-instalado no dispositivo. Testado em Linux (Ubuntu 16.04 LTS); Executando Python 3.5.


0

Experimente o dispositivo de som

Se você não tem o módulo entre pip install sounddeviceno seu terminal.

Então, em seu script Python preferido (eu uso Juypter), digite

import sounddevice as sd

sd.play(audio, sr) vai tocar o que você quiser através do Python

A melhor maneira de obter o áudio e a taxa de amostragem que você deseja é com o módulo librosa. Digite isso no terminal se você não tiver o módulo librosa.

pip install librosa

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

Seja qual for o arquivo wav que você deseja reproduzir, certifique-se de que esteja no mesmo diretório que o seu script Python. Isso deve permitir que você reproduza o arquivo wav desejado por meio do Python

Saúde, Charlie

PS

Uma vez que o áudio é um objeto de dados "librosa", o Python o vê como um array numpy. Como experiência, tente reproduzir uma coisa longa (tente 20.000 pontos de dados) de uma matriz numpy aleatória. Python deve interpretá-lo como ruído branco. O módulo de dispositivo de som também reproduz matrizes numpy e listas.


fez isso, mas não está jogando nada. É só pular a chamada sd.play
— Tobias Kolb

0

Em um notebook Colab, você pode fazer:

from IPython.display import Audio
Audio(waveform, Rate=16000)


-1

Se você estiver no OSX, pode usar o módulo "os" ou "subprocesso" etc. para chamar o comando "play" do OSX. No shell do OSX, parece

toque "bah.wav"

Ele começa a tocar em cerca de meio segundo na minha máquina.


1
Eu estaria interessado em ver a sintaxe de ambos os métodos.
— MikeiLL

-1

Simplesmente, você pode fazer isso com a ajuda de cvlc- Fiz desta forma:

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

/home/maulo/selfProject/task.mp3. Este é o local do meu arquivo mp3. com a ajuda de "--play-and-exit" você poderá reproduzir o som novamente sem encerrar o processo de vlc.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.