Streaming audio to clients
Posted: Wed Feb 17, 2021 8:26 am
I would like to be able to stream audio dynamically to clients. I think traditionally the way to send audio to clients is to precache it by having the clients download audio files, and then force the file to play locally. However this carries the prerequisite of knowing the file ahead of time and having the client connect after its known. What I would like to do is find a music source and then have the audio stream to clients in sync. I am able to download files to the server, however my attempts to stream audio does not work and appears to require clients to download files ahead of time. Is there a solution to this problem?
Syntax: Select all
import paths
from path import Path
from messages import SayText2
from commands.say import SayCommand
import pafy
import vlc
from filters.players import PlayerIter
import os
from engines.sound import StreamSound
from engines.sound import Channel
admins = []
music_commands = ['play', 'stop']
addonDir = Path(__file__).parent
adminsFile = addonDir.joinpath('admins.txt')
songDir = paths.SOUND_PATH
def load():
with open(adminsFile) as af:
for admin in af:
admins.append(admin.rstrip())
message("Jukebox Loaded")
@SayCommand('jb')
def jb(command, index, team_only=False):
jukebox(command, index, team_only)
@SayCommand('jukebox')
def jukebox(command, index, team_only=False):
commands = command.command_string.split(' ')
if len(commands) > 1:
if commands[1] not in music_commands:
messagePlayer("That command doesn't exist", index)
if commands[1] == 'play':
if len(commands) != 3:
messagePlayer("You didn't add a video at the end!", index)
else:
playVideo(commands[2])
def message(msg):
print(msg)
SayText2('\x09[Jukebox]\x01 ' + msg).send()
def messagePlayer(message, index):
print(message + ' sent to player')
SayText2('\x09[Jukebox]\x01 ' + message).send(index)
def videoDownloadStatus(total, recvd, ratio, rate, eta):
message("Downloaded {:.2f}%".format(ratio).replace("0.", "").replace("1.0", "10"))
def playVideo(videoLink):
url = videoLink
video = pafy.new(url)
best = video.getbestaudio()
best.download(callback=videoDownloadStatus)
for s in os.listdir(songDir.joinpath('music')):
if s.startswith(video.title):
song = 'source-python/music/' + s
break
try:
message(song)
except:
message('Couldnt find song')
return
duration = float((video.duration)[3:5])*60 + float((video.duration)[6:8])
durationString = "%sm %ss"%(int(duration/60), int(duration%60))
message(format("Playing {0} {1}".format(video.title, durationString)))
for p in PlayerIter():
p.play_sound(song, sound_time=duration, channel=Channel.STREAM, stream=True)