Streaming audio to clients

Please post any questions about developing your plugin here. Please use the search function before posting!
arawra
Senior Member
Posts: 190
Joined: Fri Jun 21, 2013 6:51 am

Streaming audio to clients

Postby arawra » 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)
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Streaming audio to clients

Postby Ayuto » Thu Feb 18, 2021 2:00 pm

I'm currently unable to provide an example, but IIRC this was possible with some kind of a hidden MOTD. Maybe that helps to start the research?
arawra
Senior Member
Posts: 190
Joined: Fri Jun 21, 2013 6:51 am

Re: Streaming audio to clients

Postby arawra » Fri Feb 19, 2021 3:03 pm

I did think of using VGUI and motd to send something to a client, but everything I came up with suggested a patch that removed that capability due to overuse by server admins. If I'm mistaken I'd like to know, as of now I'll need to keep googling.
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: Streaming audio to clients

Postby Kami » Fri Feb 19, 2021 3:14 pm

Are you using CS:S or CS:GO? The funfact Message of csgo has HTML compatibility, maybe that would be an approach.

Edit: I had no luck with that approach.

This is what I used for testing:

Syntax: Select all

# Source.Python
from events.manager import game_event_manager
from players.entity import Player
from events import Event

#https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3

@Event('player_say')
def _say(ev):
player = Player.from_userid(ev['userid'])
send_win_message(
message='<audio controls autoplay><source src="https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3" type="audio/mp3></audio>',
recipients=(player.index,)
)
duration = 10
player.delay(duration,send_win_message,("", (player.index,)))


def send_win_message(message='', recipients=None):
"""Creates and sends the 'cs_win_panel_round' event.

Args:
message (str): Message to send, supports some HTML tags.
recipients: List/tuple of player indexes that should receive the
message.
"""
event = game_event_manager.create_event('cs_win_panel_round')
event.set_string('funfact_token', message)

# Should the message be sent to everyone on the server?
if recipients is None:
game_event_manager.fire_event(event)

# Or have the recipients been specified?
else:
for index in recipients:
try:
# Try to get a Player instance.
Player(index).base_client.fire_game_event(event)
except ValueError:
continue

# When firing events to players/clients directly, we need to free it
# once we're done with it.
game_event_manager.free_event(event)


I tried mp3, wav and ogg files. Maybe I'm doing it wrong. Or maybe the message does not support sending audio.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Streaming audio to clients

Postby decompile » Tue Mar 02, 2021 12:29 pm

What about making a custom page which basically autoplays in the background when you open the url?

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 31 guests