@norskvideo/norsk-sdk 1.0.360 → 1.0.363

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ import { HlsTsCombinedPushMessage } from '@norskvideo/norsk-api/lib/media_pb';
18
18
  import { HlsTsMultiVariantMessage } from '@norskvideo/norsk-api/lib/media_pb';
19
19
  import { HlsTsVideoMessage } from '@norskvideo/norsk-api/lib/media_pb';
20
20
  import { Interval as Interval_2 } from '@norskvideo/norsk-api/lib/media_pb';
21
+ import { M3u8MediaInputMessage } from '@norskvideo/norsk-api/lib/media_pb';
21
22
  import { MA35DCard as MA35DCard_2 } from '@norskvideo/norsk-api/lib/media_pb';
22
23
  import { MediaClient as MediaClient_2 } from '@norskvideo/norsk-api/lib/media_grpc_pb';
23
24
  import { Nullable } from 'typescript-nullable';
@@ -1418,10 +1419,27 @@ export declare class DeltacastInputNode extends SourceMediaNode {
1418
1419
  * see: {@link NorskInput.deltaCast}
1419
1420
  */
1420
1421
  export declare interface DeltacastInputSettings extends InputSettings<DeltacastInputNode>, StreamStatisticsMixin {
1421
- /** Which deviceto use */
1422
+ /** Which device to use */
1422
1423
  deviceId: number;
1423
- /** Which card to use */
1424
- cardIndex: number;
1424
+ /** Which channel on the device to use */
1425
+ channelIndex: number;
1426
+ /**
1427
+ * An SDI signal can contain up to 16 (3G) or 32 (6G / 12G) audio channels, which are
1428
+ * transmitted as groups of 4. For example, a single stereo signal would typically be
1429
+ * encoded with the left audio on the first channel of the first group, and the right
1430
+ * audio as the second channel of the first group. The remaining 2 channels on the first
1431
+ * group will contain silence. Deltacast input captures all audio channels that are present
1432
+ * in the signal and returns them as mono streams; the audioBuidMultichannel node can be
1433
+ * used to combine these mono streams into stereo, 5.1 etc.
1434
+ * The audioChannelMask is a bit field that indicates which streams should be returned out
1435
+ * of those present in the signal. Taking the stereo signal example from above, a sensible
1436
+ * mask would be 0x3, indicating that channels 0 and 1 should be returned - thus saving
1437
+ * your code from needing to deal with channels 2 and 3, which you know to just be silent.
1438
+ * If you set a bit that is *not* present in the signal, then no stream will be created -
1439
+ * only streams present in the signal will be returned.
1440
+ * If left undefined, then a default of 0xFFFFFFFF is used - i.e., capture all
1441
+ */
1442
+ audioChannelMask?: number;
1425
1443
  }
1426
1444
 
1427
1445
  /** @public */
@@ -2299,6 +2317,16 @@ export declare type LoganHevcTier = "main" | "high";
2299
2317
  /** @public */
2300
2318
  export declare type LogicalCpuId = number;
2301
2319
 
2320
+ /**
2321
+ * see: {@link NorskInput.m3u8Media}
2322
+ */
2323
+ export declare class M3u8InputNode extends TsCommonInputNode<M3u8MediaInputMessage, M3u8InputNode> {
2324
+ }
2325
+
2326
+ export declare interface M3u8MediaInputSettings extends InputSettings<M3u8InputNode> {
2327
+ url: string;
2328
+ }
2329
+
2302
2330
  /** @public */
2303
2331
  export declare interface MA35DCard {
2304
2332
  index: number;
@@ -2586,6 +2614,10 @@ export declare interface NorskInput {
2586
2614
  * @param settings - Configuration for the WHIP input
2587
2615
  */
2588
2616
  whip(settings: WhipInputSettings): Promise<WhipInputNode>;
2617
+ /**
2618
+ * Pull an m3u8 HLS media stream and output it into Norsk in realtime
2619
+ */
2620
+ m3u8Media(settings: M3u8MediaInputSettings): Promise<M3u8InputNode>;
2589
2621
  /**
2590
2622
  * Read from a Transport Stream on the network
2591
2623
  * This can be multicast/unicast or broadcast
@@ -1,5 +1,5 @@
1
1
  import * as grpc from "@grpc/grpc-js";
2
- import { TsInputEvent, StreamKey as StreamKeyPB, Wave, FileTsInputMessage, UdpTsInputMessage, TimestampProgramNudge, RtmpError_UnsupportedVideo, RtmpError_UnsupportedAudio } from "@norskvideo/norsk-api/lib/media_pb";
2
+ import { TsInputEvent, StreamKey as StreamKeyPB, Wave, FileTsInputMessage, UdpTsInputMessage, M3u8MediaInputMessage, TimestampProgramNudge, RtmpError_UnsupportedVideo, RtmpError_UnsupportedAudio } from "@norskvideo/norsk-api/lib/media_pb";
3
3
  import { BrowserEvent, ChannelLayout, RtmpServerInputStatus, RtpLinearPcmBitDepth, SampleFormat, SampleRate, SrtMode, SrtInputStatus, ImageFormat, IceServerSettings, FrameStoreStreamSelection, FrameStoreCut } from "./types";
4
4
  import { FrameRate } from "../types";
5
5
  import { DeckLinkPixelFormat, DeckLinkVideoConnection, DeckLinkDisplayModeId } from "../types";
@@ -277,10 +277,27 @@ export declare class DeckLinkInputNode extends SourceMediaNode {
277
277
  * see: {@link NorskInput.deltaCast}
278
278
  */
279
279
  export interface DeltacastInputSettings extends InputSettings<DeltacastInputNode>, StreamStatisticsMixin {
280
- /** Which deviceto use */
280
+ /** Which device to use */
281
281
  deviceId: number;
282
- /** Which card to use */
283
- cardIndex: number;
282
+ /** Which channel on the device to use */
283
+ channelIndex: number;
284
+ /**
285
+ * An SDI signal can contain up to 16 (3G) or 32 (6G / 12G) audio channels, which are
286
+ * transmitted as groups of 4. For example, a single stereo signal would typically be
287
+ * encoded with the left audio on the first channel of the first group, and the right
288
+ * audio as the second channel of the first group. The remaining 2 channels on the first
289
+ * group will contain silence. Deltacast input captures all audio channels that are present
290
+ * in the signal and returns them as mono streams; the audioBuidMultichannel node can be
291
+ * used to combine these mono streams into stereo, 5.1 etc.
292
+ * The audioChannelMask is a bit field that indicates which streams should be returned out
293
+ * of those present in the signal. Taking the stereo signal example from above, a sensible
294
+ * mask would be 0x3, indicating that channels 0 and 1 should be returned - thus saving
295
+ * your code from needing to deal with channels 2 and 3, which you know to just be silent.
296
+ * If you set a bit that is *not* present in the signal, then no stream will be created -
297
+ * only streams present in the signal will be returned.
298
+ * If left undefined, then a default of 0xFFFFFFFF is used - i.e., capture all
299
+ */
300
+ audioChannelMask?: number;
284
301
  }
285
302
  /**
286
303
  * @public
@@ -477,6 +494,14 @@ export interface UdpTsInputSettings extends RemoteInputSettings<UdpTsInputNode>
477
494
  */
478
495
  export declare class UdpTsInputNode extends TsCommonInputNode<UdpTsInputMessage, UdpTsInputNode> {
479
496
  }
497
+ export interface M3u8MediaInputSettings extends InputSettings<M3u8InputNode> {
498
+ url: string;
499
+ }
500
+ /**
501
+ * see: {@link NorskInput.m3u8Media}
502
+ */
503
+ export declare class M3u8InputNode extends TsCommonInputNode<M3u8MediaInputMessage, M3u8InputNode> {
504
+ }
480
505
  /**
481
506
  * @public
482
507
  * Settings for a Browser Input
@@ -717,6 +742,10 @@ export interface NorskInput {
717
742
  * @param settings - Configuration for the WHIP input
718
743
  */
719
744
  whip(settings: WhipInputSettings): Promise<WhipInputNode>;
745
+ /**
746
+ * Pull an m3u8 HLS media stream and output it into Norsk in realtime
747
+ */
748
+ m3u8Media(settings: M3u8MediaInputSettings): Promise<M3u8InputNode>;
720
749
  /**
721
750
  * Read from a Transport Stream on the network
722
751
  * This can be multicast/unicast or broadcast
@@ -515,7 +515,8 @@ class DeltacastInputNode extends common_1.SourceMediaNode {
515
515
  : undefined,
516
516
  sourceName: settings.sourceName,
517
517
  deviceId: settings.deviceId,
518
- cardIndex: settings.cardIndex,
518
+ channelIndex: settings.channelIndex,
519
+ audioChannelMask: settings.audioChannelMask ? settings.audioChannelMask : 0xffffffff,
519
520
  statsSampling: settings.statsSampling
520
521
  ? (0, utils_1.provideFull)(media_pb_1.StreamStatisticsSampling, settings.statsSampling)
521
522
  : undefined,
@@ -908,7 +909,6 @@ class UdpTsInputNode extends TsCommonInputNode {
908
909
  }
909
910
  exports.UdpTsInputNode = UdpTsInputNode;
910
911
  /**
911
- * @internal
912
912
  * see: {@link NorskInput.m3u8Media}
913
913
  */
914
914
  class M3u8InputNode extends TsCommonInputNode {
@@ -343,7 +343,7 @@ class CmafNodeWithPlaylist extends CmafNodeBase {
343
343
  // An HLS segmenter can only be subscribed to one stream.
344
344
  const theStream = streams[0];
345
345
  this.subscribedStream = theStream;
346
- const url = this.localDestination ? makePlaylistUrl(theStream, playlistPath, this.localDestination.sessionId) : "";
346
+ const url = this.localDestination ? makePlaylistUrl(theStream, playlistPath, this.localDestination.id, this.localDestination.sessionId) : "";
347
347
  this.pendingUrlRequests.forEach((resolve) => resolve(url));
348
348
  this.pendingUrlRequests = [];
349
349
  }
@@ -362,7 +362,7 @@ class CmafNodeWithPlaylist extends CmafNodeBase {
362
362
  async url() {
363
363
  return (new Promise((resolve, _reject) => {
364
364
  if (this.subscribedStream) {
365
- resolve(this.localDestination ? makePlaylistUrl(this.subscribedStream, this.playlistPath, this.localDestination.sessionId) : "");
365
+ resolve(this.localDestination ? makePlaylistUrl(this.subscribedStream, this.playlistPath, this.localDestination.id, this.localDestination.sessionId) : "");
366
366
  }
367
367
  else {
368
368
  this.pendingUrlRequests.push(resolve);
@@ -527,7 +527,7 @@ function sendPlaylistUpdateTs(destinationId, [playlistAdditions, programDateTime
527
527
  * Returns the *local* url of a playlist
528
528
  * TODO Would be cool if remote locations were supported also
529
529
  */
530
- function makePlaylistUrl(stream, path, sessionId) {
530
+ function makePlaylistUrl(stream, path, id, sessionId) {
531
531
  const theStreamKey = stream.streamKey;
532
532
  let pathPrefix;
533
533
  switch (path) {
@@ -540,7 +540,7 @@ function makePlaylistUrl(stream, path, sessionId) {
540
540
  }
541
541
  const sessionIdPath = sessionId && sessionId !== "" ? sessionId + "/" : "";
542
542
  // TODO Should really come from the server
543
- return `${(0, utils_1.publicUrlPrefix)()}/${pathPrefix}/${sessionIdPath}${theStreamKey?.sourceName}/${theStreamKey?.programNumber}/${theStreamKey?.streamId}/${theStreamKey?.renditionName + "___local"}/norsk.m3u8`; // FIXME this is wrong
543
+ return `${(0, utils_1.publicUrlPrefix)()}/${pathPrefix}/${sessionIdPath}${theStreamKey?.sourceName}/${theStreamKey?.programNumber}/${theStreamKey?.streamId}/${theStreamKey?.renditionName}___${id}/norsk.m3u8`;
544
544
  }
545
545
  // TODO we'll need a Dash URL too?
546
546
  /**
@@ -1395,7 +1395,7 @@ class FrameStoreRecorderNode extends common_1.AutoSinkMediaNode {
1395
1395
  expiryPb = (0, utils_1.provideFull)(media_pb_1.FrameStoreExpiry, { message: (0, utils_1.mkCase)({ bySize: settings.expiry.size }) });
1396
1396
  break;
1397
1397
  case "byTime":
1398
- expiryPb = (0, utils_1.provideFull)(media_pb_1.FrameStoreExpiry, { message: (0, utils_1.mkCase)({ bySize: settings.expiry.durationS }) });
1398
+ expiryPb = (0, utils_1.provideFull)(media_pb_1.FrameStoreExpiry, { message: (0, utils_1.mkCase)({ byDuration: settings.expiry.durationS }) });
1399
1399
  break;
1400
1400
  default:
1401
1401
  (0, utils_1.exhaustiveCheck)(expiryType);
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "license": "MIT",
3
3
  "name": "@norskvideo/norsk-sdk",
4
- "version": "1.0.360",
4
+ "version": "1.0.363",
5
5
  "dependencies": {
6
6
  "@bufbuild/protobuf": "^0.3.0",
7
7
  "@grpc/grpc-js": "^1.2.2",
8
- "@norskvideo/norsk-api": "1.0.360",
8
+ "@norskvideo/norsk-api": "1.0.363",
9
9
  "lodash": "^4.17.21",
10
10
  "typescript-nullable": "^0.6.0"
11
11
  },