-
-
Notifications
You must be signed in to change notification settings - Fork 469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add more support for using Sinks as audio streams #2043
Comments
Feel free to pr this feature if you have it already ready |
Hi, I saw this coincidentally while my friends and I are working on getting audio streaming to work via Pycord so I thought I'd drop my code here incase you or someone else is looking for a working solution. This is still very much in development so please excuse any silly # comments or weird structuring. For implementing a custom Sink class, we went ahead and did this:
This, at the moment, will output a series of numbered 2-second mp3 files to the working directory. This is not the best solution but we did it just to validate that we can safely pull the live audio data. The end goal is to pass the audio data to some other processes without writing it to a file. To get this working in a live bot, we went ahead and implemented the following:
As it stands, this bot will join a voice channel when invited and will receive only the voice of the person who invited it. This is specific to our use case but you can likely modify this to stack the received audio. Again, this is still being developed and I will probably forget to update this so you can check to see if any changes were made here: ScruffyTheMoose/HushVC |
Summary
Currently working with AudioData as a stream is unnecessarily difficult and the experience could be improved
What is the feature request for?
The core library
The Problem
There's 2 issues with using AudioData as a stream in current version of pycord.
Encoding
AudioData objects generated by Sinks do not have the proper .wav or .mp3 encoding (including valid byte prefixes) for the data to be read directly without doing the encoding by hand. Doing the encoding without saving to a file isn't a common use case, and as such it requires the developer to subclass existing audio manipulation libraries (like wav or pydub) to achieve that goal.
Library support
voice_client.start_recording() currently requires a coroutine callback as one of it's arguments. This means you not only have to pass a function even if you don't need one, but the function can't even be a lambda, since it is required that it is a coroutine.
The Ideal Solution
Encoding
Add a .read(user_id, starting_byte=0, encode=False) method to sinks (or AudioData) which returns encoded data of the underlying AudioData object like a stream would. Make encoding optional and otherwise match the selected sink (like .wav for WaveSink).
Library support
Make the callback argument optional, or at the very least allow for passing an empty lambda as the callback.
The Current Solution
Encoding
It is possible to subclass WaveSink & AudioData to add your own .read() method, and to subclass an audio manipulation library like wav or pydub to encode the audio stream without saving it to a file.
Library support
Unfortunately you can only create a dummy coroutine that does nothing, or pass a lambda and catch the function call in a try catch block.
Additional Context
I've implemented a rough solution over at wmetryka/pycord-voice-interface if you want to look at an example.
The text was updated successfully, but these errors were encountered: