DiscordJS bot using Typescript experiences audio playback issues that halt after a short period of time

I am currently experiencing difficulties with playing audio through a discord bot that I created. The bot is designed to download a song from YouTube using ytdl-core and then play it, but for some reason, the song stops after a few seconds of playing.

Below is my "play.ts" file which contains the play command: (sorry for the messy code, I'm still trying to figure things out.)

import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import { getVoiceConnection, createAudioPlayer, createAudioResource, NoSubscriberBehavior } from '@discordjs/voice';
import { join } from "path";
import ytdl from 'ytdl-core';
import fs from 'fs';

export const data = new SlashCommandBuilder()
    .addStringOption(option =>
        option.setName("link")
            .setDescription("Link to the audio source to be played.")
            .setRequired(true)
    )
    .setName("play")
    .setDescription("Plays audio from given URL.");

export async function execute(interaction: CommandInteraction) {
    if (!interaction.guildId) {
        return interaction.reply("Oops! Something went wrong.");
    }

    const url = interaction.options.getString("link");
    const connection = getVoiceConnection(interaction.guildId);

    if (!connection) {
        return interaction.reply("The bot is not in a voice channel. Please join one before using this command.");
    }

    const audioplayer = createAudioPlayer({
        behaviors: {
            noSubscriber: NoSubscriberBehavior.Pause,
        },
    });

    const download = ytdl(url, { filter: 'audioonly' });
    const writestream = fs.createWriteStream('audio.mp4');
    const pathtoresource = join('audio.mp4');

    download.pipe(writestream);

    const resource = createAudioResource(pathtoresource, {
        inlineVolume: true,
        metadata: {
            title: "SONG",
        },
    });

    audioplayer.play(resource);
    connection.subscribe(audioplayer);

    return interaction.reply(`Playing from: ${url}`);
}

The issue seems to be that sometimes the audio doesn't play at all or only plays for a few seconds. It could be due to the download not completing on time for playback, but I'm unsure how to make it wait for the ytdl download.

Any assistance would be greatly appreciated! (once again, sorry for the messy code, I'm still learning)

EDIT: These are the intents:

const client = new Client({
    intents: ["Guilds", "GuildMessages", "DirectMessages", "GuildVoiceStates"],
});

Answer №1

The current situation you're facing is not related to Discord intents at all. The ytdl-core package was not originally intended to maintain open HTTP connections for extended periods of time. This problem arises when streaming media to a device that processes the data slower than it receives it.

An alternative npm package called play-dl addresses this issue effectively (and even offers support for other streaming platforms, which is an added bonus). You can view its example Discord bot code here to see how it works in action.

In my past Discord bot endeavors, I switched to using play-dl after encountering similar problems with ytdl-core, and things ran much more smoothly. If you require further assistance, feel free to reach out to me through a comment on this post.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Redux repeatedly triggers re-rendering despite the absence of any changes in the state

This is my first venture into React-Redux projects. I was under the impression that React only re-renders when a component's state changes. However, I am currently facing confusion. The component is being re-rendered every 1 to 3 seconds even thoug ...

Exploring Array Iteration: Navigating through Arrays with the .map Method in React and Vue

I am currently using Vue after coming from a React background. In React, there is a method called .map that allows you to render a component multiple times based on the number of items in an array and extract data from each index. Here's an example: f ...

Tips for Automatically Loading Dependencies in AngularJS

Currently, I am working on an Angular application where I am designing various widgets using HTML5. Here is a snippet of the code structure: <html ng-app> <div ng-controller="widget1"> </div> <div ng-controller="widget2"> ...

Attempting to have this .js lightbox appear as soon as the page loads

This Lightbox is absolutely stunning! However, I am looking for a way to automatically trigger the lightbox when the page loads. ...

What is the best way to send the index variable to an HTML element in Angular?

Is there a way to pass the index variable to construct HTML in the append() function? .directive('grid', ['$compile', function(compile) { return { restrict: "E", scope: { elements: '=' ...

Organize routes into distinct modules in Angular 6

Currently grappling with routing in my Angular 6 application. Wondering if the structure I have in mind is feasible. Here's what it looks like: The App module contains the main routing with a parent route defining the layout: const routes: Routes = ...

Oops! An uncaught exception error occurred because the primordials were not defined

I used npm to install the package called aws-s3-zipper, but now I am encountering an error. This is the code snippet causing the issue: AWS = require("aws-sdk"); var S3Zipper = require("aws-s3-zipper"); function zipFolderOnS3() { var zipper = new S3 ...

JS form validation malfunctioning

XHTML <form name="suggestion" method="post" action="suggestion.php" class="elegant-aero" onSubmit="return validate()" > <label> <span>Message :</span> <textarea id="Message" name="m ...

Having trouble with this code// Does anyone know how to make the div slide in line with other divs when hovering over it?

After spending countless hours analyzing and trying various solutions, I have come to the realization that I need to seek help with my code. The task at hand is proving to be incredibly frustrating, and I have exhausted all other options before resorting t ...

Attaching a buoyant div to the precise location of a different element

I have a unordered list (ul) with individual list items (li) that are displayed within a scrollable container. This means that only 8 list items are visible at a time, but you can scroll through them to see the others. Each list item (li) has an "edit" b ...

Is it possible to eliminate additional properties from an object using "as" in Typescript?

I am looking for a way to send an object through JSON that implements an interface, but also contains additional properties that I do not want to include. How can I filter out everything except the interface properties so that only a pure object is sent? ...

Set the class function to be uninitialized

I'm a little unsure of my TypeScript knowledge. I have a class MyClass with a member variable that is a function, but I don't know what this function will be at compile time. I want to allow external code to set this function dynamically during r ...

Utilize a function within an AngularJS directive

I'm struggling to understand how to pass a function (delegate) to a directive in AngularJS and utilize it within the link-function. Any guidance or suggestions on the correct approach would be immensely appreciated. Below is the controller code: myA ...

Sending the value of "username" between two components within Angular 2

I have a good understanding of nesting child components within parent components in Angular 2, but I'm a bit unclear on how to pass a single value from one component to another. In my scenario, I need to pass a username from a login component to a cha ...

Tips for successfully transferring values or parameters within the Bootstrap modal

How can I create a cancel button that triggers a modal asking "Are you sure you want to cancel the task?" and calls a function to make an API call when the user clicks "Ok"? The challenge is each user has a unique ID that needs to be passed to the API for ...

Highlighting Search Results in Kendo TreeView

I am currently working on a KendoTreeview project with spriteclass. My goal is to highlight both the root and child nodes with a specific search term. I have successfully implemented the search functionality, however, there is an issue that arises after th ...

PHP response triggers AJAX autocomplete functionality in JavaScript

The autocomplete hints are not displaying any response for me. Here is the jQuery code that I am using: jQuery( ".newtag_new" ).autocomplete({ minLength: 0, source: function( request, response ) { jQuery.ajax({ type: 'GET ...

JavaScript counter that starts at 1 and increments with each rotation

I am working with an array of image IDs. let images = ['238239', '389943', '989238', ... ]; let max = images.length; The array begins at index 0 and its size may vary. For instance, if there are 5 images in the array, the i ...

Tips on calculating the combined value of price and quantity simultaneously

Greetings, kindly bear with me as my knowledge of JS scripting is quite limited. My expertise lies more in PHP programming. I stumbled upon this neat and straightforward script that calculates the total of product table rows and also provides the grand t ...

Safari-exclusive: Google Maps API dynamically altering page aesthetics post-loading

Recently, I encountered a peculiar problem. Upon loading a page, the text displayed with full opacity. However, upon the Google Maps API loading after 2 seconds, the entire page's styling suddenly changed. It was as if the text on the page became less ...