Я хотел бы написать программу на python, которая загружает интернет-радио mp3 поток, обрабатывает данные и воспроизводит аудиопоток на компьютере.
Мне не удалось найти способ сделать это правильно. На данный момент я использую этот код для чтения данных потока блоками:
for block in r.iter_content(1024):
... обработать блок
Затем я могу обрабатывать эти блоки с помощью библиотеки soundfile, и они читаются правильно как mp3:
stream_bytes = io.BytesIO()
stream_bytes.write(block)
...
# после записи нескольких блоков конвертируем mp3 данные в аудиоданные и частоту дискретизации:
data, samplerate = soundfile.read(stream_bytes)
print(f'{samplerate} {len(data)}')
Тогда я знаю, что могу воспроизвести аудио с помощью библиотеки pyaudio, инициализировав ее с той же определённой частотой дискретизации, количеством каналов и отправив аудиоданные.
Хотя здесь я не знаю, как:
- Как обрабатывать сам поток по мере его поступления. То есть, я не могу просто добавлять данные в файл stream_bytes и увеличивать его размер бесконечно, мне нужно как-то обрезать его, но как управлять ‘заголовками’ файла, чтобы он по-прежнему оставался распознаваемым как mp3? Как его обрезать или как сделать так, чтобы soundfile принимал новые ‘байты’? Я не вижу примеров потоковой передачи данных.
- Конвертировать данные из
soundfile
в байтовые данные, приемлемые дляpyaudio
(но я как-нибудь с этим справлюсь)
Ответ
Для загрузки и обработки интернет-радио MP3 потока в Python, а также для воспроизведения этого потока, мы можем использовать несколько библиотек, таких как requests
, io
, pydub
для обработки звука, и pyaudio
для воспроизведения аудио. Вот пошаговое руководство, как это сделать.
-
Установка необходимых библиотек:
Убедитесь, что у вас установлены следующие библиотеки. Вы можете установить их с помощью pip:pip install requests pydub pyaudio
-
Загрузка и обработка потока:
Мы будем использовать библиотекуrequests
для загрузки потока. В то время какpydub
поможет нам с распознаванием и декодированием MP3 данных. Из-за того что потоки могут быть бесконечными, нам нужно обрабатывать их по блокам. Мы будем использоватьAudioSegment
изpydub
для обработки каждого блока. - Воспроизведение аудио с помощью PyAudio:
После обработки данных мы будем воспроизводить их с помощьюpyaudio
.
Вот пример кода, который выполняет все эти шаги:
import requests
import io
from pydub import AudioSegment
import pyaudio
import numpy as np
# URL интернет-радио
url = "http://stream-url" # Замените на ваш URL
# Параметры для воспроизведения
chunk_size = 1024 # Размер блока
p = pyaudio.PyAudio()
# Открытие потока
stream = p.open(format=pyaudio.paInt16,
channels=2,
rate=44100,
output=True)
# Создаем поток для запроса
with requests.get(url, stream=True) as r:
r.raise_for_status()
stream_bytes = bytes() # Хранилище для данных потока
for block in r.iter_content(chunk_size=chunk_size):
stream_bytes += block # Добавляем блок к нашим данным
try:
# Пробуем преобразовать данные в AudioSegment
audio_segment = AudioSegment.from_mp3(io.BytesIO(stream_bytes))
# Получаем данные и преобразуем их в массив numpy
raw_data = audio_segment.raw_data
# Воспроизводим аудио
stream.write(raw_data)
# Очищаем stream_bytes, оставляя только последние 10 секунд (параметр в миллисекундах)
if len(stream_bytes) > 44100 * 2 * 2 * 10: # 44100 * 2 (стерео) * 2 (байта на сэмпл) * 10 секунд
stream_bytes = stream_bytes[-(44100 * 2 * 2 * 10):] # Оставляем последние 10 секунд
except Exception as e:
print(f"Ошибка при обработке: {e}")
continue
# Завершение работы
stream.stop_stream()
stream.close()
p.terminate()
Объяснение работы кода:
- Загрузка потока: Мы используем
requests.get()
для подключения к интернет-радио и получаем поток данных. - Обработка потока: В каждом цикле мы добавляем блок данных к
stream_bytes
. Затем мы пытаемся преобразовать эти данные вAudioSegment
. Если преобразование успешное, мы извлекаем необработанные данные и воспроизводим их. - Ограничение размера буфера: Мы сохраняем только последние 10 секунд данных в
stream_bytes
, чтобы избежать переполнения памяти. Вы можете изменить этот временной интервал на свое усмотрение. - Воспроизведение: Используя PyAudio, мы воспроизводим необработанные данные аудиосегмента.
Обратите внимание:
- В зависимости от вашего потока радиостанции, вам может понадобиться установить правильный формат, каналы и частоту дискретизации для PyAudio.
- Обработку ошибок следует адаптировать под вашу конкретную ситуацию для более надежного выполнения.
Теперь у вас есть полное решение для загрузки, обработки и воспроизведения интернет-радио MP3 потока в Python.