Воспроизведение аудио с Python

108

Как я могу воспроизвести звук (это будет как звук в 1 секунду) из скрипта Python?

Было бы лучше, если бы он не зависел от платформы, но для начала он должен работать на Mac.

Я знаю, что могу просто выполнить afplay file.mp3команду из Python, но можно ли сделать это в чистом Python? Мне также было бы лучше, если бы он не полагался на внешние библиотеки.

Джош Хант
источник
Pyglet имеет возможность воспроизводить звук через внешнюю библиотеку под названием AVbin . Pyglet - это оболочка ctypes для собственных системных вызовов на каждой поддерживаемой платформе. К сожалению, я не думаю, что что-нибудь в стандартной библиотеке будет воспроизводить звук.
technomalogical
Если вам нужна портативная звуковая библиотека Python, попробуйте PyAudio . У него определенно есть порт для Mac. Что касается мр3 файлов: это, конечно, можно сделать на "сыром" Python, только боюсь, вам придется все кодировать самостоятельно :). Если вы можете позволить себе какую-то внешнюю библиотеку, я нашел здесь образец PyAudio - PyLame .
Гжегож Гацек

Ответы:

17

Вы можете найти информацию об аудио Python здесь: http://wiki.python.org/moin/Audio/

Не похоже, что он может воспроизводить файлы .mp3 без внешних библиотек. Вы можете либо преобразовать файл .mp3 в .wav или другой формат, либо использовать такую ​​библиотеку, как PyMedia .

Джереми Рутен
источник
12
Но как мне воспроизвести .wavфайл?
theonlygusti
@theonlygusti См здесь , например.
Андерсон Грин
42

Лучше всего, вероятно, использовать pygame / SDL . Это внешняя библиотека, но она имеет отличную поддержку на разных платформах.

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

Вы можете найти более конкретную документацию о поддержке аудиомикшера в документации pygame.mixer.music.

TML
источник
2
Для меня это не сработало. Я имею в виду, он играл, но без звука. Я добавил time.sleep(5)в конце, и это сработало. Python 3.6 для Windows 8.1
Nagabhushan SN
Огненный пакет! Спасибо!
Сергей Зеленчук
Он не работает на Fedora со стандартными «.wav», «.mp3» и «.ogg» (невозможно открыть файл «filename.format»)
Кальвин-Руис
1
@ Calvin-Ruiz Я только что подтвердил, что могу использовать приведенный выше код в FC31 для воспроизведения файлов MP3 и Ogg. Я думаю, что у вас есть более серьезная проблема, для которой, вероятно, необходимо детальное знание вашей платформы.
TML
18

Взгляните на Simpleaudio , относительно недавнюю и легкую библиотеку для этой цели:

> pip install simpleaudio

Затем:

import simpleaudio as sa

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

Обязательно используйте несжатые 16-битные файлы PCM.

Эрвин Майер
источник
Отлично, спасибо - полезно для игр, которые должны воспроизводить короткие звуковые эффекты и поддерживают Python 3.
Томас Перл
18

Попробуйте использовать playsound, который представляет собой кроссплатформенный однофункциональный модуль на чистом Python без каких-либо зависимостей для воспроизведения звуков.

Установить через pip:

$ pip install playsound

После установки вы можете использовать его так:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
Йехан Джая
источник
37
Это чтение меня так взволновало. Мои глаза буквально слезились от счастья. Не ожидал от себя такой реакции. (Они связались с созданным мной модулем.)
ArtOfWarfare
+1 за playsound. Я только что протестировал здесь пару решений, и это сработало для меня проще всего. К сожалению pygame, во время краткого теста решение не сработало.
Trevor Sullivan
14

В pydub мы недавно решили использовать ffplay (через подпроцесс) из набора инструментов ffmpeg, который внутренне использует SDL.

Он работает для наших целей - в основном просто для упрощения тестирования результатов кода pydub в интерактивном режиме - но у него есть свои недостатки, например, появление новой программы в доке на Mac.

Я связал реализацию выше, но следует упрощенная версия:

import subprocess

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

-nodispФлаг останавливается ffplay показ нового окна, и -autoexitфлаг вызывает ffplay к выходу и возвращать код состояния , когда аудиофайл окончания воспроизведения.

edit : pydub теперь использует pyaudio для воспроизведения, когда он установлен, и возвращается к ffplay, чтобы избежать недостатков, о которых я упоминал. Ссылка выше также показывает эту реализацию.

Jiaaro
источник
1
Pydub выглядит так, как будто у него есть большой потенциал в качестве библиотеки-оболочки - я устанавливаю его сейчас.
Shadow
1
Проклятье, PyDub выглядит неплохо и все еще очень активен.
corysimmons 05
13

Извините за поздний ответ, но я думаю, что это хорошее место для рекламы моей библиотеки ...

AFAIK, в стандартной библиотеке есть только один модуль для воспроизведения аудио: ossaudiodev . К сожалению, это работает только в Linux и FreeBSD.

