Odtwarzaj dźwięk w Pythonie

107

Jak mogę odtworzyć dźwięk (byłby to 1-sekundowy dźwięk) ze skryptu Python?

Najlepiej byłoby, gdyby był niezależny od platformy, ale najpierw musi działać na komputerze Mac.

Wiem, że mógłbym po prostu wykonać afplay file.mp3polecenie z poziomu Pythona, ale czy można to zrobić w surowym Pythonie? Byłbym też lepszy, gdyby nie polegał na zewnętrznych bibliotekach.

Josh Hunt
źródło
Pyglet ma możliwość odtwarzania dźwięku przez zewnętrzną bibliotekę o nazwie AVbin . Pyglet jest opakowaniem ctypes otaczającym natywne wywołania systemowe na każdej obsługiwanej platformie. Niestety nie sądzę, aby cokolwiek ze standardowej biblioteki odtworzyło dźwięk.
technomalogiczne
Jeśli potrzebujesz przenośnej biblioteki audio Python, wypróbuj PyAudio . Z pewnością ma port Mac. Jeśli chodzi o pliki mp3: w "surowym" Pythonie jest to z pewnością wykonalne, tylko że obawiam się, że musiałbyś sam zakodować wszystko :). Jeśli stać cię na jakąś zewnętrzną bibliotekę, znalazłem tutaj przykład PyAudio - PyLame .
Grzegorz Gacek

Odpowiedzi:

17

Informacje o dźwięku w języku Python można znaleźć tutaj: http://wiki.python.org/moin/Audio/

Nie wygląda na to, że może odtwarzać pliki .mp3 bez zewnętrznych bibliotek. Możesz albo przekonwertować plik .mp3 do formatu .wav lub innego, albo użyć biblioteki takiej jak PyMedia .

Jeremy Ruten
źródło
12
Ale jak mogę odtworzyć .wavplik?
theonlygusti
@theonlygusti Zobacz tutaj , na przykład.
Anderson Green
42

Najlepszym rozwiązaniem jest prawdopodobnie użycie pygame / SDL . Jest to biblioteka zewnętrzna, ale ma świetne wsparcie na różnych platformach.

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

Bardziej szczegółową dokumentację dotyczącą obsługi miksera audio można znaleźć w dokumentacji pygame.mixer.music

TML
źródło
2
Dla mnie to nie działało. To znaczy grało, ale nie było dźwięku. Dodałem time.sleep(5)na końcu i zadziałało. Python 3.6 w systemie Windows 8.1
Nagabhushan SN
Pakiet ognia! Dzięki!
Сергей Зеленчук
Nie działa na fedorze ze standardowymi plikami „.wav”, „.mp3” i „.ogg” (nie można otworzyć pliku „nazwa_pliku.format”)
Calvin-Ruiz
1
@ Calvin-Ruiz Właśnie potwierdziłem, że jestem w stanie użyć powyższego kodu w FC31 do odtwarzania plików MP3 i Ogg. Myślę, że masz większy problem, który prawdopodobnie wymaga szczegółowej wiedzy o Twojej platformie.
TML
18

Spójrz na Simpleaudio , która jest stosunkowo nową i lekką biblioteką do tego celu:

> pip install simpleaudio

Następnie:

import simpleaudio as sa

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

Upewnij się, że używasz nieskompresowanych 16-bitowych plików PCM.

Erwin Mayer
źródło
Świetnie, dziękuję - przydatne w grach, które wymagają krótkich efektów dźwiękowych i obsługują język Python 3.
Thomas Perl,
18

Spróbuj playound, który jest wieloplatformowym, wieloplatformowym modułem z pojedynczym modułem funkcyjnym w Pure Python, bez zależności od odtwarzania dźwięków.

Zainstaluj przez pip:

$ pip install playsound

