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

@mango-iiif/av

v0.4.0

Published

Framework-free IIIF audio and video components powered by Media Chrome.

Readme

@mango-iiif/av

Framework-free IIIF audio and video components powered by Media Chrome. The package reads Presentation 2 and Presentation 3 manifests and exposes an all-in-one element, independently placeable components, and a typed controller API. It has no React or Svelte runtime dependency.

Install

npm install @mango-iiif/av

Complete media experience

<mango-av-media> contains the player, chapters, transcript, annotations, metadata, and supplemental files:

import '@mango-iiif/av';
import type { MangoAVMediaElement } from '@mango-iiif/av';

const media = document.querySelector<MangoAVMediaElement>('mango-av-media')!;

media.config = {
  panels: {
    chapters: true,
    transcript: true,
    annotations: true,
    metadata: true,
    supplementalFiles: true,
  },
  controls: {
    navigation: false,
    autoAdvance: false,
    captions: true,
    playbackRate: true,
    pictureInPicture: true,
    fullscreen: true,
  },
  audioArt: {
    title: 'Listen to this recording',
    transcript: true,
    visualizer: 'waveform',
  },
  resume: { enabled: true },
};

media.manifest = 'https://example.org/iiif/manifest.json';

It can also be configured from HTML when only JSON-compatible options are needed:

<mango-av-media
  manifest-url="https://example.org/iiif/manifest.json"
  config='{"panels":{"transcript":true},"autoAdvance":false}'
></mango-av-media>

Independently placeable components

The player, chapters, transcript, and annotations can be placed anywhere in an application. Assign the same AVPlayerController to each element so actions and state changes synchronize across all of them:

<main><mango-av-player></mango-av-player></main>
<aside><mango-av-chapters></mango-av-chapters></aside>
<section><mango-av-transcript></mango-av-transcript></section>
<aside><mango-av-annotations></mango-av-annotations></aside>
import { AVPlayerController } from '@mango-iiif/av/core';
import '@mango-iiif/av/player';
import '@mango-iiif/av/chapters';
import '@mango-iiif/av/transcript';
import '@mango-iiif/av/annotations';
import { type MangoAVPlayerElement } from '@mango-iiif/av/player';
import { type MangoAVChaptersElement } from '@mango-iiif/av/chapters';
import { type MangoAVTranscriptElement } from '@mango-iiif/av/transcript';
import { type MangoAVAnnotationsElement } from '@mango-iiif/av/annotations';

const controller = new AVPlayerController();

document.querySelector<MangoAVPlayerElement>('mango-av-player')!.controller = controller;
document.querySelector<MangoAVChaptersElement>('mango-av-chapters')!.controller = controller;
document.querySelector<MangoAVTranscriptElement>('mango-av-transcript')!.controller = controller;
document.querySelector<MangoAVAnnotationsElement>('mango-av-annotations')!.controller = controller;

await controller.load(manifest);

The controller is an EventTarget. A chapter selection calls selectCanvas, a transcript or annotation selection calls seekTo, and every connected component reacts to the resulting typed controller events. Components do not need a common DOM parent.

Use one <mango-av-player> per controller. Any number of display or interaction components can share that controller, including components rendered in different framework components, panels, or portals.

const unsubscribe = controller.on('av-timeupdate', ({ detail }) => {
  console.log(detail.canvasId, detail.time);
});

Translations

Override any package-owned interface string with the typed, partial strings configuration. Unspecified values keep their English defaults, and the same controller dictionary is used by every connected standalone component:

const controller = new AVPlayerController({
  preferredLanguages: ['cy', 'en', 'none'],
  strings: {
    chapters: 'Penodau',
    transcript: 'Trawsgrifiad',
    previous: 'Blaenorol',
    next: 'Nesaf',
    searchTranscript: 'Chwilio’r trawsgrifiad',
    sourceNumber: 'Ffynhonnell {number}',
    resumePrompt: 'Parhau o {time}?',
  },
});

preferredLanguages chooses localized IIIF labels and sets the Media Chrome language. The package automatically loads Media Chrome's bundled German, Spanish, French, Portuguese, and Chinese dictionaries. strings covers the Mango AV wrapper UI and generated fallback labels for any language. The complete English dictionary is exported as defaultStrings for building and validating translation files.

Svelte

The element works as a normal custom element. The future Mango integration does not need a wrapper library:

<script lang="ts">
  import '@mango-iiif/av';
  import type { AVPlayerConfig } from '@mango-iiif/av';

  const config: AVPlayerConfig = {
    panels: { chapters: true, transcript: true },
  };
</script>

<mango-av-media manifest-url={manifestUrl} .config={config}></mango-av-media>

For Svelte versions that do not accept property syntax in markup, bind the element and assign element.config in an effect.

Controller-only API

Use the controller when an application owns its own UI:

import { AVPlayerController } from '@mango-iiif/av/core';

const controller = new AVPlayerController({ autoAdvance: true });
const manifest = await controller.load(manifestJson);

controller.attachMedia(document.querySelector('video')!);
controller.selectCanvas(manifest.canvases[1].id, { time: 12.5 });
await controller.play();

Styling and themes

The component maps its theme to public CSS custom properties. This gives the host full control of the look without depending on private shadow-DOM selectors:

mango-av-media.tailwind-audio,
mango-av-player.tailwind-audio,
mango-av-chapters.tailwind-audio,
mango-av-transcript.tailwind-audio,
mango-av-annotations.tailwind-audio {
  --mango-av-accent: #0f172a;
  --mango-av-accent-contrast: #f8fafc;
  --mango-av-background: #f8fafc;
  --mango-av-surface: #e2e8f0;
  --mango-av-text: #0f172a;
  --mango-av-border: #cbd5e1;
  --mango-av-radius: 0.875rem;
  --mango-av-font: Inter, ui-sans-serif, system-ui;
  --mango-av-panel-width: 26rem;
}

The audio artwork visualizer follows --mango-av-accent unless it is given --mango-av-visualizer-color, and --mango-av-visualizer-intensity scales how strongly it renders (1 by default, 0 to hide it). See docs/API.md for the full property list.

Media Chrome variables such as --media-primary-color and --media-secondary-color can also be set directly. The complete element provides header, before-player, player-overlay, controls, and after-player slots. The standalone player provides overlay and controls; the information components provide a heading slot.

Run npm run dev to use the interactive configuration builder and the linked composable-components demonstration. They include Video, HLS, and Audio presets, feature switches, generated API configuration, independently positioned components, and multiple style recipes.

Supported IIIF AV behavior

  • Presentation 2 sequences and Presentation 3 Canvas items
  • Audio, video, native HLS, and hls.js-backed HLS through <hls-video>
  • Choice and multiple painting bodies, media source selection, temporal fragments, and clipped playback
  • Multi-Canvas previous/next, start/startCanvas, auto-advance, and repeat
  • Nested Range navigation and temporal chapters
  • Inline and external supplementing annotations
  • Captions, subtitles, audio descriptions, transcript selection, search, download, and synchronized scrolling
  • WebVTT, SRT, plain text, structured JSON, and inline TextualBody transcripts
  • Commenting, supplementing, transcribing, tagging, and highlighting annotations
  • Manifest/Canvas metadata, rights, required statements, homepages, and rendering downloads
  • Placeholder posters, request resolution for protected media, and service metadata normalization
  • Optional persisted playback positions
  • Configurable annotation create/update/delete adapters

See API.md for the complete API and FEATURE_PARITY.md for feature coverage.

Development

npm install
npm run dev
npm run typecheck
npm test
npm run test:e2e
npm run build
npm run pack:check

License

MIT