discordjs / voice

Implementation of the Discord Voice API for discord.js and other JS/TS libraries
Apache License 2.0
328 stars 112 forks source link

Memory leak with inlineVolume: true #197

Open cjh980402 opened 2 years ago

cjh980402 commented 2 years ago

Please describe the problem you are having in as much detail as possible:

Include a reproducible code sample here, if possible:

// Place your code here
let stream = await playdl.stream('https://www.youtube.com/watch?v=rn0wEJmoGdg')

let resource = createAudioResource(stream.stream, {
    inputType : stream.type,
    inlineVolume: true
})
let player = createAudioPlayer({
    behaviors: {
        noSubscriber: NoSubscriberBehavior.Stop
    }
})
player.play(resource)

connection.subscribe(player)

// wait 10 seconds

let connection = getVoiceConnection(message.guild.id)
let player = connection.state.subscription.player
player.stop()

// repeat above code about 5~10 times then we can see memory leak(memory usage is increased.)

Further details:

Relevant client options:

iim-ayush commented 2 years ago

You could have provided a better code for them to test :-

client.on('messageCreate', async message => {
    if(message.content.startsWith('!play')){
        await connectVC(message)
        play_loop(message)
    }
})

async function connectVC(message){
    if(!message.member.voice?.channel) return message.channel.send('Connect to a Voice Channel')
    const connection = joinVoiceChannel({
        channelId : message.member.voice.channel.id,
        guildId : message.guild.id,
        adapterCreator: message.guild.voiceAdapterCreator
    })

    let player = createAudioPlayer({
        behaviors: {
            noSubscriber: NoSubscriberBehavior.Play
        }
    })
    connection.subscribe(player)
}

async function play_loop(message){

    let stream = await playdl.stream('https://www.youtube.com/watch?v=6tyB97J1cVA&t=834s')

    let resource = createAudioResource(stream.stream, {
        inputType : stream.type,
        inlineVolume: true
    })

    let connection = getVoiceConnection(message.guild.id)
    let player = connection.state.subscription.player
    player.play(resource)

    setTimeout(() => {
        player.stop()
        setTimeout(() => {play_loop(message)}, 6000)
    }, 10000)
}
iim-ayush commented 2 years ago

Audio Resource getting in that 6 seconds loop [ where I am looping play_loop() function ] :-

here

PapiOphidian commented 2 years ago

This seems to occur within the opus Encoder as piping audio control through FFMPEG (both prism-media's FFmpeg class and conventionally using child_process.spawn) outputting as S16LE and then piping to an opus Encoder causes the leak.

pauldb09 commented 2 years ago

Is there any fix yet?

PapiOphidian commented 2 years ago

A fix lib side has not been implemented yet

A workaround is to have all voice logic in a separate worker_thread since they're their own separate v8 instance which you can destroy arbitrarily and all the resources will be freed.

iim-ayush commented 2 years ago

Is there any fix yet?

Yup just uninstall discordjs opus now and start using opusscript.