Phát âm thanh bằng Python


107

Làm cách nào để phát âm thanh (giống như âm thanh 1 giây) từ tập lệnh Python?

Sẽ là tốt nhất nếu nó độc lập với nền tảng, nhưng trước hết nó cần hoạt động trên máy Mac.

Tôi biết tôi chỉ có thể thực thi afplay file.mp3lệnh từ bên trong Python, nhưng liệu có thể thực hiện nó bằng Python thô không? Tôi cũng sẽ tốt hơn nếu nó không dựa vào các thư viện bên ngoài.


Pyglet có khả năng phát lại âm thanh thông qua một thư viện bên ngoài có tên là AVbin . Pyglet là một ctypes wrapper xung quanh các lệnh gọi hệ thống gốc trên mỗi nền tảng mà nó hỗ trợ. Thật không may, tôi không nghĩ rằng bất kỳ thứ gì trong thư viện chuẩn sẽ phát lại âm thanh.
technomalogical

Nếu bạn cần thư viện âm thanh Python di động, hãy thử PyAudio . Nó chắc chắn có một cổng mac. Đối với các tệp mp3: nó chắc chắn có thể làm được bằng Python "thô", chỉ có điều tôi e rằng bạn phải tự viết mã mọi thứ :). Nếu bạn có thể mua một số thư viện bên ngoài, tôi đã tìm thấy một số mẫu PyAudio - PyLame ở đây.
Grzegorz Gacek

Câu trả lời:


17

Bạn có thể tìm thông tin về âm thanh Python tại đây: http://wiki.python.org/moin/Audio/

Có vẻ như nó không thể phát tệp .mp3 mà không có thư viện bên ngoài. Bạn có thể chuyển đổi tệp .mp3 của mình sang .wav hoặc định dạng khác hoặc sử dụng thư viện như PyMedia .


12
Nhưng làm cách nào để phát một .wavtập tin?
theonlygusti 27/12/16

@theonlygusti Xem ví dụ ở đây .
Anderson Green

42

Đặt cược tốt nhất của bạn có lẽ là sử dụng pygame / SDL . Đó là một thư viện bên ngoài, nhưng nó có hỗ trợ tuyệt vời trên các nền tảng.

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

Bạn có thể tìm thêm tài liệu cụ thể về hỗ trợ bộ trộn âm thanh trong tài liệu pygame.mixer.music


2
Đối với tôi, điều này đã không hoạt động. Ý tôi là, nó đang phát nhưng không có âm thanh. Tôi đã thêm time.sleep(5)vào cuối và điều đó đã hoạt động. Python 3.6 trên Windows 8.1
Nagabhushan SN

Gói cháy! Cảm ơn!
Сергей Зеленчук

Nó không hoạt động trên fedora với tiêu chuẩn ".wav", ".mp3" và ".ogg" (Không thể mở tệp 'filename.format')
Calvin-Ruiz

1
@ Calvin-Ruiz Tôi vừa xác nhận rằng tôi có thể sử dụng mã trên trong FC31 để phát các tệp MP3 và Ogg. Tôi nghĩ rằng bạn có một vấn đề lớn hơn có thể cần một số kiến ​​thức chi tiết về nền tảng của bạn.
TML

18

Hãy xem Simpleaudio , đây là một thư viện tương đối gần đây và nhẹ cho mục đích này:

> pip install simpleaudio

Sau đó:

import simpleaudio as sa

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

Đảm bảo sử dụng tệp PCM 16 bit không nén.


Rất vui, cảm ơn - hữu ích cho các trò chơi cần phát hiệu ứng âm thanh ngắn và hỗ trợ Python 3.
Thomas Perl

18

Hãy thử phát âm thanh là một mô-đun thuần túy Python, nền tảng đa chức năng, không có phụ thuộc để phát âm thanh.

Cài đặt qua pip:

$ pip install playsound

Sau khi cài đặt xong, bạn có thể sử dụng nó như sau:

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

36
Đọc đến đây khiến tôi rất xúc động. Mắt tôi rưng rưng vì hạnh phúc. Không ngờ phản ứng như vậy từ chính tôi. (Họ đã liên kết với một mô-đun tôi đã thực hiện.)
ArtOfWarfare

+1 cho playsound. Tôi vừa thử nghiệm một vài giải pháp ở đây và giải pháp này phù hợp nhất với tôi. Thật không may, pygamegiải pháp không hoạt động với tôi, trong một thử nghiệm ngắn.
Trevor Sullivan

