<commit_before>const ytdl = require("ytdl-core");
const Speaker = require("speaker");
const ffmpeg = require("fluent-ffmpeg");
const { EventEmitter } = require("events");
const lame = require("lame");

class Player extends EventEmitter {

    /**
     * A callback handler only accepting an error
     * @callback emptyCallback
     * @param {*} [error]
     */

    /**
     * A simple music player, playing YouTube videos to speakers
     */
    constructor() {
        super();

        /**
         * Music queue of the bot
         * @type {string[]}
         */
        this.queue = [];

        /**
         * Current play status of the player
         * @type {boolean}
         * @private
         */
        this._playing = false;

        /**
         * The currently played song
         * @type {object}
         * @private
         */
        this._currentSong = null;

        /**
         * Current volume
         * @type {number}
         * @private
         */
        this._volume = 0.7;

        /**
         * Contains various streams for playnig audio
         * @type {object}
         * @private
         */
        this._streams = {}

    }

    /**
     * Current play status
     */
    get playing() {
        return this._playing;
    }

    /**
     * Current song
     * @returns {object} Object containing url and name 
     */
    get currentSong() {
        return this._currentSong;
    }

    /**
     * @private
     */
    set currentSong(value) {
        this._currentSong = value;
        this.emit("songChanged", value);
    }

    /**
     * Current volume
     */
    get volume() {
        return this._volume;
    }

    /**
     * Current volume
     */
    set volume(value) {
        this._volume = value;
        if (this._streams.volume)
            this._streams.volume.setVolume(value);
        this.emit("volumeChanged", value);
    }

    /**
     * Add song to queue, currently only accepts YouTube URLs
     * @param {string} url URL to song
     * @param {emptyCallback} callback Called after song got added to the queue callback
     */
    addSong(url, callback) {
        if (true || ytdl.validateLink(url)) {  // Worst fix in history
            this.once("queueChanged", callback);
            ytdl.getInfo(url).then(info => {
                this.queue.push({ name: info.title, url: url, pictureUrl: info.iurlmaxres, description: info.description });
                console.log("Song '" + info.title + "' added to queue");
                this.emit("queueChanged", this.queue);
            });
        }
    }

    /**
     * Start the player
     * @private
     */
    start() {
        if (this._corked) {
            this._streams.speaker.uncork();
            this._corked = false;
            this._playing = true;
            console.log("Player resumed");
            this.emit("resume");
        } else if (this.queue.length > 0 && !this.playing) {
            let song = this.queue.pop();
            this.emit("queueChanged", this.queue);

            this._streams.speaker = new Speaker();
            // Start next song
            this._streams.speaker.on("close", () => {
                if (this.playing) {
                    console.log("Finished song: " + this.currentSong.name);
                    this.emit("finished", this.currentSong);
                    this.next();
                }
            });
            this._streams.speaker.on("error", console.error);

            this._streams.lame = new lame.Decoder();
            this._streams.lame.on("error", console.error);
            this._streams.lame.pipe(this._streams.speaker);

            // Get youtube stream; use ffmpeg to convert to wav format; pipe into speakers
            this._streams.youtube = ytdl(song.url, { quality: "lowest" });

            // -ar 44100 sets output sample rate to 44100 Hz to match Speaker sample rate
            this._streams.ffmpeg = ffmpeg(this._streams.youtube).format("mp3").on("error", console.error).stream();
            this._streams.ffmpeg.pipe(this._streams.lame);

            this._playing = true;
            this.currentSong = song;
            console.log("Playing: " + song.name);
            this.emit("start", song);
        }
    }<commit_msg>Player now plays queue in correct order<commit_after>const ytdl = require("ytdl-core");
const Speaker = require("speaker");
const ffmpeg = require("fluent-ffmpeg");
const { EventEmitter } = require("events");
const lame = require("lame");

class Player extends EventEmitter {

    /**
     * A callback handler only accepting an error
     * @callback emptyCallback
     * @param {*} [error]
     */

    /**
     * A simple music player, playing YouTube videos to speakers
     */
    constructor() {
        super();

        /**
         * Music queue of the bot
         * @type {string[]}
         */
        this.queue = [];

        /**
         * Current play status of the player
         * @type {boolean}
         * @private
         */
        this._playing = false;

        /**
         * The currently played song
         * @type {object}
         * @private
         */
        this._currentSong = null;

        /**
         * Current volume
         * @type {number}
         * @private
         */
        this._volume = 0.7;

        /**
         * Contains various streams for playnig audio
         * @type {object}
         * @private
         */
        this._streams = {}

    }

    /**
     * Current play status
     */
    get playing() {
        return this._playing;
    }

    /**
     * Current song
     * @returns {object} Object containing url and name 
     */
    get currentSong() {
        return this._currentSong;
    }

    /**
     * @private
     */
    set currentSong(value) {
        this._currentSong = value;
        this.emit("songChanged", value);
    }

    /**
     * Current volume
     */
    get volume() {
        return this._volume;
    }

    /**
     * Current volume
     */
    set volume(value) {
        this._volume = value;
        if (this._streams.volume)
            this._streams.volume.setVolume(value);
        this.emit("volumeChanged", value);
    }

    /**
     * Add song to queue, currently only accepts YouTube URLs
     * @param {string} url URL to song
     * @param {emptyCallback} callback Called after song got added to the queue callback
     */
    addSong(url, callback) {
        if (true || ytdl.validateLink(url)) {  // Worst fix in history
            this.once("queueChanged", callback);
            ytdl.getInfo(url).then(info => {
                this.queue.push({ name: info.title, url: url, pictureUrl: info.iurlmaxres, description: info.description });
                console.log("Song '" + info.title + "' added to queue");
                this.emit("queueChanged", this.queue);
            });
        }
    }

    /**
     * Start the player
     * @private
     */
    start() {
        if (this._corked) {
            this._streams.speaker.uncork();
            this._corked = false;
            this._playing = true;
            console.log("Player resumed");
            this.emit("resume");
        } else if (this.queue.length > 0 && !this.playing) {
            let song = this.queue.shift();
            this.emit("queueChanged", this.queue);

            this._streams.speaker = new Speaker();
            // Start next song
            this._streams.speaker.on("close", () => {
                if (this.playing) {
                    console.log("Finished song: " + this.currentSong.name);
                    this.emit("finished", this.currentSong);
                    this.next();
                }
            });
            this._streams.speaker.on("error", console.error);

            this._streams.lame = new lame.Decoder();
            this._streams.lame.on("error", console.error);
            this._streams.lame.pipe(this._streams.speaker);

            // Get youtube stream; use ffmpeg to convert to wav format; pipe into speakers
            this._streams.youtube = ytdl(song.url, { quality: "lowest" });

            // -ar 44100 sets output sample rate to 44100 Hz to match Speaker sample rate
            this._streams.ffmpeg = ffmpeg(this._streams.youtube).format("mp3").on("error", console.error).stream();
            this._streams.ffmpeg.pipe(this._streams.lame);

            this._playing = true;
            this.currentSong = song;
            console.log("Playing: " + song.name);
            this.emit("start", song);
        }
    }
{'fraction_non_alphanumeric': 0.12860830790894157, 'fraction_numerical': 0.0032856137057028865, 'mean_word_length': 1.6184331797235023, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4752176', 'n_tokens_mistral': 2459, 'n_tokens_neox': 2321, 'n_words': 558}