ОБНОВЛЕНИЕ: также есть выигрыш , но, очевидно, это также зависит от платформы.

Для чего-то более независимого от платформы вам понадобится внешняя библиотека.

Я рекомендую модуль звукового устройства (но будьте осторожны, я автор).

Пакет включает предварительно скомпилированную библиотеку PortAudio для Mac OS X и Windows, и ее можно легко установить с помощью:

pip install sounddevice --user

Он может воспроизводить звук из массивов NumPy, но также может использовать простые буферы Python (если NumPy недоступен).

Для воспроизведения массива NumPy это все, что вам нужно (при условии, что аудиоданные имеют частоту дискретизации 44100 Гц):

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

Подробнее читайте в документации .

Он не может читать / записывать звуковые файлы, для этого вам понадобится отдельная библиотека.

Матиас
источник
Большой! Как раз то, что мне нужно для создания демонстрационной программы о волнах.
Bill N
5

Вы можете увидеть это: http://www.speech.kth.se/snack/

s = Sound() 
s.read('sound.wav') 
s.play()
user1926182
источник
3
Выглядит так чисто, я бы хотел, чтобы для этого был пакет pip. Простота установки является ключевым моментом
Джонатан
4

Ответ Аарона кажется примерно в 10 раз сложнее, чем необходимо. Просто сделайте это, если вам нужен только ответ, работающий в OS X:

from AppKit import NSSound

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

Одно дело ... это немедленно возвращается. Таким образом, вы можете также сделать это, если хотите, чтобы вызов блокировался до тех пор, пока звук не перестанет воспроизводиться.

from time import sleep

sleep(sound.duration())

Изменить: я взял эту функцию и объединил ее с вариантами для Windows и Linux. В результате получился кроссплатформенный модуль на чистом питоне без зависимостей, который называется playsound . Я загрузил его на pypi.

pip install playsound

Затем запустите его так:

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

Файлы MP3 также работают в OS X. WAV должен работать на всех платформах. Я не знаю, какие другие комбинации платформы / формата файла работают или не работают - я их еще не пробовал.

Искусство Войны
источник
Я получаю следующую ошибку: «Не могу неявно преобразовать объект 'bytes' в str» в Python 3.5 (Windows).
Эрвин Майер,
@ErwinMayer - Ты про playsoundмодуль, который я написал? Я не тестировал это ни на чем новее, чем Python 2.7.11 ... Я, конечно, могу попытаться исправить это на 3.5 ...
ArtOfWarfare
На самом деле. Это должно быть связано с различиями в Python 3.
Эрвин Майер
AppKit - это зависимость.
Крис Ларсон,
2
@ArtOfWarfare Это просто не так. Он устанавливается вместе с системным python, но не с большинством дистрибутивов, включая официальные дистрибутивы с python.org. Большинство моих знакомых, использующих python, устанавливают один из дистрибутивов, чтобы обойти ограничения SIP. Чтобы получить AppKit для большинства дистрибутивов, пользователю необходимо установить pyobjc. Что делает его определенно зависимостью.
Крис Ларсон,
3

Это самый простой и лучший из найденных. Он поддерживает Linux / pulseaudio, Mac / coreaudio и 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)

См. Https://github.com/bastibe/PySoundFile и https://github.com/bastibe/SoundCard для множества других супер-полезных функций.

n00p
источник
Просто предупреждение для всех, кто собирается на это (как и я). Все библиотеки и их зависимости требуют вечности, чтобы построить на Raspberry Pi 1B + - особенно numpy.
Пойд
PS: это не сработало для raspberry pi "NotImplementedError: SoundCard еще не поддерживает linux2" и не смог найти способ исправить это. Я использую os.system ("mpg123 file.mp3")
пойда
Ах, это отстой. Я полагаю, что Raspberry Pi - это особенная среда. Возможно, если вы разместите проблему в системе отслеживания ошибок, вы сможете решить ее или исправить.
n00p
Если подумать, возможно, проблема в том, что вы используете старое ядро ​​или старую версию Python. Я думаю, что с более новыми версиями Python эта ошибка не должна выглядеть так.
n00p
Он работает под управлением Raspbian, который по сути является форком Debian Stretch. Я сдался и пошел путем os.system, который отлично работает. Спасибо, что помогли мне!
Пойд
2

Можно воспроизводить звук в OS X без каких-либо сторонних библиотек, используя аналог следующего кода. Необработанные аудиоданные можно вводить с помощью wave_wave.writeframes. Этот код извлекает 4 секунды аудио из входного файла.

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()
Аарон
источник
Это намного сложнее, чем необходимо - они спрашивали, как просто воспроизвести звук, а не как им управлять, а затем воспроизводить. Мой ответ обрезает ненужные 90% из этого ответа и оставляет именно то, что хотел спрашивающий - воспроизведение звука из файла в OS X с использованием Python. stackoverflow.com/a/34984200/901641
ArtOfWarfare
2

