> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Play a livestream

> Learn how to use a media player with Livepeer

In this guide, we demonstrate how to play livestreams in your application.

<Warning>
  We do not recommend using ["CORS-enabled" API
  keys](/api-reference/overview/authentication) - they will be deprecated in an
  upcoming release. We recommend making requests from your backend to the
  Livepeer Studio API.
</Warning>

## Using the UI Kit Player

The example below show to use the UI Kit [`Player`](/sdks/react/player/Root) to
play a livestream.

<iframe src="https://lvpr.tv/?v=f5eese9wwl88k4g8" frameborder="0" width="100%" height="410" webkitallowFullScreen mozallowFullScreen allowFullScreen />

### Play Video

This guide assumes you have configured a Livepeer JS SDK client with an API key.
We use the [`Player`](/sdks/react/player/Root) with a `playbackId`, which we
created previously when creating a livestream.

```tsx DemoPlayer.tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import * as Player from "@livepeer/react/player";
import { getSrc } from "@livepeer/react/external";

const playbackId = "f5eese9wwl88k4g8";

// fetch the playback info on the server, using React Server Components
// or regular API routes
export const getPlaybackSource = () => {
  const playbackInfo = await livepeer.playback.get(playbackId);

  const src = getSrc(playbackInfo.playbackInfo);

  return src;
};

export const DemoPlayer = ({ src }: { src: Src[] | null }) => {
  return (
    <Player.Root src={src}>
      <Player.Container>
        <Player.Video title="Live stream" />

        <Player.Controls className="flex items-center justify-center">
          <Player.PlayPauseTrigger className="w-10 h-10">
            <Player.PlayingIndicator asChild matcher={false}>
              <PlayIcon />
            </Player.PlayingIndicator>
            <Player.PlayingIndicator asChild>
              <PauseIcon />
            </Player.PlayingIndicator>
          </Player.PlayPauseTrigger>
        </Player.Controls>
      </Player.Container>
    </Player.Root>
  );
};
```

Check out the [Player docs](/sdks/react/player/Root) for more details on the
video primitives you can use to build custom viewing experiences.

## Using your own player

<Warning>
  Using Livepeer React is the recommended way to play back a livestream - it
  handles WebRTC WHEP playback, fallback to HLS on errors (which may occur with
  WebRTC due to network firewalls, etc), errors from the API, and is composable
  to allow advanced video apps without writing a custom integration. However, if
  you want to use an alternative, you can do so by following the instructions
  below.
</Warning>

### Fetch the playback URL

To play back a livestream in other players, you'll need to fetch the playback
URL(s). By default, all content has an HLS endpoint. HLS is a protocol that
allows you to stream video and audio content over HTTP. Much of the video you
watch on the web is delivered using HLS. Livepeer uses HLS to deliver video and
audio content.

We also support WebRTC WHEP low latency playback - however, ecosystem player
support is limited, as it is a new spec that is rapidly gaining traction.

Below, we show how to fetch playback info in Typescript using the
[playback info API endpoint](/api-reference/playback/get), but we have a similar
interface across all SDKs.

```tsx DemoPlayer.tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import { Player } from "@livepeer/react";
import Livepeer from "livepeer";

const livepeer = new Livepeer({
  apiKey: process.env.YOUR_PRIVATE_API_KEY,
});

const playbackId = "f5eese9wwl88k4g8";

// fetch the playback info on the server
const playbackInfo = await livepeer.playback.get(playbackId);

// use the playbackInfo with your player
```

<Info>
  Please note that to play back livestreams inside your application you'll need
  to use a video player component that supports HLS or WebRTC WHEP.
</Info>

### Handling various playback sources

The playback info endpoint can return multiple sources in the response, as
outlined above.

WebRTC URLs for low latency livestream playback *must* be played back with our
ICE servers, which are used to route traffic in restricted networking
environments. The WebRTC WHEP negotiation will send back these STUN/TURN servers
in the SDP response headers, which can be used in a player.

If there is WebRTC playback available, the API will return a JSON payload
similar to:

