Putar audio dengan Python

107

Bagaimana cara memutar audio (seperti suara 1 detik) dari skrip Python?

Akan lebih baik jika itu adalah platform independen, tetapi pertama-tama itu perlu bekerja di Mac.

Saya tahu saya bisa menjalankan afplay file.mp3perintah dari dalam Python, tetapi apakah mungkin melakukannya dengan Python mentah? Saya juga akan lebih baik jika tidak bergantung pada perpustakaan eksternal.

Josh Hunt
sumber
Pyglet memiliki kemampuan untuk memutar audio melalui perpustakaan eksternal yang disebut AVbin . Pyglet adalah pembungkus ctypes di sekitar panggilan sistem asli pada setiap platform yang didukungnya. Sayangnya, saya tidak berpikir apa pun di pustaka standar akan memutar audio kembali.
technomalogical
Jika Anda membutuhkan pustaka audio Python portabel, coba PyAudio . Ini pasti memiliki port mac. Sedangkan untuk file mp3: ini pasti bisa dilakukan dengan Python "mentah", hanya saja saya khawatir Anda harus mengkodekan semuanya sendiri :). Jika Anda mampu membeli beberapa perpustakaan eksternal, saya telah menemukan beberapa sampel PyAudio - PyLame di sini.
Grzegorz Gacek

Jawaban:

17

Anda dapat menemukan informasi tentang audio Python di sini: http://wiki.python.org/moin/Audio/

Sepertinya itu tidak dapat memutar file .mp3 tanpa perpustakaan eksternal. Anda dapat mengonversi file .mp3 Anda ke .wav atau format lain, atau menggunakan perpustakaan seperti PyMedia .

Jeremy Ruten
sumber
12
Tapi bagaimana cara memutar .wavfile?
theonlygusti
@theonlygusti Lihat di sini , misalnya.
Anderson Green
42

Taruhan terbaik Anda mungkin menggunakan pygame / SDL . Ini adalah perpustakaan eksternal, tetapi memiliki dukungan hebat di seluruh platform.

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

Anda dapat menemukan dokumentasi yang lebih spesifik tentang dukungan mixer audio di dokumentasi pygame.mixer.music

TML
sumber
2
Bagi saya, ini tidak berhasil. Maksudku, itu diputar tapi tidak ada suara. Saya menambahkan time.sleep(5)di akhir dan itu berhasil. Python 3.6 pada Windows 8.1
Nagabhushan SN
Paket api! Terima kasih!
Сергей Зеленчук
Itu tidak bekerja pada fedora dengan standar ".wav", ".mp3" dan ".ogg" (Tidak dapat membuka file 'filename.format')
Calvin-Ruiz
1
@ Calvin-Ruiz Saya baru saja mengonfirmasi bahwa saya dapat menggunakan kode di atas di FC31 untuk memutar file MP3 dan Ogg. Saya pikir Anda memiliki masalah yang lebih besar yang mungkin membutuhkan pengetahuan mendetail tentang platform Anda.
TML
18

Lihatlah Simpleaudio , yang merupakan pustaka yang relatif baru dan ringan untuk tujuan ini:

> pip install simpleaudio

Kemudian:

import simpleaudio as sa

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

Pastikan untuk menggunakan file PCM 16 bit yang tidak terkompresi.

Erwin Mayer
sumber
Bagus, terima kasih - berguna untuk game yang perlu memainkan efek suara pendek, dan mendukung Python 3.
Thomas Perl
18

Coba playsound yang merupakan modul Pure Python, lintas platform, fungsi tunggal tanpa ketergantungan untuk memutar suara.

Instal melalui pip:

$ pip install playsound

Setelah Anda menginstal, Anda dapat menggunakannya seperti ini:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
yehan jaya
sumber
36
Membaca ini membuatku sangat emosional. Mataku benar-benar berkaca-kaca karena kebahagiaan. Tidak mengharapkan reaksi seperti itu dari diriku. (Mereka terhubung ke modul yang saya buat.)
ArtOfWarfare
1 untuk playsound. Saya baru saja menguji beberapa solusi di sini, dan yang ini bekerja paling mudah bagi saya. Sayangnya pygamesolusinya tidak berhasil untuk saya, selama pengujian singkat.
Trevor Sullivan
13

Di pydub, kami baru-baru ini memilih untuk menggunakan ffplay (melalui subproses) dari rangkaian alat ffmpeg, yang secara internal menggunakan SDL.

Ini berfungsi untuk tujuan kami - terutama hanya mempermudah untuk menguji hasil kode pydub dalam mode interaktif - tetapi memiliki kelemahan, seperti menyebabkan program baru muncul di dok di mac.

Saya telah menautkan penerapan di atas, tetapi versi yang disederhanakan mengikuti:

import subprocess

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

The -nodispbendera berhenti ffplay dari menampilkan jendela baru, dan -autoexitbendera menyebabkan ffplay untuk keluar dan kembali kode status ketika file audio dilakukan bermain.

edit : pydub sekarang menggunakan pyaudio untuk pemutaran ketika diinstal dan kembali ke ffplay untuk menghindari kerugian yang saya sebutkan. Tautan di atas menunjukkan implementasi itu juga.

Jiaaro
sumber
1
Pydub sepertinya memiliki cukup banyak potensi sebagai pustaka pembungkus - Saya sedang menginstalnya sekarang.
Bayangan
1
Sialan PyDub terlihat bagus dan masih sangat aktif.
corysimmons
13

Maaf atas balasan yang terlambat, tapi saya pikir ini adalah tempat yang bagus untuk mengiklankan perpustakaan saya ...

AFAIK, perpustakaan standar hanya memiliki satu modul untuk memutar audio: ossaudiodev . Sayangnya, ini hanya berfungsi di Linux dan FreeBSD.

UPDATE: Ada juga winsound , tetapi jelas ini juga khusus untuk platform.

Untuk sesuatu yang lebih mandiri dari platform, Anda harus menggunakan perpustakaan eksternal.

Rekomendasi saya adalah sounddevice modul (tapi hati-hati, aku penulis).

Paket ini menyertakan pustaka PortAudio yang telah dikompilasi sebelumnya untuk Mac OS X dan Windows, dan dapat dengan mudah diinstal dengan:

pip install sounddevice --user

Ia dapat memutar ulang suara dari array NumPy, tetapi juga dapat menggunakan buffer Python biasa (jika NumPy tidak tersedia).

Untuk memutar ulang array NumPy, hanya itu yang Anda butuhkan (dengan asumsi bahwa data audio memiliki frekuensi sampling 44100 Hz):

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

Untuk lebih jelasnya, lihat dokumentasi .

Itu tidak dapat membaca / menulis file suara, Anda memerlukan perpustakaan terpisah untuk itu.

Matthias
sumber
Bagus! Hanya apa yang saya butuhkan untuk membuat program demo kelas tentang ombak.
Bill N
5

Anda dapat melihat ini: http://www.speech.kth.se/snack/

s = Sound() 
s.read('sound.wav') 
s.play()
user1926182
sumber
3
Tampak sangat bersih, saya berharap ada paket pip untuk ini. Kemudahan penginstalan adalah kuncinya
Jonathan
4

Jawaban Aaron tampaknya 10x lebih rumit dari yang seharusnya. Lakukan saja ini jika Anda hanya membutuhkan jawaban yang berfungsi di OS X:

from AppKit import NSSound

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

Satu hal ... ini segera kembali. Jadi, Anda mungkin ingin melakukan ini juga, jika Anda ingin panggilan diblokir hingga suara selesai diputar.

from time import sleep

sleep(sound.duration())

Sunting: Saya mengambil fungsi ini dan menggabungkannya dengan varian untuk Windows dan Linux. Hasilnya adalah python murni, modul lintas platform tanpa ketergantungan yang disebut playsound . Saya telah mengunggahnya ke pypi.

pip install playsound

Kemudian jalankan seperti ini:

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

File MP3 juga berfungsi di OS X. WAV harus berfungsi di semua platform. Saya tidak tahu kombinasi lain dari format platform / file apa yang berfungsi atau tidak - saya belum mencobanya.

