Skip to content

Output Stream for AudioPlayer #10489

Open
@DanielBUBU

Description

Which application or package is this feature request for?

voice

Feature

I am trying to build a site that can play same music on discord.

  • when AudioPlayer pause, the music on the site pause (site got long keep alive setting so it should be fine)
  • the site can take multiple request at once
  • the stream on the site should able to play on VLC

here's the part of the code I wrote:
BufferTransformStream

const { Transform } = require('stream');

const DEFAULT_CAPACITY = 10;

class BufferingTransform extends Transform {
    constructor(options = {}) {
        super(options);

        this.capacity = options.capacity || DEFAULT_CAPACITY;
        this.delay = options.delay || 25
        this.pending = [];

        return;
    }

    get atCapacity() {
        return this.pending.length >= this.capacity;
    }

    _transform(chunk, encoding, cb) {

        if (this.atCapacity) {
            this.push(...this.pending.shift());
        }

        this.pending.push([chunk, encoding]);

        if (cb != undefined) {
            cb();
        }
    }

    _flush(cb) {

        while (this.pending.length > 0) {
            this.push(...this.pending.shift());
        }

        if (cb != undefined) {
            cb();
        }
    }

    _write(chunk, encoding, callback) {
        this.push(chunk);
        setTimeout(callback, this.delay);
    }
    _final() {
        this.push(null)
    }
}

in my class for music processing:

this.port = process.env.PORT + processIndex + 1 || 4000 + processIndex + 1;

        this.expressApp.get('/', (req, res) => {
            console.log("A new connection was made by a client.");
            var bufferStr = new BufferingTransform();
            res.writeHead(200, {
                //'Content-Type': 'video/mp4',
                //"Content-Length": "*",
            });
            bufferStr.on("data", async (data) => {
                //console.log("BufData")
            })
            bufferStr.on("end", async (data) => {
                //console.log("BufEnd")
            })
            res.on('close', () => {
                console.log("Des")
                try {
                    bufferStr.destroy();
                } catch (error) {

                }
            });
            bufferStr.pipe(res);
            this.webAudioStream.pipe(bufferStr);
        })
        while (!this.webListenerSuccessFlag && this.port <= 65535) {
            try {
                this.expressApp.listen(this.port, () => {
                    this.port--;
                    console.log(`ChildProcess ${processIndex} listening on port ${this.port}`)
                }).on('connection', function (socket) {
                        socket.setTimeout(3000 * 1000);
                        // 30 second timeout. Change this as you see fit.
                });
                this.webListenerSuccessFlag = true;
            } catch (error) {
                console.log(error);
            }
            this.port++;
        }

this.webAudioStream is a BufferingTransform object
I want data pass from a AudioPlayer object to this.webAudioStream (so music sync with discord)

Ideal solution or implementation

  • Output silence when player is not in AudioPlayerPlayingState instead of close/end the output stream

Method1-Add pipe function

Pipe to another stream and AudioPlayerObject doesn't close when the stream that pipe into is closed

AudioPlayerObject.pipe(BufferingTransformStreamETC1)
BufferingTransformStream.Close();
AudioPlayerObject.pipe(BufferingTransformStreamETC2)

Method2-Pretend it's a connection

Init a VoiceConnection object using a stream, so it can be sub/unsub just like a VoiceConnection

VoiceConnectionObject=joinVoiceChannel({
            stream :BufferingTransform
        })

or

VoiceConnectionObject=createFromStream({
            stream :BufferingTransform
        })

Alternative solutions or implementations

No response

Other context

My target is create a web radio that sync with discord.
It can be done if I pipe them like this:

sources=>web radio=>discord audio resource

But the annoying part is that I have to maintain more stuff.
And discord audio might be unstable due to the web radio part, in a discord bot project, so it become a tradeoff between reliability and new web radio function for my bot

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions