dgurkaynak / nodeshout

Native libshout bindings for node.js
MIT License
49 stars 19 forks source link

Unable to play next track. #11

Open TheArmagan opened 1 year ago

TheArmagan commented 1 year ago

After streaming one mp3 file, the stream turns itself off. And when I try to play the second file, although the data is sent correctly, I cannot listen to it via icecast.

I am experimenting with this piece of code:

const nodeshout = require("nodeshout");
const fs = require("fs");

nodeshout.init();

// Create a shout instance
const shout = nodeshout.create();

// Configure it
shout.setHost('localhost');
shout.setPort(8000);
shout.setUser('source');
shout.setPassword('hackme');
shout.setMount('source');
shout.setFormat(1); // 0=ogg, 1=mp3
shout.setAudioInfo('bitrate', '320');
shout.setAudioInfo('samplerate', '44100');
shout.setAudioInfo('channels', '2');

console.log(shout.open());

function playFile(fileName, next) {
  fs.open(fileName, 'r', function (status, fd) {
    if (status) {
      console.log(status.message);
      return;
    }

    fs.fstat(fd, function (err, stats) {
      var fileSize = stats.size,
        bufferSize = fileSize,
        chunkSize = 4096,
        bytesRead = 0;

      function read() {
        var buffer = Buffer.alloc(bufferSize);

        if ((bytesRead + chunkSize) > fileSize) {
          chunkSize = (fileSize - bytesRead);
        }

        fs.read(fd, buffer, 0, chunkSize, bytesRead, function (err, bytesRead_, buffer) {
          if (err) {
            console.log(e);
            return;
          }

          bytesRead += bytesRead_;
          console.log(fileName, 'Bytes read:' + bytesRead + ' Total:' + fileSize);

          if (bytesRead_ > 0) {
            console.log(shout.send(buffer, bytesRead_));
            setTimeout(read, Math.abs(shout.delay()));
          } else {
            console.log('Zero bytes read, aborting');
            fs.closeSync(fd);
            setTimeout(next, Math.abs(shout.delay()));
          }
        });
      }

      read();
    });
  });
}

const fileNames = fs.readdirSync("./test-mp3s");
let idx = -1;
function playNext() {
  let n = fileNames[(idx = ((idx + 1) % fileNames.length))];
  console.log(n);
  playFile(`./test-mp3s/${n}`, () => {
    playNext();
  });
}

playNext();
dgurkaynak commented 1 year ago

Hey @TheArmagan, sorry for the late response, I was on vacation. I will look into this today.

dgurkaynak commented 1 year ago

@TheArmagan I think I found the issue. Icecast requires stable bitrate & sample rate for the whole stream. So all of your mp3 files should have the exact bitrate & sample rate. Can you check your mp3 files, you can use ffprobe x.mp3?

TheArmagan commented 1 year ago

Yep they are exactly same bitrate. All of them are 320kbps

dgurkaynak commented 1 year ago

Can you share the output of ffprobe x.mp3 for both the first and the second mp3 files in your test-mp3s folder?

TheArmagan commented 1 year ago

test1.mp3

  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
Input #0, mp3, from 'test1.mp3':
  Metadata:
    encoder         : Lavf58.20.100
  Duration: 00:00:25.50, start: 0.011995, bitrate: 465 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : Lavc59.37
  Stream #0:1: Video: png, rgb24(pc), 640x640 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn (attached pic)
    Metadata:
      title           : Front Cover
      comment         : Cover (front)

test2.mp3

  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
Input #0, mp3, from 'test2.mp3':
  Metadata:
    encoder         : Lavf58.20.100
  Duration: 00:00:25.23, start: 0.025056, bitrate: 469 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : Lavc59.37
  Stream #0:1: Video: png, rgb24(pc), 640x640 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn (attached pic)
    Metadata:
      title           : Front Cover
      comment         : Cover (front)
dgurkaynak commented 1 year ago

I guess their bitrates are different: 465 kb/s vs 469 kb/s. But just one line below, they're both 320 kb/s. I have no idea 😅

Could you try with this two mp3 files: Archive.zip? They're working fine for me.

test1.mp3

ffprobe version 5.1.2 Copyright (c) 2007-2022 the FFmpeg developers
  built with Apple clang version 14.0.0 (clang-1400.0.29.202)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1.2_1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, mp3, from 'test1.mp3':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf58.29.100
  Duration: 00:00:33.02, start: 0.025057, bitrate: 128 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.54

test2.mp3

ffprobe version 5.1.2 Copyright (c) 2007-2022 the FFmpeg developers
  built with Apple clang version 14.0.0 (clang-1400.0.29.202)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1.2_1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, mp3, from 'test2.mp3':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf58.29.100
  Duration: 00:01:00.03, start: 0.025057, bitrate: 128 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.54