Python ile ses çalın


108

Bir Python betiğinden nasıl ses çalabilirim (1 saniyelik bir ses gibi olur)?

Platformdan bağımsız olması en iyisi olurdu, ancak öncelikle bir Mac üzerinde çalışması gerekiyor.

afplay file.mp3Komutu Python içinden çalıştırabileceğimi biliyorum , ancak bunu ham Python'da yapmak mümkün mü? Ayrıca dış kitaplıklara dayanmasaydı daha iyi olurdum.


Pyglet , sesi AVbin adı verilen harici bir kitaplık aracılığıyla yürütme yeteneğine sahiptir . Pyglet, desteklediği her platformda yerel sistem çağrılarını çevreleyen bir ctype sarmalayıcıdır. Ne yazık ki, standart kitaplıktaki hiçbir şeyin sesi çalacağını düşünmüyorum.
technomalogical

Taşınabilir Python ses kitaplığına ihtiyacınız varsa PyAudio'yu deneyin . Kesinlikle bir mac bağlantı noktası var. MP3 dosyalarına gelince: "ham" Python'da kesinlikle yapılabilir, sadece korkarım her şeyi kendiniz kodlamanız gerekir :). Harici bir kitaplık almaya gücünüz yetiyorsa, burada bazı PyAudio - PyLame örneği buldum .
Grzegorz Gacek

Yanıtlar:



42

En iyi bahsiniz muhtemelen pygame / SDL kullanmaktır . Bu harici bir kitaplık, ancak platformlar arasında harika bir desteğe sahip.

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

Pygame.mixer.music belgelerinde ses karıştırıcı desteği hakkında daha spesifik belgeler bulabilirsiniz.


2
Benim için bu işe yaramadı. Demek istediğim, çalıyordu ama ses yok. time.sleep(5)Sonunda ekledim ve işe yaradı. Windows 8.1'de Python 3.6
Nagabhushan SN

Yangın paketi! Teşekkürler!
Armağan Зеленчук

Standart ".wav", ".mp3" ve ".ogg" ile fedora üzerinde çalışmıyor ('filename.format' dosyası açılamıyor)
Calvin-Ruiz

1
@ Calvin-Ruiz Yukarıdaki kodu FC31'de MP3 ve Ogg dosyalarını çalmak için kullanabileceğimi doğruladım. Bence, muhtemelen platformunuz hakkında ayrıntılı bilgiye ihtiyaç duyan daha büyük bir sorununuz var.
TML

18

Bu amaç için nispeten yeni ve hafif bir kitaplık olan Simpleaudio'ya bir göz atın :

> pip install simpleaudio

Sonra:

import simpleaudio as sa

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

Sıkıştırılmamış 16 bit PCM dosyaları kullandığınızdan emin olun.


Güzel, teşekkürler - kısa ses efektleri çalması gereken oyunlar için kullanışlıdır ve Python 3'ü destekler.
Thomas Perl

18

Pure Python, çapraz platform, ses çalmak için bağımlılığı olmayan tek işlevli bir modül olan playsound'u deneyin .

Pip ile kurun:

$ pip install playsound

Kurduktan sonra şu şekilde kullanabilirsiniz:

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

36
Bunu okumak beni çok duygusal yaptı. Gözlerim tam anlamıyla mutluluktan yırtıldı. Benden bu tür bir tepki beklemiyordum. (Yaptığım bir modüle bağlandılar.)
ArtOfWarfare

+1 playsound. Burada birkaç çözümü test ettim ve bu benim için en kolay olanı oldu. pygameKısa bir test sırasında maalesef çözüm bende işe yaramadı.
Trevor Sullivan

13

Gelen pydub yakın zamanda ettik (alt süreç üzerinden) ffplay kullanmayı tercih dahili SDL kullanır araçları ffmpeg paketi, gelen.

Amaçlarımız için çalışıyor - esas olarak sadece etkileşimli modda pydub kodunun sonuçlarını test etmeyi kolaylaştırıyor - ancak Mac'teki dock'ta yeni bir programın görünmesine neden olmak gibi dezavantajları var.