```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "type": "live",
  "meta": {
    "live": 0,
    "source": [
      {
        "hrn": "HLS (TS)",
        "type": "html5/application/vnd.apple.mpegurl",
        "url": "https://livepeercdn.studio/hls/{PLAYBACK_ID}/index.m3u8"
      },
      {
        "hrn": "WebRTC (H264)",
        "type": "html5/video/h264",
        "url": "https://livepeercdn.studio/webrtc/{PLAYBACK_ID}"
      },
      {
        "hrn": "Thumbnail (PNG)",
        "type": "image/png",
        "url": "https://storage.lp-playback.studio/{ID}/catalyst-recordings-com/hls/{PLAYBACK_ID}/{ID}/source/latest.png"
      }
    ]
  }
}
```

There are multiple sources you can choose from, and it is up to you to decide
how you want to prioritize each source for your custom player. See the
[Player docs](/sdks/react/player/Root) for more information on how Livepeer UI
Kit Player handles this.

### Use the playback URL in a player

You can use the playback URL with any video player that supports HLS. Here is a
list of popular players that support HLS:

* [Video.js](https://videojs.com/)
* [Plyr.io](https://plyr.io/)
* [JW Player](https://www.jwplayer.com/html5-video-player/)
* [Bitmovin Player](https://bitmovin.com/video-player/)
* [HLS.js](https://github.com/video-dev/hls.js) (requires custom logic to wire
  to a video element)

Here is an example of how to use the playback URL in video.js player.

```html theme={"theme":{"light":"github-light","dark":"dark-plus"}}
<head>
  <link href="https://vjs.zencdn.net/7.20.3/video-js.css" rel="stylesheet" />

  <!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
  <!-- <script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script> -->
</head>

<body>
  <video
    id="my-video"
    class="video-js"
    controls
    preload="auto"
    width="640"
    height="264"
    poster="MY_VIDEO_POSTER.jpg"
  >
    <source
      src="https://lp-playback.com/hls/{PLAYBACK_ID}/index.m3u8"
      type="application/x-mpegURL"
    />
  </video>

  <script src="https://vjs.zencdn.net/7.20.3/video.min.js"></script>
</body>
```

## Embeddable Player

Livepeer Studio maintains an embeddable version of the Livepeer Player that is
suitable for iframing.

<Warning>
  If you are using React, consider using Livepeer UI Kit instead.
</Warning>

This is one of the easiest ways to play back a livestream on your website. You
can embed the player by using the below code snippet.

You can replace the `PLAYBACK_ID` with your video's playback id.

```html theme={"theme":{"light":"github-light","dark":"dark-plus"}}
<iframe
  src="https://lvpr.tv?v={PLAYBACK_ID}"
  allowfullscreen
  allow="autoplay; encrypted-media; fullscreen; picture-in-picture"
  frameborder="0"
>
</iframe>
```

### Low Latency

In the embeddable player, livestreams will, by default, play back with
low-latency WebRTC. If this does not succeed in playing back (rarely, usually
due to a slow network or connectivity issues), the embeddable player will
automatically fall back to HLS playback. Also, if the stream contains B-frames
(or bidirectional frames, which are common for users streaming with OBS or other
streaming apps), the Player will automatically fall back to HLS, so that
out-of-order frames are not displayed. *This only applies to users who are
playing livestreams.*

If you do not want to use WebRTC, you can pass `&lowLatency=false` in the query
string, or if you want *only* low latency, you can pass `&lowLatency=force`.

<Warning>
  OBS users should be instructed to use the Livepeer Studio stream profile, or
  to manually turn off B-frames in their stream. See our [Stream from
  OBS](/developers/guides/stream-via-obs) docs for more information.
</Warning>

### Clipping

To enable clipping, `&clipLength={seconds}` can be passed, which will allow
viewers to clip livestreams. The length in seconds **must be less than 120
seconds**.

### Constant Playback

The embed supports "constant" playback with `constant=true`, which means that
audio will not be distorted if the playhead falls behind the livestream. This is
usually used for music applications, where audio quality/consistency is more
important than latency.

### Other Configs

You can also override the default `muted` and `autoplay` behavior with
`&muted=false` and/or `&autoplay=false`. These are set to true by default.
Looping can also be set with `&loop=true`.

<iframe src="https://lvpr.tv/?v=f5eese9wwl88k4g8" frameborder="0" width="100%" height="410" webkitallowFullScreen mozallowFullScreen allowFullScreen />
