NorskTransform.videoEncode() method

Encode a video stream to one or more renditions using either software or appropriate hardware if available

Signature:

videoEncode(settings: VideoEncodeSettings): Promise<VideoEncodeNode>;

Parameters

Parameter Type Description

settings

VideoEncodeSettings

Encode ladder settings

Returns:

Promise<VideoEncodeNode>

Example [17_rtmp_to_ladder.ts]

Build an ABR ladder from an RTMP source and publish as HLS and WebRTC

export async function main(): Promise<void> {
  const norsk = await Norsk.connect();
  let rtmpInput = { id: "rtmp", port: 5001 };
  let input = await norsk.input.rtmpServer(rtmpInput);

  let abrLadder = await norsk.processor.transform.videoEncode({ id: "ladder", rungs: ladderRungs });
  let destinations: CMAFDestinationSettings[] = [{ type: "local", retentionPeriodSeconds: 60 }]
  let masterOutput = await norsk.output.cmafMaster({ id: "master", playlistName: "master", destinations });
  let audioOutput = await norsk.output.cmafAudio({ id: "audio", destinations, ...segmentSettings });
  let highOutput = await norsk.output.cmafVideo({ id: "high", destinations, ...segmentSettings });
  let mediumOutput = await norsk.output.cmafVideo({ id: "medium", destinations, ...segmentSettings });
  let lowOutput = await norsk.output.cmafVideo({ id: "low", destinations, ...segmentSettings });

  highOutput.subscribe([{ source: abrLadder, sourceSelector: ladderItem("high") }]);
  mediumOutput.subscribe([{ source: abrLadder, sourceSelector: ladderItem("medium") }]);
  lowOutput.subscribe([{ source: abrLadder, sourceSelector: ladderItem("low") }]);
  audioOutput.subscribe([{ source: input, sourceSelector: selectAudio }]);

  let allVideoAndAudio = [
    { source: abrLadder, sourceSelector: selectAllVideos(ladderRungs.length) },
    { source: input, sourceSelector: selectAudio },
  ];
  masterOutput.subscribe(allVideoAndAudio);

  console.log(`Local player: ${masterOutput.playlistUrl}`);

  let localRtcOutput = await norsk.duplex.webRtcBrowser({ id: "webrtc" });
  localRtcOutput.subscribe(allVideoAndAudio);

  console.log(`Local player: ${localRtcOutput.playerUrl}`);

  abrLadder.subscribe([{ source: input, sourceSelector: selectVideo }]);
}

const segmentSettings = {
  partDurationSeconds: 1.0,
  segmentDurationSeconds: 4.0,
}
const ladderRungs: VideoEncodeRung[] = [
  {
    name: "high",
    width: 1280,
    height: 720,
    frameRate: { frames: 25, seconds: 1 },
    codec: {
      type: "x264",
      bitrateMode: { value: 8000000, mode: "abr" },
      keyFrameIntervalMax: 50,
      keyFrameIntervalMin: 50,
      bframes: 3,
      sceneCut: 0,
      profile: "high",
      level: 4.1,
      preset: "veryfast",
      tune: "zerolatency",
    },
  },
  {
    name: "medium",
    width: 640,
    height: 360,
    frameRate: { frames: 25, seconds: 1 },
    codec: {
      type: "x264",
      bitrateMode: { value: 250000, mode: "abr" },
      keyFrameIntervalMax: 50,
      keyFrameIntervalMin: 50,
      bframes: 0,
      sceneCut: 0,
      tune: "zerolatency",
    },
  },
  {
    name: "low",
    width: 320,
    height: 180,
    frameRate: { frames: 25, seconds: 1 },
    codec: {
      type: "x264",
      bitrateMode: { value: 150000, mode: "abr" },
      keyFrameIntervalMax: 50,
      keyFrameIntervalMin: 50,
      bframes: 0,
      sceneCut: 0,
      tune: "zerolatency",
    },
  },
];

const ladderItem =
  (desiredRendition: string) => (streams: StreamMetadata[]) => {
    const video = videoStreamKeys(streams);
    if (video.length == ladderRungs.length) {
      return video.filter((k) => k.renditionName == desiredRendition);
    }
    return [];
  };

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'

Find Examples