ytdl-core, node.js, как установить ограничение скорости на скачивания

Рейтинг: 0Ответов: 1Опубликовано: 11.05.2023

Мне необходимо скачивать с youtube видео/музыку и сохранять в файл с ограниченной скоростью, например до 128кб.

Может кто показать на примере этого кода - как реализовать ограничение в скорости скачивания.

const fs = require('fs');
const ytdl = require('ytdl-core');

ytdl('https://youtu.be/dQw4w9WgXcQ', {filter: 'audioonly', quality: 'highestaudio'})
  .pipe(fs.createWriteStream('video.webm'));

В консольном варианте ytdl можно передав аргумент -r, либо --rate-limit ограничить скорость, но как тоже самое реализовать в коде...

Предполагаю, что нужно ограничить скорость записи конкретно модуля fs, но ни одного примера не нашел. (99% плохо искал...)

Ответы

▲ 0

По итогу решение пришлось придумывать через костыль. (Как я считаю.) Изучив документацию потоков nodejs и ytdl-core пришел к такому выводу:

  1. Ограничить буфер потока ytdl до 512кб с помощью highWaterMark: 256 *1024.
  2. Создать пустой записывающий поток. fs.createWriteStream('test.mp4')
  3. Через Interval каждую секунду с помощью yt_stream.read(256 *1024) вытаскивать из потока ytdl по 256кб данных и записывать в другой.

Если кто знает способ проще, то пожалуйста дайте ответ, буду благодарен.

А так вот код, который у меня получился по итогу:

const fs = require('fs');
const ytdl = require('ytdl-core');

const yt_stream = ytdl('https://youtu.be/dQw4w9WgXcQ', {highWaterMark: 256 *1024});
const w_stream = fs.createWriteStream('test.mp4');
let chunk_buf = 0;

yt_stream.on('progress', (a1, a2, a3) => {
  chunk_buf += a1;
  console.log(`buffer: ${chunk_buf /1024} | chunk: ${a1 /1024} kb (${a1} byte) | total: ${ Math.round( a2/1024 ) } kb (${a2} byte) | of ${ Math.round( a3/1048576 ) } mb | progress ${ (100/a3*a2).toFixed(2) }`);
});

const write_interval = setInterval(() => {
  if( !yt_stream.readable )
    return;

  const chunk = yt_stream.read(256 *1024);
  if( !chunk )
    return;

  chunk_buf -= chunk.length;
  w_stream.write(chunk);
  console.log(`writed: ${ chunk.length /1024 } kb | buffer: ${chunk_buf /1024}`);
}, 1000);

yt_stream.on('end', () => {
  clearInterval(write_interval);
  console.log('end');
});