NorskControl.streamStatistics() method

Record statistical information about media streams, including bitrate, frame rate, and number of keyframes, measured over some configurable sampling windows.

Corresponding settings are found on many input and output nodes.

Signature:

streamStatistics(settings: StreamStatisticsSettings): Promise<StreamStatisticsNode>;

Parameters

Parameter Type Description

settings

StreamStatisticsSettings

Callback and sampling intervals

Returns:

Example [09_rtmp_stream_stats.ts]

Print out audio and video bitrate every 5 seconds.

This demo uses the dedicated StreamStatisticsNode, but other nodes also expose stream stats through the same interface (e.g. NorskInput.rtmpServer)

let sampleIntervalSeconds = 5;
let input_stats = await norsk.processor.control.streamStatistics({
  id: "inputStreamStatistics",
  onStreamStatistics: ({ audio, video, total, allStreams }) => {
    // Stats can be found for each stream individually by stream key
    console.log(`${allStreams.length} streams:`);
    // And aggregated information for audio, video, and total is available
    console.log(`  audio: ${(audio.bitrate/1000).toFixed(1)}kbps`)
    console.log(`  video: ${(video.bitrate/1000).toFixed(1)}kbps`);
  },
  statsSampling: { sampleIntervalsSeconds: [sampleIntervalSeconds] },
});
input_stats.subscribe([{ source: input, sourceSelector: selectAV }]);

Run the following command to generate example input at url rtmp://127.0.0.1:5001/norsk/high:

ffmpeg -v error -re -f lavfi -i "sine=frequency=220:sample_rate=48000" -loop 1 -i data/test-src-still.png -vf drawtext=fontfile=Arial.ttf:text="%{frame_num}":start_number=1:x=980:y=330:fontcolor=black:fontsize=40:box=1:boxcolor=white:boxborderw=5,scale=1280:720 -vcodec h264 -b:v 150000 -b:a 20000 -aspect 1280:720 -x264opts "keyint=25:min-keyint=25:no-scenecut:bframes=0" -bluray-compat true -tune stillimage -preset fast -pix_fmt yuv420p -acodec aac -metadata language=en -f flv 'rtmp://127.0.0.1:5001/norsk/high'

Example [10_bitrate_estimator.ts]

Measure bitrate and set this estimate in the stream metadata

// SRT inputs do not have bitrate information, which is required for HLS
// master playlists.
//
// AAC audio does not need a transcode in this setting, and without a
// transcode (implicit or explicit), there is no bitrate information added.
let srtAacInput = await norsk.input.srt(srtSettings);

// So we sample the stream for 10 seconds to estimate its bitrate and add this
// bitrate to the stream's metadata before subscribing the master playlist to
// the stream.
let streamStarted = false;
let streamStatistics = await norsk.processor.control.streamStatistics({
  id: "inputStreamStatistics",
  statsSampling: {
    // 1s for visualiser updates
    // 5s for console updates
    // 10s for stream bitrate estimation
    sampleIntervalsSeconds: [1, 5, 10],
  },
  onStreamStatistics: async stats => {
    let { audio, video } = stats;
    if (stats.sampleSizeSeconds === 10) {
      if (streamStarted) return;
      streamStarted = true;
      console.log(`+ audio: ${(audio.bitrate / 1000).toFixed(1)}kbps`)
      console.log(`+ video: ${(video.bitrate / 1000).toFixed(1)}kbps`);

      // Use NorskTransform.streamMetadataOverride to add bitrate information
      // to the video and audio streams
      streamMetadataOverride.updateConfig({
        video: {
          bitrate: video.bitrate,
        },
        audio: {
          bitrate: audio.bitrate,
        }
      });

      // And subscribe the master playlist, now that the stream has bitrate
      // metadata
      masterOutput.subscribe([
        { source: streamMetadataOverride, sourceSelector: selectAV },
      ]);
    } else if (stats.sampleSizeSeconds === 5 && streamStarted) {
      console.log(`  audio: ${(audio.bitrate / 1000).toFixed(1)}kbps`)
      console.log(`  video: ${(video.bitrate / 1000).toFixed(1)}kbps`);
    }
  },
});
streamStatistics.subscribe([
  { source: srtAacInput, sourceSelector: selectAV },
]);

let streamMetadataOverride = await norsk.processor.transform.streamMetadataOverride({
  id: "setBitrate",
});
streamMetadataOverride.subscribe([
  { source: srtAacInput, sourceSelector: selectAV },
]);

Run the following command to generate example input at url srt://127.0.0.1:5001:

ffmpeg -v error -re -f lavfi -i "sine=frequency=220:sample_rate=48000" -loop 1 -i data/test-src-still.png -vf drawtext=fontfile=Arial.ttf:text="%{frame_num}":start_number=1:x=980:y=330:fontcolor=black:fontsize=40:box=1:boxcolor=white:boxborderw=5,scale=1280:720 -vcodec h264 -b:v 150000 -b:a 20000 -aspect 1280:720 -x264opts "keyint=25:min-keyint=25:no-scenecut:bframes=0" -bluray-compat true -tune stillimage -preset fast -pix_fmt yuv420p -acodec aac -metadata language=en -f mpegts -flush_packets 0 'srt://127.0.0.1:5001'

Find Examples