Yukarıdaki uygulamayı bağladım, ancak basitleştirilmiş bir sürüm şu şekildedir:

import subprocess

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

-nodispBayrak yeni bir pencere göstermesini ffplay durur ve -autoexitbayrak çıkmak için ffplay neden olur ve ses dosyası bitti oynama olduğunda bir durum kodu döndürür.

edit : pydub artık kurulduğunda oynatma için pyaudio kullanıyor ve bahsettiğim dezavantajları önlemek için ffplay'e geri dönüyor. Yukarıdaki bağlantı bu uygulamayı da göstermektedir.


1
Pydub, bir sarmalayıcı kitaplığı olarak epey bir potansiyele sahip gibi görünüyor - şimdi kuruyorum.
Shadow

1
Lanet PyDub güzel görünüyor ve hala gerçekten aktif.
corysimmons

13

Geç cevap verdiğim için üzgünüm, ama sanırım burası kütüphanemin reklamını yapmak için iyi bir yer ...

AFAIK, standart kitaplığın ses çalmak için tek bir modülü vardır: ossaudiodev . Ne yazık ki, bu yalnızca Linux ve FreeBSD'de çalışır.

GÜNCELLEME: Winsound da var , ancak tabii ki bu da platforma özgü.

Platformdan daha bağımsız bir şey için, harici bir kitaplık kullanmanız gerekir.

Benim tavsiyem, ses cihazı modülü (ama dikkat edin, ben yazarım).

Paket, Mac OS X ve Windows için önceden derlenmiş PortAudio kitaplığını içerir ve aşağıdakilerle kolayca kurulabilir:

pip install sounddevice --user

NumPy dizilerinden ses çalabilir, ancak düz Python tamponlarını da kullanabilir (NumPy yoksa).

Bir NumPy dizisini oynatmak için ihtiyacınız olan tek şey bu (ses verilerinin 44100 Hz örnekleme frekansına sahip olduğunu varsayarak):

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

Daha fazla ayrıntı için belgelere bakın .

Ses dosyalarını okuyamaz / yazamaz, bunun için ayrı bir kitaplığa ihtiyacınız olacak.


Harika! Wave hakkında bir sınıf demo programı yapmak için tam da ihtiyacım olan şey.
Bill N


4

Aaron'un cevabı gerekenden 10 kat daha karmaşık görünüyor. Yalnızca OS X'de çalışan bir cevaba ihtiyacınız varsa bunu yapın:

from AppKit import NSSound

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

Bir şey ... bu hemen geri döner. Bu nedenle, aramanın ses çalmayı bitirene kadar engellenmesini istiyorsanız, bunu da yapmak isteyebilirsiniz.

from time import sleep

sleep(sound.duration())

Düzenleme: Bu işlevi aldım ve Windows ve Linux için varyantlarla birleştirdim. Sonuç, playsound olarak adlandırılan hiçbir bağımlılığı olmayan saf bir python, çapraz platform modülüdür . Bunu pypi'ye yükledim.

pip install playsound

O zaman şu şekilde çalıştırın:

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

MP3 dosyaları da OS X üzerinde çalışır. WAV tüm platformlarda çalışmalıdır. Diğer platform / dosya formatı kombinasyonlarının ne işe yarayıp yaramadığını bilmiyorum - henüz denemedim.


Şu hatayı alıyorum: Python 3.5'te (Windows) "'bytes' nesnesi str'ye örtük olarak dönüştürülemiyor".
Erwin Mayer

@ErwinMayer - Yazdığım modülden mi bahsediyorsunuz playsound? Python 2.7.11'den daha yeni bir şey üzerinde test etmedim ... Bunu 3.5'te düzeltmeye kesinlikle bakabilirim ...
ArtOfWarfare

Aslında. Python 3 farklarından kaynaklanıyor olmalı.
Erwin Mayer

AppKit olan bir bağımlılık.
Chris Larson

2
@ArtOfWarfare Bu kesinlikle doğru değil . Python sistemiyle birlikte kurulur, ancak python.org'daki resmi dağıtımlar dahil çoğu dağıtımda değil. Python kullananların çoğu, SIP kısıtlamalarını aşmak için dağıtımlardan birini kurar. Çoğu dağıtımda AppKit'i edinmek için, kullanıcının pyobjc kurulumunu pip yapması gerekir. Bu da onu kesinlikle bir bağımlılık yapar .
Chris Larson

3

Bu, bulunan en kolay ve en iyi iv. Linux / pulseaudio, Mac / coreaudio ve Windows / WASAPI'yi destekler.

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)

Tonlarca başka süper kullanışlı özellik için https://github.com/bastibe/PySoundFile ve https://github.com/bastibe/SoundCard sayfalarına bakın .


Sadece bunu isteyen herkes için bir uyarı (benim gibi). Tüm kitaplıklar ve bağımlılıkları bir Raspberry Pi 1B + üzerine inşa etmek sonsuza kadar sürer - özellikle uyuşuk.
pojda

Not: bu, ahududu pi için işe yaramadı "NotImplementedError: SoundCard henüz linux2'yi desteklemiyor" ve düzeltmenin bir yolunu bulamadı. Os.system ("mpg123 file.mp3") ile gidiyorum
pojda

Ah, bu berbat. Ahududu pi biraz özel bir ortam sanırım. Belki de yayıncıya bir sorun yayınladıysanız, onu çözebilir veya düzeltebilirsiniz.
n00p

Daha fazla düşündüğümüzde, belki de sorun eski bir çekirdek veya eski bir python sürümü kullanıyor olmanızdır. Daha yeni python sürümlerinde bu hatanın öyle görünmemesi gerektiğini düşünüyorum.
n00p

Temelde bir Debian Stretch çatalı olan Raspbian'ı çalıştırıyor. Ben pes ettim ve sadece iyi atm çalışan os.system yoluna gittim. Bana yardım ettiğin için teşekkürler!
pojda

2

Aşağıdaki kodun bir analogunu kullanarak herhangi bir üçüncü taraf kitaplığı olmadan OS X'te ses çalmak mümkündür. Ham ses verileri, wave_wave.writeframes ile girilebilir. Bu kod, giriş dosyasından 4 saniyelik ses çıkarır.

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

Bu, gerekenden çok daha karmaşık - bir sesin nasıl çalıştırılacağını ve sonra çalınacağını değil, nasıl basitçe çalınacağını sordular. Cevabım bu yanıttan gereksiz% 90'ı keser ve soruyu soranın tam olarak istediği şeyi bırakır - Python kullanarak OS X'teki bir dosyadan bir ses çalmak. stackoverflow.com/a/34984200/901641
ArtOfWarfare

2

Deneyin PySoundCard birçok platformlarda kullanılabilir oynatma için portaudio kullanır. Ayrıca çok sayıda kanalı olan "profesyonel" ses cihazlarını tanır.

İşte Benioku'dan küçük bir örnek:

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

İlginç olsa da, yalnızca bağlantı içeren yanıtlar önerilmez. En azından, cevabınıza onu kullanmanın kısa bir örneğini eklemelisiniz. Bu aynı zamanda, havuzun yeniden adlandırılması ve bağlantının sarkması durumunda cevabınızı tüm değerini kaybetmekten korur.
spectras

2

Ayrıca OSX'te - dan SO , OSX en kullanarak afplay komutunu:

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

GÜNCELLEME: Bütün bunlar , OP'nin ilk başta yapmaktan kaçınmak istediği şeyi nasıl yapacağını belirlemektir . Sanırım bunu buraya gönderdim çünkü OP'nin kaçınmak istediği şey aradığım bilgiydi. Hata.


Harika çalışıyor, ancak oynarken yürütmeyi duraklatıyor. Belki bunu adlandırmanın eşzamansız bir yolu vardır?
Praxiteles