Po zainstalowaniu możesz go używać w następujący sposób:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
yehan jaya
źródło
36
Czytanie tego bardzo mnie wzruszyło. Moje oczy dosłownie łzawiły ze szczęścia. Nie spodziewałem się od siebie takiej reakcji. (
Połączyli
+1 dla playsound. Właśnie przetestowałem tutaj kilka rozwiązań i ten zadziałał dla mnie najłatwiej. Niestety pygamerozwiązanie u mnie nie zadziałało podczas krótkiego testu.
Trevor Sullivan
13

W pydub ostatnio zdecydowaliśmy się na użycie ffplay (przez podproces) z zestawu narzędzi ffmpeg, który wewnętrznie używa SDL.

Działa do naszych celów - głównie po prostu ułatwia testowanie wyników kodu pydub w trybie interaktywnym - ale ma swoje wady, takie jak spowodowanie pojawienia się nowego programu w stacji dokującej na Macu.

Powyżej połączyłem implementację, ale następuje uproszczona wersja:

import subprocess

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

-nodispFlag zatrzymuje ffplay od pokazując nowe okno, a -autoexitflaga powoduje ffplay do wyjścia i zwracają kod stanu, gdy plik audio odbywa się gra.

edit : pydub używa teraz pyaudio do odtwarzania po zainstalowaniu i wraca do ffplay, aby uniknąć wad, o których wspomniałem. Powyższy link pokazuje również tę implementację.

Jiaaro
źródło
1
Wygląda na to, że Pydub ma spory potencjał jako biblioteka opakowująca - instaluję go teraz.
Shadow
1
Cholerny PyDub wygląda ładnie i nadal jest naprawdę aktywny.
corysimmons
13

Przepraszamy za spóźnioną odpowiedź, ale myślę, że to dobre miejsce na reklamowanie mojej biblioteki ...

AFAIK, standardowa biblioteka ma tylko jeden moduł do odtwarzania dźwięku: ossaudiodev . Niestety działa to tylko w Linuksie i FreeBSD.

AKTUALIZACJA: Jest też wygrana , ale oczywiście jest to również specyficzne dla platformy.

Aby uzyskać coś bardziej niezależnego od platformy, musisz użyć biblioteki zewnętrznej.

Moją rekomendacją jest moduł sounddevice (ale uwaga, ja jestem jego autorem).

Pakiet zawiera wstępnie skompilowaną bibliotekę PortAudio dla systemów Mac OS X i Windows i można go łatwo zainstalować za pomocą:

pip install sounddevice --user

Może odtwarzać dźwięk z tablic NumPy, ale może również używać zwykłych buforów Pythona (jeśli NumPy nie jest dostępny).

Aby odtworzyć tablicę NumPy, to wszystko, czego potrzebujesz (zakładając, że dane audio mają częstotliwość próbkowania 44100 Hz):

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

Aby uzyskać więcej informacji, zapoznaj się z dokumentacją .

Nie może czytać / zapisywać plików dźwiękowych, będziesz potrzebować do tego osobnej biblioteki.

Matthias
źródło
Wspaniały! Właśnie tego potrzebowałem, aby stworzyć program demonstracyjny o falach.
Bill N
5

Możesz to zobaczyć: http://www.speech.kth.se/snack/

s = Sound() 
s.read('sound.wav') 
s.play()
user1926182
źródło
3
Wygląda tak czysto, żałuję, że nie było do tego pakietu pip. Łatwość instalacji jest kluczowa
Jonathan
4

Odpowiedź Aarona wydaje się być około 10 razy bardziej skomplikowana niż to konieczne. Po prostu zrób to, jeśli potrzebujesz tylko odpowiedzi działającej w systemie OS X:

from AppKit import NSSound

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

Jedna rzecz ... to wraca natychmiast. Więc możesz to również zrobić, jeśli chcesz, aby połączenie było blokowane do momentu zakończenia odtwarzania dźwięku.

from time import sleep

sleep(sound.duration())

Edycja: wziąłem tę funkcję i połączyłem ją z wariantami dla Windows i Linux. Rezultatem jest czysty, Pythonowy , wieloplatformowy moduł bez zależności o nazwie playsound . Przesłałem to do pypi.

pip install playsound

Następnie uruchom to w ten sposób:

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

Pliki MP3 działają również na OS X. WAV powinien działać na wszystkich platformach. Nie wiem, jakie inne kombinacje platformy / formatu pliku działają lub nie działają - jeszcze ich nie wypróbowałem.

ArtOfWarfare
źródło
Pojawia się następujący błąd: „Nie można niejawnie przekonwertować obiektu„ bajtów ”na str.” W Pythonie 3.5 (Windows).
Erwin Mayer
@ErwinMayer - Czy mówisz o playsoundmodule, który napisałem? Nie testowałem tego na niczym nowszym niż Python 2.7.11 ... Z pewnością mogę to naprawić w 3.5 ...
ArtOfWarfare
W rzeczy samej. Musi to wynikać z różnic w Pythonie 3.
Erwin Mayer
AppKit to zależność.
Chris Larson,
2
@ArtOfWarfare To po prostu nie prawda. Jest instalowany z systemem python, ale nie z większością dystrybucji, w tym z oficjalnymi dystrybucjami z python.org. Większość ludzi, których znam, którzy używają Pythona, instaluje jedną z dystrybucji, aby ominąć ograniczenia SIP. Aby uzyskać AppKit dla większości dystrybucji, użytkownik musi zainstalować pyobjc. Co sprawia, że ​​jest to zdecydowanie uzależnienie.
Chris Larson
3

To jest najłatwiejszy i najlepszy znaleziony iv'e. Obsługuje Linux / pulseaudio, Mac / coreaudio i 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)

Zobacz https://github.com/bastibe/PySoundFile i https://github.com/bastibe/SoundCard, aby uzyskać mnóstwo innych bardzo przydatnych funkcji.

n00p
źródło
Tylko heads-up dla każdego, kto to robi (tak jak ja). Wszystkie biblioteki i ich zależności trwają wiecznie, aby zbudować na Raspberry Pi 1B + - szczególnie numpy.
pojda
PS: to nie zadziałało dla raspberry pi "NotImplementedError: SoundCard nie obsługuje jeszcze linux2" i nie mogłem znaleźć sposobu, aby to naprawić. Idę z os.system ("mpg123 file.mp3")
pojda
Ach, to jest do bani. Wydaje mi się, że raspberry pi to nieco szczególne środowisko. Być może, gdybyś opublikował problem w witrynie Issuetracker, mógłbyś go rozwiązać lub naprawić.
n00p
Po zastanowieniu się, być może problem polega na tym, że używasz starego jądra lub starej wersji Pythona. W nowszych wersjach Pythona ten błąd nie powinien wyglądać tak, jak myślę.
n00p
Działa na Raspbian, który jest w zasadzie widelcem Debiana Stretch. Poddałem się i poszedłem na sposób os.system, który działa dobrze. Dzięki za pomoc!
pojda
2

Możliwe jest odtwarzanie dźwięku w systemie OS X bez żadnych bibliotek innych firm przy użyciu analogu następującego kodu. Surowe dane audio można wprowadzać za pomocą wave_wave.writeframes. Ten kod wyodrębnia 4 sekundy dźwięku z pliku wejściowego.

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
źródło
Jest to o wiele bardziej skomplikowane niż to konieczne - pytali, jak po prostu zagrać dźwięk, a nie jak nim manipulować, a potem grać. Moja odpowiedź ucina niepotrzebne 90% z tej odpowiedzi i pozostawia dokładnie to, czego chciał pytający - odtwarzanie dźwięku z pliku w OS X przy użyciu Pythona. stackoverflow.com/a/34984200/901641
ArtOfWarfare
2

Wypróbuj PySoundCard, która używa PortAudio do odtwarzania, która jest dostępna na wielu platformach. Ponadto rozpoznaje „profesjonalne” urządzenia dźwiękowe z dużą ilością kanałów.

Oto mały przykład z pliku Readme:

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
źródło
Chociaż interesujące, odpowiedzi zawierające tylko łącza są odradzane. Jako minimum powinieneś zamieścić w swojej odpowiedzi krótki przykład jej wykorzystania. Chroni to również twoją odpowiedź przed utratą całej wartości, jeśli nazwa repozytorium zostanie zmieniona, a link zawiesi się.
widma
2

Również na OSX - z SO , używając polecenia afplay OSX :

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

AKTUALIZACJA: Wszystko , co to robi, to przede wszystkim określenie, jak zrobić to, czego OP chciał uniknąć. Wydaje mi się, że opublikowałem to tutaj, ponieważ OP chciał uniknąć informacji, których szukałem. Ups.

MikeiLL
źródło
Działa świetnie, ale wstrzymuje wykonanie podczas odtwarzania. Być może istnieje asynchroniczny sposób, aby to nazwać?
Praxiteles
Dobre pytania @Praxiteles. Ewentualnie z gwintowaniem. zobacz tutaj Zgłoś się ponownie, jeśli masz szansę z tym eksperymentować.
MikeiLL
PO wyraźnie poprosił o alternatywę dla tego.
whitey 04
OP szuka / szukał alternatywy dla „wykonania polecenia afplay file.mp3 z poziomu Pythona”, a przetwarzanie podrzędne nadal odbywa się w Pythonie, prawda? Poprawiono mnie. Ale prawdopodobnie nie zaszkodzi mieć ten mały post, ponieważ może to pomóc innym.
MikeiLL
@ whitey04 (w końcu) rozumiem, co mówisz.
MikeiLL
1

Pypi zawiera listę modułów dla języka Python w muzyce. Moim ulubionym byłby jython, ponieważ ma więcej zasobów i bibliotek muzycznych. Jako przykład kodu do odtworzenia pojedynczej notatki z podręcznika :

# 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
źródło
1

Mac OS Próbowałem wielu kodów, ale to działa na mnie

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
Kapitanie Django
źródło
1

Zainstaluj playsoundpakiet przy użyciu:

pip install playsound

Stosowanie:

from playsound import playsound
playsound("file location\audio.p3")
Harish
źródło
0
Umieść to na górze swojego skryptu Pythona, który piszesz:
import subprocess
Jeśli plik wav znajduje się w katalogu skryptu Pythona:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Jeśli plik wav NIE JEST w katalogu skryptu Pythona:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Jeśli chcesz dowiedzieć się więcej o aplay:
man aplay
Crawsome
źródło
0

Aby odtworzyć dźwięk powiadomienia za pomocą Pythona, wywołaj odtwarzacz muzyki, taki jak vlc. VLC poprosił mnie, abym zamiast tego użył jego wersji wiersza poleceń, cvlc.

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

Wymaga preinstalacji vlc na urządzeniu. Przetestowano w systemie Linux (Ubuntu 16.04 LTS); Uruchamianie Pythona 3.5.

amarVashishth
źródło
0

Wypróbuj sounddevice

Jeśli nie masz modułu, wejdź pip install sounddevicedo swojego terminala.

Następnie w preferowanym skrypcie Pythona (ja używam Juyptera) wpisz

import sounddevice as sd

sd.play(audio, sr) będzie odtwarzać to, co chcesz za pośrednictwem Pythona

Najlepszym sposobem na uzyskanie żądanego dźwięku i częstotliwości próbkowania jest użycie modułu librosa. Wpisz to w terminalu, jeśli nie masz modułu librosa.

pip install librosa

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

Niezależnie od pliku wav, który chcesz odtworzyć, po prostu upewnij się, że znajduje się w tym samym katalogu, co skrypt Pythona. Powinno to umożliwić odtworzenie żądanego pliku wav przez Python

Pozdrawiam, Charlie

PS

Gdy dźwięk jest obiektem danych „librosa”, Python widzi go jako tablicę numpy. W ramach eksperymentu spróbuj odtworzyć długą (spróbuj 20 000 punktów danych) losową tablicę numpy. Python powinien odtwarzać to jako biały szum. Moduł sounddevice odtwarza również tablice numpy i listy.

Charlie Carrera
źródło
zrobił to, ale nic nie gra. To tylko pomijanie połączenia sd.play
Tobias Kolb
0

W notatniku Colab możesz:

from IPython.display import Audio
Audio(waveform, Rate=16000)
Axel Bregnsbo
źródło
-1

Jeśli używasz OSX, możesz użyć modułu „os” lub „podprocesu” itp., Aby wywołać polecenie OSX „play”. Wygląda na to, że z powłoki OSX

odtwórz „bah.wav”

Zaczyna grać za mniej więcej pół sekundy na moim komputerze.

Moondoggy
źródło
1
Chciałbym zobaczyć składnię obu tych metod.
MikeiLL
-1

Po prostu możesz to zrobić z pomocą cvlc - zrobiłem to w ten sposób:

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

/home/maulo/selfProject/task.mp3. To jest lokalizacja mojego pliku mp3. przy pomocy "--play-and-exit" będziesz mógł ponownie odtworzyć dźwięk bez kończenia procesu vlc.

pyAddict
źródło