13

Trong pydub gần đây, chúng tôi đã chọn sử dụng ffplay (thông qua quy trình con) từ bộ công cụ ffmpeg, sử dụng nội bộ SDL.

Nó hoạt động cho các mục đích của chúng tôi - chủ yếu chỉ giúp kiểm tra kết quả của mã pydub ở chế độ tương tác dễ dàng hơn - nhưng nó có nhược điểm, như khiến một chương trình mới xuất hiện trong thanh công cụ trên mac.

Tôi đã liên kết việc triển khai ở trên, nhưng một phiên bản đơn giản sau:

import subprocess

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

Các -nodispcờ dừng ffplay hiển thị một cửa sổ mới, và các -autoexitlá cờ gây ffplay để thoát và trả về một mã trạng thái khi tập tin âm thanh được thực hiện chơi.

chỉnh sửa : pydub hiện sử dụng pyaudio để phát lại khi nó được cài đặt và quay trở lại ffplay để tránh những nhược điểm mà tôi đã đề cập. Liên kết ở trên cũng cho thấy việc triển khai đó.


1
Pydub có vẻ như nó có khá nhiều tiềm năng như một thư viện trình bao bọc - tôi đang cài đặt nó ngay bây giờ.
Shadow

1
PyDub chết tiệt trông đẹp và nó vẫn thực sự hoạt động.
corysimmons

13

Xin lỗi vì đã trả lời muộn, nhưng tôi nghĩ đây là một nơi tốt để quảng cáo thư viện của tôi ...

AFAIK, thư viện tiêu chuẩn chỉ có một mô-đun để phát âm thanh: ossaudiodev . Đáng buồn thay, điều này chỉ hoạt động trên Linux và FreeBSD.

CẬP NHẬT: Cũng có lợi thế , nhưng rõ ràng đây cũng là nền tảng cụ thể.

Đối với một cái gì đó độc lập với nền tảng hơn, bạn sẽ cần sử dụng một thư viện bên ngoài.

Đề xuất của tôi là mô-đun sounddevice (nhưng hãy cẩn thận, tôi là tác giả).

Gói này bao gồm thư viện PortAudio được biên dịch trước cho Mac OS X và Windows, và có thể dễ dàng cài đặt với:

pip install sounddevice --user

Nó có thể phát lại âm thanh từ mảng NumPy, nhưng nó cũng có thể sử dụng bộ đệm Python thuần túy (nếu NumPy không có sẵn).

Để phát lại mảng NumPy, đó là tất cả những gì bạn cần (giả sử rằng dữ liệu âm thanh có tần số lấy mẫu là 44100 Hz):

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

Để biết thêm chi tiết, hãy xem tài liệu .

Nó không thể đọc / ghi các tệp âm thanh, bạn sẽ cần một thư viện riêng cho việc đó.


Tuyệt quá! Chỉ những gì tôi cần để tạo một chương trình demo lớp học về wave.
Bill N


4

Câu trả lời của Aaron dường như phức tạp hơn khoảng 10 lần so với mức cần thiết. Chỉ cần làm điều này nếu bạn chỉ cần câu trả lời hoạt động trên OS X:

from AppKit import NSSound

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

Một điều ... điều này trở lại ngay lập tức. Vì vậy, bạn cũng có thể muốn làm điều này, nếu bạn muốn cuộc gọi bị chặn cho đến khi âm thanh phát xong.

from time import sleep

sleep(sound.duration())

Chỉnh sửa: Tôi đã lấy chức năng này và kết hợp nó với các biến thể cho Windows và Linux. Kết quả là một mô-đun nền tảng chéo, python thuần túy không có phụ thuộc được gọi là Playingound . Tôi đã tải nó lên pypi.

pip install playsound

Sau đó chạy nó như thế này:

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

Các tệp MP3 cũng hoạt động trên OS X. WAV sẽ hoạt động trên tất cả các nền tảng. Tôi không biết các kết hợp nền tảng / định dạng tệp khác hoạt động hoặc không hoạt động - tôi chưa thử chúng.


Tôi gặp lỗi sau: "Không thể chuyển đổi hoàn toàn đối tượng 'byte' thành str" trên Python 3.5 (Windows).
Erwin Mayer

@ErwinMayer - Bạn đang nói về playsoundmô-đun mà tôi đã viết? Tôi đã không thử nghiệm nó trên bất cứ điều gì mới hơn so với Python 2.7.11 ... Tôi chắc chắn có thể nhìn vào sửa chữa này trên 3,5 ...
ArtOfWarfare

