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.


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:



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


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.


Ś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')

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ę.


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.


Wspaniały! Właśnie tego potrzebowałem, aby stworzyć program demonstracyjny o falach.
Bill N


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.


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.


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

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

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.


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!

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

1

Zainstaluj playsoundpakiet przy użyciu:

pip install playsound

Stosowanie:

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

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

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.


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.


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)


-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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.