Попробуйте PySoundCard, использующий для воспроизведения PortAudio, доступный на многих платформах. Кроме того, он распознает «профессиональные» звуковые устройства с большим количеством каналов.

Вот небольшой пример из 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()
Стефан Балке
источник
Хотя это интересно, ответы только по ссылкам не приветствуются. Как минимум, вы должны включить в свой ответ краткий пример его использования. Это также защищает ваш ответ от потери всей его ценности, если репозиторий будет переименован, а ссылка будет зависать.
спектры
2

Также в OSX - из SO , используя команду OSX afplay :

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

ОБНОВЛЕНИЕ: все это указывает, как делать то, чего OP хотел избежать в первую очередь. Думаю, я разместил это здесь, потому что OP хотел избежать именно той информации, которую я искал. Упс.

MikeiLL
источник
Отлично работает, хотя приостанавливает выполнение во время воспроизведения. Возможно, есть способ вызвать это асинхронно?
Пракситель
Хорошие вопросы @Praxiteles. Возможно с резьбой. см. здесь. Сообщите, если у вас есть возможность поэкспериментировать.
MikeiLL 05
ОП явно попросил альтернативы этому.
whitey04
OP искал / искал альтернативу «выполнить команду afplay file.mp3 из Python», и подпроцессинг все еще происходит в Python, не так ли. Я исправился. Но, вероятно, этот небольшой пост здесь не повредит, так как он может помочь другим.
MikeiLL
@ whitey04 Я (наконец) понял, о чем вы говорите.
MikeiLL
1

Pypi имеет список модулей для Python в музыке. Мне больше всего нравится jython, потому что в нем больше ресурсов и библиотек для музыки. В качестве примера кода для воспроизведения одной заметки из учебника :

# 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 Я пробовал много кодов, но у меня это работает

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

Установите playsoundпакет, используя:

pip install playsound

Использование:

from playsound import playsound
playsound("file location\audio.p3")
Хариш
источник
0
Поместите это в начало вашего скрипта python, который вы пишете:
import subprocess
Если wav-файл находится в каталоге скрипта python:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
Если wav-файла НЕТ в каталоге скрипта python:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
Если вы хотите узнать больше об игре:
man aplay
Ползучий
источник
0

Чтобы воспроизвести звук уведомления с помощью python, вызовите музыкальный проигрыватель, например vlc. VLC побудил меня использовать его версию командной строки, cvlc, вместо этого.

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

Для этого требуется, чтобы на устройстве был предварительно установлен vlc. Протестировано в Linux (Ubuntu 16.04 LTS); Запуск Python 3.5.

AmarVashishth
источник
0

Попробуйте звуковое устройство

Если у вас нет модуля, введите его pip install sounddeviceв свой терминал.

Затем в предпочитаемом вами скрипте Python (я использую Juypter) введите

import sounddevice as sd

sd.play(audio, sr) будет воспроизводить то, что вы хотите, через Python

Лучший способ получить нужный звук и частоту дискретизации - использовать модуль librosa. Введите это в терминал, если у вас нет модуля librosa.

pip install librosa

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

Независимо от того, какой файл wav вы хотите воспроизвести, просто убедитесь, что он находится в том же каталоге, что и ваш скрипт Python. Это должно позволить вам воспроизводить желаемый файл WAV через Python.

Привет, Чарли

PS

Как только аудио является объектом данных "librosa", Python видит его как массив numpy. В качестве эксперимента попробуйте воспроизвести длинный (попробуйте 20 000 точек данных) случайный массив numpy. Python должен воспроизводить это как белый шум. Модуль sounddevice также воспроизводит множество массивов и списков.

Чарли Каррера
источник
сделал это, но ничего не воспроизводит. Это просто пропуск звонка sd.play
Тобиас Колб
0

В записной книжке Colab вы можете:

from IPython.display import Audio
Audio(waveform, Rate=16000)
Аксель Брегнсбо
источник
0

Недавно я заставил свой музыкальный проигрыватель поддерживать все аудиофайлы локально. Я сделал это, выяснив, как использовать модуль vlc python, а также файлы dll VLC. Вы можете проверить это: https://github.com/elibroftw/music-caster/blob/master/audio_player.py

Эли
источник
-1

Если вы работаете в OSX, вы можете использовать модуль «os» или «подпроцесс» и т. Д., Чтобы вызвать команду OSX «play». Из оболочки OSX это выглядит как

играть "bah.wav"

На моей машине он начинает играть примерно через полсекунды.

Лунная собачка
источник
1
Мне было бы интересно увидеть синтаксис обоих этих методов.
MikeiLL
-1

Просто вы можете сделать это с помощью cvlc - я сделал это так:

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

/home/maulo/selfProject/task.mp3. Здесь находится мой mp3-файл. с помощью "--play-and-exit" вы сможете снова воспроизвести звук, не прерывая процесс vlc.

pyAddict
источник