Thật. Nó phải là do sự khác biệt của Python 3.
Erwin Mayer

AppKit một phụ thuộc.
Chris Larson

2
@ArtOfWarfare Điều đó chỉ đơn giản là không đúng. Nó được cài đặt bằng python hệ thống, nhưng không phải với hầu hết các bản phân phối, bao gồm cả các bản phân phối chính thức từ python.org. Hầu hết những người tôi biết sử dụng python đều cài đặt một trong các bản phân phối để vượt qua các hạn chế của SIP. Để tải AppKit cho hầu hết các bản phân phối, người dùng cần cài đặt pyobjc. Điều này làm cho nó chắc chắn là một phụ thuộc.
Chris Larson

3

Đây là cách dễ nhất và tốt nhất mà chúng tôi tìm thấy. Nó hỗ trợ Linux / pulseaudio, Mac / coreaudio và 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)

Xem https://github.com/bastibe/PySoundFilehttps://github.com/bastibe/SoundCard để biết rất nhiều tính năng siêu hữu ích khác.


Chỉ là một cảnh báo cho bất kỳ ai đang làm điều này (như tôi). Tất cả các lib và phụ thuộc của chúng sẽ mất vĩnh viễn để xây dựng trên Raspberry Pi 1B + - đặc biệt là numpy.
pojda

Tái bút: điều này không hoạt động đối với raspberry pi "NotImplementedError: SoundCard chưa hỗ trợ linux2" và không thể tìm ra cách để khắc phục nó. Tôi đang đi với os.system ( "mpg123 xmms file.mp3")
pojda

A, thật tệ. Tôi đoán raspberry pi là một môi trường hơi đặc biệt. Có lẽ nếu bạn đăng một vấn đề trên Issuetracker, bạn có thể sắp xếp hoặc khắc phục sự cố.
n00p

Suy nghĩ sâu hơn, có lẽ vấn đề là bạn đang sử dụng hạt nhân cũ hoặc phiên bản python cũ. Với các phiên bản python mới hơn, lỗi đó sẽ không giống như tôi nghĩ.
n00p

Nó đang chạy Raspbian, về cơ bản là một nhánh Debian Stretch. Tôi đã từ bỏ và đi theo cách hệ thống os.system đang hoạt động tốt atm. Cảm ơn vì đã giúp tôi ra ngoài!
pojda

2

Có thể phát âm thanh trong OS X mà không cần bất kỳ thư viện của bên thứ 3 nào bằng cách sử dụng mã tương tự của mã sau. Dữ liệu âm thanh thô có thể được nhập bằng wave_wave.writeframes. Đoạn mã này trích xuất 4 giây âm thanh từ tệp đầu vào.

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

Điều này phức tạp hơn nhiều so với mức cần thiết - họ hỏi làm thế nào để phát một âm thanh đơn giản chứ không phải làm thế nào để thao tác và sau đó phát âm thanh đó. Câu trả lời của tôi cắt bỏ 90% không cần thiết từ câu trả lời này và để lại chính xác những gì người hỏi muốn - phát âm thanh từ tệp trong OS X bằng Python. stackoverflow.com/a/34984200/901641
ArtOfWarfare,

2

Hãy thử PySoundCard sử dụng PortAudio để phát lại có sẵn trên nhiều nền tảng. Ngoài ra, nó còn nhận ra các thiết bị âm thanh "chuyên nghiệp" với rất nhiều kênh.

Dưới đây là một ví dụ nhỏ từ 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()

Mặc dù thú vị, nhưng câu trả lời chỉ có liên kết không được khuyến khích. Ít nhất, bạn nên đưa vào câu trả lời của mình một ví dụ ngắn về việc sử dụng nó. Điều đó cũng bảo vệ câu trả lời của bạn khỏi mất tất cả giá trị của nó, nếu kho lưu trữ được đổi tên và liên kết bị treo.
phổ

2

Cũng trên OSX - từ SO , sử dụng lệnh afplay của OSX :

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

CẬP NHẬT: Tất cả điều này là chỉ định cách thực hiện những gì OP muốn tránh làm ngay từ đầu. Tôi đoán tôi đã đăng điều này ở đây vì những gì OP muốn tránh là thông tin tôi đang tìm kiếm. Rất tiếc.


