-
Notifications
You must be signed in to change notification settings - Fork 38
Sfx Cog Tutorial
Sound effects can be difficult to implement. Discord just isn't (for the time being) designed to support playing of sound effects in multiple voice channels. The goal of this project was to make sound effects a little easier for everyone. In addition to being a great standalone SFX/TTS cog, you can also include sound effects and text-to-speech in your own cog by using the Sfx cog as an API. The following class methods are available once you use get_cog('Sfx')
. They will return True
if queuing was successful, and False
if queuing failed.
def enqueue_tts(self, vchan: discord.Channel,
text: str,
vol: int=None,
priority: int=5,
tchan: discord.Channel=None,
language: str=None):
def enqueue_sfx(self, vchan: discord.Channel,
path: str,
vol: int=None,
priority: int=5,
delete: bool=False,
tchan: discord.Channel=None):
How do the arguments work?
-
vchan
is the discord voice channel object where the sound is to be played -
text
is a string of the text to convert to TTS -
path
is the path to the sound effect file -
vol
(optional) is an integer from 0-100 specifying the volume -
priority
(optional) is an integer for future implementation of a priority queue -
language
(optional) is a string for the gTTS language -
delete
(optional) is a boolean value.True
if you want the Sfx cog to attempt to delete the sound effect after it's played -
tchan
(optional) is the discord text channel object for future implementation of text channel things
Just show me an example!
OK!
from discord.ext import commands
class SfxTest:
"""Example cog using Sfx"""
def __init__(self, bot):
self.bot = bot
self.sfx = bot.get_cog('Sfx')
@commands.command(pass_context=True, no_pm=True)
async def ttstest(self, ctx, *text: str):
"""Play a TTS clip"""
vchan = ctx.message.author.voice_channel
if vchan is None:
await self.bot.say("You're not in a voice channel.")
return
text = ''.join(text)
if not self.sfx.enqueue_tts(vchan, text):
await self.bot.say("Failed to queue TTS.")
@commands.command(pass_context=True, no_pm=True)
async def sfxtest(self, ctx):
"""Play an sfx clip"""
vchan = ctx.message.author.voice_channel
if vchan is None:
await self.bot.say("You're not in a voice channel.")
return
if not self.sfx.enqueue_sfx(vchan, '/data/your_folder/your_sound.mp3'):
await self.bot.say("Failed to queue sfx.")
def setup(bot):
bot.add_cog(SfxTest(bot))
I gotta run, folks. Droppy Jr. will stick around to answer the rest of your questions.
Wut. How does this even work?
The Sfx cog dispatches each sound effect request to a server specific queue. The server queues are First In, First Out (FIFO). This means all sound effects play nice and wait their turn. No cutting!
Can I use Sfx as a standalone cog?
Yes! The cog contains some fantastic sound effect commands written by tmerc, as well as built-in TTS. Use
[p]help
to see what it can do. Sfx is also backwards compatible with tmerc's playsound cog.
Can Sfx be used on multiple servers at the same time?
Yes! Sfx maintains a separate queue for each server. If your bot has the processing power to handle multiple audio streams, Sfx can do it.
What about mutiple channels on the same server at the same time?
Yep! Sfx takes care of the logistics. Discord allows only one active voice connection per server, so the bot will hop between channels as required, but it works.
This totally breaks the core audio cog, right?
You might be surprised how far this project has come. This cog is very polite. If an existing voice client is playing audio and a sound effect is queued, Sfx can pause the existing audio, play the Sfx queue, and then resume the existing audio. This means it's fairly agnostic and can theoretically work with any other audio cog.
But... I mean... this totally breaks the core audio cog, right?
Not totally! Thanks to some monkeypatching, there are very few cases where this conflicts with core audio. It can interrupt core audio streams just fine without breaking them, and when core audio interrupts an Sfx queue, the Sfx queue just gives up and goes home. Like I said, it's very polite. The biggest known issue at the moment, is when an Sfx queue is playing, and someone tries to interrupt it with a brand new core audio stream, the voice client generally disconnects and you'll have to start the audio stream again. If you find additional problems, please open an issue on the repo.