python - 无法使用 Shouty 在流功能中播放多个 .mp3 文件
问题描述
我正在编写一些使用Shouty
. 我的代码采用 .mp3 文件并使用 IceCast 将其流式传输到我制作的网络播放器。
from multiprocessing import Process, JoinableQueue
import queue
import subprocess
import os
from flask import Response
import shouty
class Worker(Process):
def __init__(self):
super().__init__()
self.queue = JoinableQueue()
self.is_mp3 = True
def put_queue(self, mp3file):
self.queue.put(mp3file)
def join_queue(self):
self.queue.join()
def checkMP3(self):
''' Check files before streaming'''
def go_Stream(self):
with shouty.connect(**params) as connection:
song_path = 0
allfiles = os.listdir('app/')
for i in allfiles:
if i[:1] == "C":
song_path = i
return Response(self.streamStart(connection=connection, mp3file=song_path), mimetype="audio/mp3")
def streamStart(self, connection, mp3file):
with open('music/' + mp3file, 'rb') as song:
ffmpeg = None
src = song
if self.is_mp3:
ffmpeg = subprocess.Popen(
[
"ffmpeg",
"-i",
"-",
"-f",
"mp3",
"-ab",
"192",
"-",
],
stdin=song,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
src = ffmpeg.stdout
chunk_size = 4096
sent_bytes = 0
if src:
while True:
chunk = src.read(chunk_size)
if not chunk:
return "Buffer Empty"
yield chunk
sent_bytes += len(chunk)
src.close()
if ffmpeg:
ffmpeg.terminate()
def run(self):
checkMP3()
def run ():
w = Worker()
w.start()
在我用 Flask 设置的 HTML 页面中,网络播放器有一个播放按钮,可以触发go_Stream
. 它有效,但它只播放 .mp3 文件之一,我不知道如何继续播放目录中的 .mp3 文件。我应该streamStart
为每个 .mp3 文件设置一些循环吗?
解决方案
我会让 HTML 播放器页面使用 jquery 之类的东西来请求下一首歌曲并使用索引。如果您修改为您的客户提供歌曲的路线,以在索引处提供歌曲,用户也可以非常简单地跳过歌曲或返回到以前的歌曲,然后您的客户端和服务器端逻辑也可以更简单。
Python 中的服务器端:在 /songplayurl 处等待获取请求,根据请求在所述请求中查找具有所需歌曲索引的路径参数或表单参数,然后使用 icecast 播放该歌曲。
客户端:当用户点击播放器上的下一个或上一个按钮时,向服务器发送一个获取 /songplayurl 的请求,参数为 index+1 或 index-1 。此外,对于自动播放功能,使用播放器检测歌曲何时播放完毕,然后发出新的 index+1 请求。
我建议这样做的原因是因为 Web 应用程序是客户端/服务器应用程序。循环播放需要服务器发送事件来更改歌曲,或者您需要一次将所有歌曲的所有数据发送到客户端应用程序。因此,与其花费所有精力来配置服务器发送的事件,也不必发送大量有效负载,而只需一次发送一首歌曲的数据。
推荐阅读
- connection - Zabbix Server 尝试连接到我的代理
- aframe - Oculus quest 2 控制器模型未在 A-Frame 中正确加载
- android - 当 sweepAngle 小于 360 度时,Android Studio Canvas.drawArc() 不绘制
- apache - Apache2 只是指向全局 documentRoot 而不是子域的文档根目录
- javascript - 从带有参数的函数返回 combineLatest 可观察对象
- adobe - 无法使用集成密钥,因为 Adobe Sign 中新生成的令牌的到期日期是上个月
- android - Android圆形按钮奇怪的差异
- javascript - 从JS中的日期字符串获取日期模式
- css - 绝对位置将搜索结果设置在另一个之上
- c - 检查两个字符串是否大小写相同