Nextjs ytdl stream music with ability to fast forward/rewind

Viewed 16

I've been messing around with ytdl and nextjs lately, I want to play audio from a video but I'm having issues with being able to forward/rewind the audio. I found some posts that helped a bit but still doesn't seem to be working properly. So, I thought I'd open a new post and see if anyone could help me out a bit :)

import ytdl from "ytdl-core";
const toArray = require("stream-to-array");

export default async function handler(req, res) {
  try {
    const stream = ytdl("mzB1VGEGcSU", {
      filter: "audioonly",
      quality: "highestaudio",
    });

    const parts = await toArray(stream);
    const buffers = parts.map((part) =>
      Buffer.isBuffer(part) ? part : Buffer.from(part)
    );
    const compressedBuffer = Buffer.concat(buffers);

    const total = compressedBuffer.length;

    if (stream.headers && stream.headers.range) {
      const range = req.headers.range;
      const parts = range.replace(/bytes=/, "").split("-");
      const partialstart = parts[0];
      const partialend = parts[1];

      const start = parseInt(partialstart, 10);
      const end = partialend ? parseInt(partialend, 10) : total - 1;
      const chunksize = end - start + 1;

      res.writeHead(206, {
        "Content-Range": "bytes " + start + "-" + end + "/" + total,
        "Accept-Ranges": "bytes",
        "Content-Length": chunksize,
        "Content-Type": "audio/mpeg",
      });

      stream.pipe(res);
    } else {
      res.writeHead(200, {
        "Content-Length": total,
        "Content-Type": "audio/mpeg",
      });
      stream.pipe(res);
    }
  } catch (err) {
    console.log(err);
  }
}

Alternative way (doesn't work):

import ytdl from "ytdl-core";
const toArray = require("stream-to-array");

export default async function handler(req, res) {
  try {
    const stream = ytdl("mzB1VGEGcSU", {
      filter: "audioonly",
      quality: "highestaudio",
    });

    const parts = await toArray(stream);
    const buffers = parts.map((part) =>
      Buffer.isBuffer(part) ? part : Buffer.from(part)
    );
    const compressedBuffer = Buffer.concat(buffers);
    const total = compressedBuffer.length;

    res.writeHead(200, {
      "accept-ranges": "bytes",
      "Content-Length": Math.ceil(total / 8),
      "Content-Type": "audio/mpeg",
    });

    stream.pipe(res);
  } catch (err) {
    console.log(err);
  }
}

Temporary solution (Very slow data read):

import ytdl from "ytdl-core";
const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path;
const ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath(ffmpegPath);

export default async function handler(req, res) {
  try {
    const stream = ytdl("mzB1VGEGcSU", {
      filter: "audioonly",
      quality: "highestaudio",
    });

    const newStream = ffmpeg(stream).audioBitrate("128").toFormat("mp3");

    res.writeHead(200, {
      Connection: "keep-alive",
      "Content-Type": "audio/mpeg",
    });

    newStream.pipe(res, {end: true});
  } catch (err) {
    console.log(err);
  }
}

0 Answers
Related