> ## 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.

# Clip a livestream

> Learn how to create clips from your livestream

## Introduction

You can use Livepeer Studio to create clips of active streams provided via API.
Currently, you can create clips from the most recent N seconds of a given
stream. You may also clip specific sections of a long-running stream, such as a
particular session from a live-streamed conference.

This guide offers a comprehensive walkthrough of the clipping functionality.

<Warning>
  Clipping is currently *only* supported by livestreams and livestream
  recordings. Check back later for further support.
</Warning>

## Create a stream

Follow our previous guide on
[creating a stream](/developers/guides/create-livestream) to get a stream key to
provide to the creator on your platform. They can then start broadcasting to
that stream.

## Create a clip

<Info>
  Clips are created from the perspective of the user who initiates the clip. For
  example, if a viewer clips the most recent 30 seconds, it will be the most
  recent 30 seconds that they saw.
</Info>

Submit a request to the [Create Clip API](/api-reference/stream/create-clip)
using the following request parameters:

<ParamField path="startTime" type="number">
  UNIX timestamp (in milliseconds) of clip's starts from the browser’s playhead
  (commonly supplied by HLS players).
</ParamField>

<ParamField path="endTime" type="number">
  UNIX timestamp (in milliseconds) of clip's end from the browser’s playhead
  (commonly supplied by HLS players).
</ParamField>

<ParamField path="playbackId" type="string">
  Active stream's Playback ID
</ParamField>

<ParamField path="name" type="string">
  (Optional) Output clip's name
</ParamField>

<Info>
  Ensure the `startTime` aligns with or postdates the stream's initiation, and
  that the `endTime` isn't set in the future.
</Info>

### API + Player Integration

If you are using HLS.js, it provides an API for getting the program date time,
`hls.playingDate`, which can be used to get the browser’s current playhead. This
returns a Date object which is used similar to:

<Info>
  HLS players typically provide a `Program-Date-Time` for each segment when
  parsing an HLS manifest. You can utilize `Program-Date-Time` to create a
  clipping user interface (UI) and generate the correct timestamps.
</Info>

```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import Hls from "hls.js";

const hls = new Hls();

// Assuming you have already connected HLS.js to a video element

const endTime = hls.playingDate.getTime(); // This retrieves the current playing date from HLS.js
const startTime = endTime - 30000; // 30 seconds before the endTime in milliseconds

const playbackId = process.env.PLAYBACK_ID_OF_RUNNING_STREAM;

const result = await livepeer.stream.createClip({
  startTime,
  endTime,
  playbackId,
  name: "Your clip name",
});
```

If you are using the Livepeer Player, you use the
[Clip Trigger](/sdks/react/player/Clip), which abstracts this functionality into
an easy-to-use primitive. **You will need to call the Livepeer Clip API from
your backend, and perform sanitization on the user input.**

```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
<Player.ClipTrigger
  onClip={({ playbackId, startTime, endTime }) => {
    // use the start/end time to call the Livepeer API, from your backend
    // e.g. this should be a fetch to your /api/clip endpoint, which then
    // makes a request to Livepeer's Clip endpoint, after validating the
    // input parameters (e.g. clip is less than 60 seconds, etc)
  }}
>
  <ClipIcon />
</Player.ClipTrigger>
```

## Monitor the clip's status

After calling the clip API, Livepeer generates an asset. You'll receive the
asset's details in the response.

```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "task": {
    "id": "635cbcbb-30cb-4136-a7f0-ec5ea2ac39d0"
  },
  "asset": {
    "id": "e28c63c6-ffe8-4f0f-8ae0-4fbbe5c7b493",
    "playbackId": "e28crdyrtxjkx836",
    "userId": "8f175616-1a6d-4481-86f5-7351c041b5ca",
    "createdAt": 1695835443441,
    "status": {
      "phase": "waiting",
      "updatedAt": 1695835443441
    },
    "name": "My Clip",
    "source": {
      "type": "clip",
      "sessionId": "e0d88141-8ade-4274-9039-360245283645"
    },
    "objectStoreId": "9b526cee-bd25-44d2-9fda-f98db3a38a48"
  }
}
```

There are two approaches to track the clip's status:

* **using the `/api/asset/$ASSET_ID` API**

You can poll this endpoint to retrieve the current status of the asset. Keep
polling until the `asset.status` field is `ready`.

* **using webhooks**

If you have configured a webhook in Livepeer to listen for the `asset.ready`
event, you will receive a notification when the clip processing is complete. You
can use the `assetId` received in the previous response to determine when your
clip is ready.

To determine if an asset you are polling or receiving as an event is a clip, you
can check the `source` field. If the `source` field contains a `clip` type and
the relative session ID, then it is indeed a clip.

You can always fetch clips by stream using the
[Clips for Livestream API](/api-reference/stream/get-clip):

```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
const playbackId = process.env.PLAYBACK_ID_OF_RUNNING_STREAM;

const livepeer = new Livepeer({
  apiKey: "your_api_key_here",
});

const id = "08eeeda4-681f-46e5-a760-63d6cac91d91";

await livepeer.stream.getAllClips(id);

// Alternatively, you can use the streamId or fetch the clips
// by session using the /api/session/$sessionId/clips endpoint.
```

<Info>
  Clips offer source playback just like other assets. On completion, a transcode
  job is triggered. Even before this job concludes, the source playback becomes
  available. The `playbackUrl` field in the asset gets populated when the
  playback is ready, and the `sourcePlayback` field is set to true.
</Info>

## Get your clip!

A clip generated in Livepeer is the same as any other Livepeer asset. You are
able to get the playback URLs in your asset object, or fetching them from the
[Playback Info API](/api-reference/playback/get), providing the playbackId of
the output asset representing the clip.
