Home/Embeddable video player
Embeddable video player

An embeddable video player that refreshes its own signed links

Drop one script and one element into any page. The player picks HLS or MP4, shows captions, keeps the viewer's place when links are renewed and only plays on the sites you allow. Or paste an iframe and write no code.

Two ways to embed

The web component. <video-piper> is a drop-in player for developers. It plays the HLS stream (with hls.js loaded only where the browser needs it) or the MP4, shows captions, and refreshes its signed links before they expire, keeping the viewer's position. It is one script of about 3 KB gzipped, with no framework.

The iframe. For a page where you'd rather not write code, open a video's menu, choose Embed and copy the code, with options for autoplay (muted), loop, captions on and a start time.

Example

Your server returns the links for a video (it holds the API key, and can cache them per video). The page needs only the script and the element:

// Your server (Node.js): GET /api/videos/:id/links, cached per video
const cache = new Map();
app.get("/api/videos/:id/links", async (req, res) => {
  const hit = cache.get(req.params.id), now = Date.now() / 1000;
  if (hit && hit.playbackExpiresAt - now > 0.2 * hit.ttl) return res.json(hit);
  const r = await fetch(`${API}/videos/${req.params.id}?linkTtl=86400`, { headers: { Authorization: `Bearer ${API_KEY}` } });
  if (!r.ok) return res.status(r.status).end();
  const s = await r.json();
  const links = { playbackUrl: s.playbackUrl, streamUrl: s.streamUrl, posterUrl: s.posterPlaybackUrl,
                  captionsUrl: s.captions?.vttUrl, playbackExpiresAt: s.playbackExpiresAt, ttl: s.playbackExpiresAt - now };
  cache.set(req.params.id, links);
  res.json(links);
});
<script src="https://videopiper.com/player/player.js"></script>

<video-piper links-url="/api/videos/VIDEO_ID/links"></video-piper>

Both snippets come from the documentation, which also has a C# (ASP.NET Core) version of the server code.

Attributes and events

AttributeWhat it does
links-urlYour endpoint for fresh links (JSON, same names as the status).
src, stream-src, posterThe MP4 (playbackUrl), the HLS stream (streamUrl, Pro and Scale, preferred when present) and the poster.
captions, captions-lang, captions-label, ccA WebVTT file for the MP4 (the stream carries its own subtitle track), and cc shows captions from the start.
expires-atUnix time the links expire, so it knows when to refresh.
autoplay, muted, loop, start, controls="false"As for <video>; autoplay also mutes, as browsers require; start is in seconds.

No endpoint? Leave out links-url, listen for the vp-expiring event and call element.setLinks({...}) with fresh links. The element is 16:9 by default and styled like any element (video-piper { width: 100%; }); the inner video is element.video for events like timeupdate and ended.

Control where it plays

Plays count as delivery, like any other playback. See the HLS streaming API for signed links and allowed domains in more detail, or the captions API for subtitle files.

Which plans include the player

The web component and the iframe embed work on every plan, playing the signed MP4 playback link. On Pro and Scale they prefer the adaptive HLS stream when there is one. Embeds from Free-plan accounts show a small brand badge.

PlanPriceProcessing minutesMax qualityEmbeddable player
Free$0/mo30720pIncluded
Starter$49/mo4001080pIncluded
Pro$199/mo1,5004KIncluded
Scale$699/mo6,0004KIncluded

Usage beyond a paid plan is billed at $0.09 per processing minute, $0.15 per GB-month of storage and $0.55 per GB of delivery. Full details are on the pricing page.

In the documentation

Frequently asked questions

How do I add the player to my page?

Load the one script, player.js, and add a video-piper element whose links-url attribute points at your own endpoint. That endpoint returns the video's playbackUrl, streamUrl, poster and caption links. The component calls it again a few minutes before the links expire.

Does the page need my API key?

No. The signed links are the only thing the player needs. Your API key stays on your server, and you decide who your endpoint answers, for example only signed-in users.

Can I embed without writing code?

Yes. Turn on embedding for a video (Embed in the video's menu, or PUT /videos/{id}/embed) and paste the iframe code. Embedding is off until you enable it, and turning it off revokes the code.

How big is the component?

About 3 KB gzipped. It uses a shadow root and native controls with no framework, and loads hls.js only where the browser needs it.

Can other sites reuse my embed?

Once you set allowed domains, browsers only show the player inside your sites, and playback links only play there. Embedding is not DRM.

Start building with Video Piper

Create a free account with just your email, grab an API key and make your first request in minutes.