ArtOfWarfare
sumber
Saya mendapatkan kesalahan berikut: "Tidak dapat mengubah objek 'byte' menjadi str secara implisit" pada Python 3.5 (Windows).
Erwin Mayer
@ErwinMayer - Apakah Anda berbicara tentang playsoundmodul yang saya tulis? Saya belum mengujinya pada sesuatu yang lebih baru dari Python 2.7.11 ... Saya pasti bisa memperbaiki ini di 3.5 ...
ArtOfWarfare
Memang. Itu pasti karena perbedaan Python 3.
Erwin Mayer
AppKit adalah ketergantungan.
Chris Larson
2
@ArtOfWarfare Itu tidak benar. Itu diinstal dengan sistem python, tetapi tidak dengan sebagian besar distribusi, termasuk distribusi resmi dari python.org. Kebanyakan orang yang saya kenal yang menggunakan python menginstal salah satu distribusi untuk melewati batasan SIP. Untuk mendapatkan AppKit untuk sebagian besar distribusi, pengguna perlu memasang pip pyobjc. Yang membuatnya pasti ketergantungan.
Chris Larson
3

Ini adalah iv'e termudah & terbaik yang ditemukan. Ini mendukung Linux / pulseaudio, Mac / coreaudio, dan 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)

Lihat https://github.com/bastibe/PySoundFile dan https://github.com/bastibe/SoundCard untuk banyak fitur berguna lainnya.

n00p
sumber
Hanya pemberitahuan untuk siapa pun yang melakukan ini (seperti saya). Semua lib dan dependensinya membutuhkan waktu lama untuk dibangun di atas Raspberry Pi 1B + - terutama numpy.
pojda
PS: ini tidak bekerja untuk raspberry pi "NotImplementedError: SoundCard belum mendukung linux2", dan tidak dapat menemukan cara untuk memperbaikinya. Saya pergi dengan os.system ("mpg123 file.mp3")
pojda
Ah, itu menyebalkan. Saya kira raspberry pi adalah lingkungan yang agak istimewa. Mungkin jika Anda memposting masalah pada penerbit penerbit, Anda bisa menyelesaikannya atau memperbaikinya.
n00p
Jika dipikir lebih jauh, mungkin masalahnya adalah Anda menggunakan kernel lama atau versi python lama. Dengan versi python yang lebih baru, kesalahan itu seharusnya tidak terlihat seperti itu.
n00p
Ini menjalankan Raspbian, yang pada dasarnya adalah garpu Debian Stretch. Saya menyerah dan pergi ke sistem os.sistem yang bekerja dengan baik atm. Terima kasih telah membantu saya!
pojda
2

Dimungkinkan untuk memutar audio di OS X tanpa pustaka pihak ketiga menggunakan analog dari kode berikut. Data audio mentah dapat dimasukkan dengan wave_wave.writeframes. Kode ini mengekstrak 4 detik audio dari file input.

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
sumber
Ini jauh lebih rumit dari yang seharusnya - mereka bertanya bagaimana cara memainkan suara, bukan bagaimana memanipulasinya dan kemudian memainkannya. Jawaban saya memangkas 90% yang tidak perlu dari jawaban ini dan meninggalkan apa yang diinginkan penanya - memutar suara dari file di OS X menggunakan Python. stackoverflow.com/a/34984200/901641
ArtOfWarfare
2

Coba PySoundCard yang menggunakan PortAudio untuk pemutaran yang tersedia di banyak platform. Selain itu, ia mengenali perangkat suara "profesional" dengan banyak saluran.

Berikut contoh kecil dari 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
sumber
Meskipun menarik, jawaban hanya tautan tidak disarankan. Setidaknya, Anda harus memasukkan dalam jawaban Anda contoh singkat tentang penggunaannya. Itu juga melindungi jawaban Anda dari kehilangan semua nilainya, jika repositori diganti namanya dan tautannya menggantung.
spektrum
2

Juga di OSX - dari SO , menggunakan perintah afplay OSX :

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

UPDATE: Semua ini dilakukan adalah menentukan bagaimana melakukan apa yang OP ingin hindari lakukan di tempat pertama. Saya kira saya memposting ini di sini karena yang OP ingin hindari adalah info yang saya cari. Ups.