İyi sorular @Praxiteles. Muhtemelen diş açma ile. buraya bakın Eğer bir şansınız varsa lütfen bize bildirin.
MikeiLL

OP açıkça buna alternatifler istedi.
whitey04

OP, "afplay file.mp3 komutunu Python içinden yürütmek" için bir alternatif arıyor / arıyordu ve alt işleme hala Python içinde gerçekleşiyor, değil mi? Düzeltilmiş durumdayım. Ancak başkalarına yardımcı olabileceğinden, bu küçük gönderiyi burada bulundurmak muhtemelen zarar vermez.
MikeiLL

@ whitey04 (Sonunda) ne dediğini anladım.
MikeiLL

1

Pypi , müzikte python için bir modül listesine sahiptir. Benim favorim jython olurdu çünkü müzik için daha fazla kaynağa ve kitaplığa sahip. Ders kitabından tek bir notayı çalmak için kod örneği olarak :

# 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 Çok sayıda kod denedim ama sadece bu bende çalışıyor

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

playsoundPaketi kullanarak kurun :

pip install playsound

Kullanım:

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

0
Bunu, yazdığınız python betiğinizin en üstüne koyun:
import subprocess
Wav dosyası python betiğinin dizinindeyse:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Wav dosyası python betiğinin dizininde DEĞİLSE:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Aplay hakkında daha fazla bilgi edinmek istiyorsanız:
man aplay

0

Python kullanarak bir bildirim sesi çalmak için, vlc gibi bir müzik çaları arayın. VLC benden komut satırı sürümünü cvlc'yi kullanmamı istedi.

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

Vlc'nin cihaza önceden yüklenmesini gerektirir. Linux (Ubuntu 16.04 LTS) üzerinde test edilmiştir; Python 3.5 çalıştırılıyor.


0

Ses cihazını deneyin

Modüle sahip pip install sounddevicedeğilseniz terminalinize girin .

Sonra tercih ettiğiniz Python betiğine (Juypter kullanıyorum) şunu girin:

import sounddevice as sd

sd.play(audio, sr) Python aracılığıyla istediğinizi oynayacak

İstediğiniz sesi elde etmenin ve örneklemenin en iyi yolu librosa modülüdür. Librosa modülünüz yoksa bunu terminale girin.

pip install librosa

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

Oynatmak istediğiniz wav dosyası ne olursa olsun, Python betiğinizle aynı dizinde olduğundan emin olun. Bu, istediğiniz wav dosyasını Python aracılığıyla oynatmanıza izin vermelidir

Şerefe, Charlie

PS

Ses bir "librosa" veri nesnesi olduğunda, Python onu uyuşmuş bir dizi olarak görür. Bir deney olarak, rastgele bir uyuşuk dizinin uzun (20.000 veri noktası deneyin) bir şey oynamayı deneyin. Python bunu beyaz gürültü olarak çalmalıdır. Sounddevice modülü, numpy dizileri ve listeleri de çalar.


bunu yaptı, ama hiçbir şey oynamıyor. Sadece sd.play çağrısını atlıyor
Tobias Kolb

0

Bir Colab not defterinde şunları yapabilirsiniz:

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


-1

OSX üzerindeyseniz, OSX "play" komutunu çağırmak için "os" modülünü veya "alt işlemi" vb. Kullanabilirsiniz. OSX kabuğundan şöyle görünüyor:

"bah.wav" çal

Makinemde yaklaşık yarım saniye içinde oynamaya başlıyor.


1
Bu iki yöntemin sözdizimini görmek isterim.
MikeiLL

-1

Basitçe Bunu cvlc'nin yardımıyla yapabilirsiniz- Ben şu şekilde yaptım:

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

/home/maulo/selfProject/task.mp3. Bu, mp3 dosyamın konumu. "--play-and-exit" yardımıyla vlc sürecini sonlandırmadan sesi yeniden çalabileceksiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.