npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@byomakase/omakase-tams-player

v1.0.2

Published

Omakase TAMS adapter

Readme

Omakase TAMS Player

Omakase TAMS Player is a TypeScript component that allows native playback of media stored in TAMS. Omakase TAMS Player has the same interface as the vanilla Omakase Player so it can be easily integrated in an existing Omakase Player project.

Omakase TAMS Player can load a source or a flow by URL or can receive flow(s) and flow segments directly.

Omakase TAMS Player implements OmakasePlayerApi but it extends certain functionalities and APIs. No core Omakase Player capabilities have been changed by the Omakase TAMS Player.

| Addition | Explanation | | ----------------------------------------------------------------------------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | loadVideo(videoSource: string, options?: TamsVideoLoadOptions): Observable<TamsVideo | Video> | Accepts a URL of TAMS source or flow resource, if protocol is set in options, media other than TAMS can be loaded (all of the formats supported by Omakase Player). | | loadVideo(videoSource: string[], options?: TamsVideoLoadOptions): Observable<TamsVideo | Video> | Accepts an array of flows. Flows should be time aligned, either part of the same source or different time synchronized sources. Only one video flow is allowed. Multi flows are not allowed in this case. | | loadVideo(videoSource: TamsMediaData, options?: TamsVideoLoadOptions): Observable<TamsVideo | Video> | Allows user to fetch and manage resources and resource segments manually. Omakase Player doesn’t interact with TAMS API in this case, it just fetches provided segments from TAMS storage. | | setTamsEndpoint(endpoint: string) | Sets TAMS endpoint. If not invoked before video load, the endpoint is resolved from the url | | video.getVideo(): TamsVideo | Video | getVideo returns TamsVideo if TAMS flow is loaded | | video.onVideoLoading$(): TamsVideoLoadingEvent | | | video.onVideoLoaded$(): TamsVideoLoadedEvent | | | isTamsLoaded(): boolean; | Returns true if the currently loaded media is sourced from TAMS |

TamsMediaData is an object containing all of the data needed for manually loading a TAMS resource

export type TamsMediaData = {
  flow: Flow;
  subflows?: Flow[];
  flowsSegments: Map<string, FlowSegment[]>;
};

As seen in the TamsMediaData, playback of multiflows is supported as well as the playback of a single (audio or video) flow. Text tracks are also supported with automatic slewing.

TamsVideo is an extended Video interface:

export interface TamsVideo extends Video {
  mediaStartTime: number;
  thumbnailVttTrackUrl?: string;
  tamsMediaData?: TamsMediaData;
  videoUrls?: Map<string, string>;
  audioUrls?: Map<string, string>;
  textUrls?: Map<string, string>;
}
  • mediaStartTime represents the start time of the first main media segment in regards to TAMS timeline. Useful to align segments with Omakase timeline.
  • thumbnailVttTrackUrl represents the URL of the generated thumbnail VTT file if an image flow is found.
  • tamsMediaData represents the flows and segments used to bootstrap the playback. Present if returnTamsMediaData is set to true during video load
  • videoUrls represents a map of created video manifest urls
  • audioUrls represents a map of created audio manifest urls
  • textUrls represents a map of created text manifest urls

TamsVideoLoadOptions is an extended VideoLoadOptions interface:

export interface TamsVideoLoadOptions extends VideoLoadOptions {
  timerange?: string | undefined;
  duration?: number | undefined;
  returnTamsMediaData?: boolean;
  ffomTimeZoneOffset?: number;
}
  • timerange can be used to specify the timerange of flows to be loaded into the player. Overrides duration if both are present.
  • duration can be used to load the requested duration from the flow's end.
  • returnTamsMediaData can be used to return the fetched flows and segments in the TamsVideo object
  • ffomTimeZoneOffset can be used to shift the ffom from UTC to other timezones. The provided value has to be an integer from [-23, 23] range.

If protocol is not provided, the player assumes the provided URL represents a TAMS resource. If neither timerange nor duration is specified, the player will load last 600 seconds of media. TamsVideoLoadingEvent is an extended VideoLoadingEvent interface:

export interface TamsVideoLoadingEvent extends VideoLoadingEvent {
  isTamsLoading?: boolean;
}

TamsVideoLoadedEvent is an extended VideoLoadedEvent interface:

export interface TamsVideoLoadedEvent extends VideoLoadedEvent {
  isTamsLoaded?: boolean;
  video: Video | TamsVideo;
}

Usage

Loading TAMS media by providing resource URL:

let omakasePlayer = new OmakaseTamsPlayer(config);
omakasePlayer
  .loadVideo("https://tams.example/sources/uuid1", videoLoadOptions)
  .subscribe({
    next: (tamsVideo) => {
      console.log(tamsVideo);
    },
  });

Loading TAMS media by providing manually fetched resource:

let omakasePlayer = new OmakaseTamsPlayer(config);
omakasePlayer
  .loadVideo(
    { flow: flow, subflows: subflows, flowsSegments: flowsSegments },
    videoLoadOptions,
  )
  .subscribe({
    next: (tamsVideo) => {
      console.log(tamsVideo);
    },
  });

Loading multiple TAMS flows:

omakasePlayer
  .loadVideo([
    "https://tams.example/flows/uuid1",
    "https://tams.example/flows/uuid2",
    "https://tams.example/flows/uuid3",
    "https://tams.example/flows/uuid4",
  ])
  .subscribe((tamsVideo) => {
    console.log(tamsVideo);
  });

When providing a list of urls, player will assume that the urls represent TAMS flows. If TAMS sources or multiflows are provided the player will return an error. If more than one video flow is provided the player will return an error.

Omakase timeline can be instantiated as follows:

omakasePlayer
  .loadVideo("https://tams.example/flows/uuid")
  .subscribe((tamsVideo) => {
    omakasePlayer
      .createTimeline({
        timelineHTMLElementId: "omakase-timeline",
      })
      .subscribe({
        next: (timelineApi) => {
          if (tamsVideo.thumbnailVttTrackUrl) {
            let thumbnailLane = new omakase.ThumbnailLane({
              description: "Thumbnails",
              vttUrl: tamsVideo.thumbnailVttTrackUrl,
            });

            timelineApi.addTimelineLane(thumbnailLane);
          }

          tamsVideo?.textUrls?.forEach((textUrl, label) => {
            // external function for now - not provided
            fetchAndMergeSubtitlesManifest(textUrl).subscribe((vtt) => {
              const subtitlesLane = new SubtitlesLane({
                vttUrl: vtt,
                description: label,
                style: {
                  paddingTop: 5,
                  paddingBottom: 5,
                  marginBottom: 5,
                },
              });
              timelineApi.addTimelineLane(subtitlesLane);
            });
          });
        },
      });
  });

Setting authentication should usually be done before the video loads or through the OmakaseTamsPlayer's constructor:

omakasePlayer.setAuthentication({
  type: "custom",
  headers: (url) => {
      // Returns empty headers for S3 presigned resources to exclude them from custom authentication
      if (url.includes('X-Amz-Signature') || url.includes('x-amz-signature')) {
          return { headers: {} };
      }
      // Default behavior adds a Bearer access token for TAMS API requests
      return {
          headers: {
              Authorization: `Bearer ${getAccessToken()}`,
          }
      };

      // Any additional resource provider authentication should be handled if Omakase Player
      // is accessing such resources
      
  },
});

Links