MikeiLL
sumber
Bekerja dengan baik meskipun menjeda eksekusi saat bermain. Mungkin ada cara asinkron untuk menyebut ini?
Praxiteles
Pertanyaan bagus @Praxiteles. Mungkin dengan threading. lihat di sini Harap laporkan kembali jika Anda memiliki kesempatan untuk bereksperimen dengannya.
MikeiLL
OP secara eksplisit meminta alternatif untuk ini.
whitey04
OP sedang / sedang mencari alternatif untuk "menjalankan perintah afplay file.mp3 dari dalam Python", dan subprosesing masih terjadi dalam Python, bukan. Saya berdiri dikoreksi. Tetapi mungkin tidak ada salahnya memiliki posting kecil ini di sini karena dapat membantu orang lain.
MikeiLL
@ whitey04 Saya (akhirnya) mengerti apa yang Anda katakan.
MikeiLL
1

Pypi memiliki daftar modul untuk python dalam musik. Favorit saya adalah jython karena memiliki lebih banyak sumber daya dan perpustakaan untuk musik. Sebagai contoh kode untuk memainkan satu nada dari buku teks :

# 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
sumber
1

Mac OS Saya mencoba banyak kode tetapi hanya ini yang berhasil pada saya

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
Kapten Django
sumber
1

Instal playsoundpaket menggunakan:

pip install playsound

Pemakaian:

from playsound import playsound
playsound("file location\audio.p3")
Harish
sumber
0
Letakkan ini di bagian atas skrip python yang Anda tulis:
import subprocess
Jika file wav IS di direktori skrip python:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Jika file wav TIDAK ada di direktori skrip python:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Jika Anda ingin mempelajari lebih lanjut tentang aplay:
man aplay
Crawome
sumber
0

Untuk memutar suara notifikasi menggunakan python, panggil pemutar musik, seperti vlc. VLC meminta saya untuk menggunakan versi baris perintahnya, cvlc, sebagai gantinya.

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

Ini membutuhkan vlc untuk diinstal sebelumnya pada perangkat. Diuji di Linux (Ubuntu 16.04 LTS); Menjalankan Python 3.5.

amarVashishth
sumber
0

Coba perangkat suara

Jika Anda tidak memiliki modul, masuk pip install sounddeviceke terminal Anda.

Kemudian di skrip Python pilihan Anda (saya menggunakan Juypter), masukkan

import sounddevice as sd

sd.play(audio, sr) akan memainkan apa yang Anda inginkan melalui Python

Cara terbaik untuk mendapatkan audio dan sampel yang Anda inginkan adalah dengan modul librosa. Masukkan ini di terminal jika Anda tidak memiliki modul librosa.

pip install librosa

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

Apa pun file wav yang ingin Anda mainkan, pastikan saja itu ada di direktori yang sama dengan skrip Python Anda. Ini memungkinkan Anda untuk memutar file wav yang Anda inginkan melalui Python

Cheers, Charlie

PS

Setelah audio menjadi objek data "librosa", Python melihatnya sebagai array numpy. Sebagai percobaan, coba mainkan hal yang panjang (coba 20.000 titik data) dari larik numpy acak. Python harus memainkannya sebagai white noise. Modul perangkat suara juga memainkan larik dan daftar numpy.

Charlie Carrera
sumber
melakukan ini, tetapi tidak memainkan apa pun. Ini hanya melewatkan panggilan sd.play
Tobias Kolb
0

Di notebook Colab, Anda dapat melakukan:

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

Jika Anda menggunakan OSX, Anda dapat menggunakan modul "os" atau "subprocess" dll. Untuk memanggil perintah "play" OSX. Dari shell OSX, sepertinya

mainkan "bah.wav"

Ini mulai diputar sekitar setengah detik di mesin saya.

Moondoggy
sumber
1
Saya tertarik untuk melihat sintaks untuk kedua metode ini.
MikeiLL
-1

Cukup Anda dapat melakukannya dengan bantuan cvlc- Saya melakukannya dengan cara ini:

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

/home/maulo/selfProject/task.mp3. Ini adalah lokasi file mp3 saya. dengan bantuan "--play-and-exit" Anda akan dapat memutar kembali suara tersebut tanpa mengakhiri proses vlc.

pyAddict
sumber