Hoạt động tốt mặc dù không tạm dừng thực hiện trong khi nó phát. Có lẽ có một cách không đồng bộ để gọi điều này?
Praxiteles

Câu hỏi hay @Praxiteles. Có thể với luồng. xem tại đây Vui lòng báo cáo lại nếu bạn có cơ hội thử nghiệm với nó.
MikeiLL

OP đã yêu cầu rõ ràng các lựa chọn thay thế cho điều này.
whitey04,

OP đang / đang tìm kiếm một giải pháp thay thế để "thực thi lệnh afplay file.mp3 từ bên trong Python" và quá trình xử lý con vẫn xảy ra trong Python, phải không. Tôi đứng sửa lại. Nhưng có lẽ không có hại gì nếu có một bài đăng nhỏ này ở đây vì nó có thể giúp ích cho những người khác.
MikeiLL

@ whitey04 Tôi (cuối cùng) cũng hiểu bạn đang nói gì.
MikeiLL

1

Pypi có một danh sách các mô-đun cho python trong âm nhạc. Yêu thích của tôi là jython vì nó có nhiều tài nguyên và thư viện hơn cho âm nhạc. Ví dụ về mã để chơi một nốt nhạc trong sách giáo khoa :

# 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 Tôi đã thử rất nhiều mã nhưng chỉ mã này hoạt động với tôi

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

Cài đặt playsoundgói bằng:

pip install playsound

Sử dụng:

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

0
Đặt cái này ở đầu tập lệnh python mà bạn đang viết:
import subprocess
Nếu tệp wav nằm trong thư mục của tập lệnh python:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Nếu tệp wav KHÔNG có trong thư mục của tập lệnh python:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Nếu bạn muốn tìm hiểu thêm về aplay:
man aplay

0

Để phát âm thanh thông báo bằng python, hãy gọi một trình phát nhạc, chẳng hạn như vlc. VLC đã nhắc tôi sử dụng phiên bản dòng lệnh của nó, cvlc, để thay thế.

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

Nó yêu cầu vlc được cài đặt sẵn trên thiết bị. Đã thử nghiệm trên Linux (Ubuntu 16.04 LTS); Chạy Python 3.5.


0

Thử thiết bị âm thanh

Nếu bạn không có mô-đun nhập pip install sounddevicetrong thiết bị đầu cuối của bạn.

Sau đó, trong tập lệnh Python ưa thích của bạn (tôi sử dụng Juypter), hãy nhập

import sounddevice as sd

sd.play(audio, sr) sẽ chơi những gì bạn muốn thông qua Python

Cách tốt nhất để có được âm thanh và tốc độ lấy mẫu bạn muốn là sử dụng mô-đun librosa. Nhập mã này vào terminal nếu bạn không có mô-đun librosa.

pip install librosa

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

Bất kỳ tệp wav nào bạn muốn phát, chỉ cần đảm bảo rằng nó nằm trong cùng thư mục với tập lệnh Python của bạn. Điều này sẽ cho phép bạn phát tệp wav mong muốn của mình thông qua Python

Chúc mừng, Charlie

PS

Khi âm thanh là một đối tượng dữ liệu "librosa", Python sẽ coi nó như một mảng phức tạp. Như một thử nghiệm, hãy thử chơi một thứ dài (thử 20.000 điểm dữ liệu) của một mảng ngẫu nhiên. Python nên chơi nó dưới dạng tiếng ồn trắng. Mô-đun sounddevice cũng chơi các mảng và danh sách phức tạp.


đã làm điều này, nhưng nó không chơi bất cứ điều gì. Nó chỉ bỏ qua cuộc gọi sd.play
Tobias Kolb

0

Trong sổ ghi chép Colab, bạn có thể làm:

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


-1

Nếu đang sử dụng OSX, bạn có thể sử dụng mô-đun "os" hoặc "subprocess", v.v. để gọi lệnh "play" OSX. Từ giao diện OSX, có vẻ như

chơi "bah.wav"

Nó bắt đầu phát sau khoảng nửa giây trên máy của tôi.


1
Tôi muốn xem cú pháp cho cả hai phương pháp này.
MikeiLL

-1

Đơn giản là Bạn có thể làm điều đó với sự trợ giúp của cvlc- Tôi đã làm theo cách này:

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

/home/maulo/selfProject/task.mp3. Đây là vị trí của tệp mp3 của tôi. với sự trợ giúp của "--play-and-exit", bạn sẽ có thể phát lại âm thanh mà không cần kết thúc quá trình vlc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.