> ## Documentation Index
> Fetch the complete documentation index at: https://bunnynet-cb9733c2-nathan-draft-aug-24-2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> Integrate Bunny Stream into your Android apps with the Kotlin SDK - playback, uploads, camera capture, and embed view token authentication.

The Bunny Stream Android SDK lets you quickly integrate the Bunny Stream player, uploads, and video management into your Android applications.

## Key Features

* **Complete API Integration:** Full support for the Bunny REST Stream API
* **Efficient Video Upload:** TUS protocol implementation for reliable, resumable uploads
* **Advanced Video Player:** Custom-built player with full Bunny CDN integration
* **Camera Upload Support:** Built-in capabilities for recording and uploading videos directly from the device camera
* **Type-Safe API:** Fully typed Kotlin API for compile-time safety
* **Background Processing:** Support for background uploads and downloads
* **Comprehensive Error Handling:** Detailed error information and recovery options

## What is the Bunny Stream Android SDK?

Bunny Stream is an Android library designed to seamlessly integrate Bunny's powerful video streaming capabilities into your Android applications. The library provides a robust set of tools for video management, playback, uploading, and camera-based video uploads, all through an intuitive **Kotlin API**.

<Card title="Android SDK" horizontal href="https://github.com/BunnyWay/bunny-stream-android" cta="Hosted on github">
  [https://github.com/BunnyWay/bunny-stream-android](https://github.com/BunnyWay/bunny-stream-android)
</Card>

## Token authentication

When using the Android SDK, **two authentication layers exist**:

* **Embed View Token Authentication** — controls access to the video.
* **CDN Token Authentication** — protects delivery from Bunny CDN and is handled automatically by the SDK.

This section focuses on **Embed View Token Authentication**, which must be handled by a **customer-managed backend or Edge Script** containing custom business logic that decides whether a client is allowed to play back a video by returning an embed view token.

### Embed View Token Authentication

Embed View Token Authentication:

* Authorizes a viewer to play a specific video
* Is enforced at the **Stream API level**
* Is required for private or restricted videos

**Android SDK responsibility**

* The **customer backend generates the token**.
* The app requests the token and passes it to the `PlayVideo` call.
* The SDK uses the token for playback; **CDN token signing happens automatically**.

### Supported authentication methods

| Method                          | Android SDK                    |
| ------------------------------- | ------------------------------ |
| Embed View Token Authentication | Supported via customer backend |
| CDN Token Authentication        | Automatic                      |
| Client-side token signing       | Not supported                  |

<Warning>
  The **Video Library API Key** must **never** be included in your Android app. It is a secret that only your backend or Edge Script should hold.
</Warning>

### Backend requirements

Your backend (or Edge Script) must:

* Securely store the **Video Library API Key**, as it serves as a secret that must not be stored in the mobile app.
* Authenticate the app user with your custom business logic.
* Generate the embed view token by following the [token authentication signing procedure](/docs/stream/token-authentication#signing-procedure) (the token security key is your Video Library API Key).
* Return `token` and `expires` values in the response:

```json theme={null}
{
  "token": "SIGNED_EMBED_VIEW_TOKEN",
  "expires": 1710000000
}
```

<Note>
  Tokens should be **short-lived** (1–5 minutes recommended), unless you have a specific use case that requires a longer expiration.
</Note>

### Edge Script example

Below is an example Edge Script that generates embed view tokens. Store `VIDEO_LIBRARY_API_KEY` as an **Edge Script Secret**.

```typescript theme={null}
BunnySDK.net.http.serve(async (request: Request): Promise<Response> => {
  const url = new URL(request.url);

  const apiKey = BunnySDK.env.VIDEO_LIBRARY_API_KEY;
  const videoId = url.searchParams.get("videoId");
  const expires = Math.floor(Date.now() / 1000) + 300; // 5 minutes or adjust if needed

  if (!videoId) {
    return new Response(JSON.stringify({ error: "Missing videoId" }), {
      status: 400,
      headers: { "Content-Type": "application/json" },
    });
  }

  /*
   * ============================================================
   * Custom authentication / authorization logic
   * ------------------------------------------------------------
   * Perform your business checks here:
   * - Validate user identity (e.g. by using JWT, API key, or some other auth headers)
   * - Verify entitlement to this video
   * - Apply subscription / access rules
   *
   * Only generate a token if access is allowed.
   * ============================================================
   */

  // Example:
  // if (!isUserAuthorized(request, videoId)) {
  //   return new Response(
  //     JSON.stringify({ error: "Unauthorized" }),
  //     { status: 403, headers: { "Content-Type": "application/json" } }
  //   );
  // }

  const token = generateEmbedViewToken(apiKey, videoId, expires);

  return new Response(JSON.stringify({ token, expires }), {
    headers: { "Content-Type": "application/json" },
  });
});

/**
 * Embed View Token generation (per Bunny Stream docs):
 *
 * Token data sequence:
 *   Video Library API Key + videoId + expires
 *
 * Steps:
 * 1. Concatenate the values in the order above (no separators)
 * 2. Generate HMAC-SHA256 using the Video Library API Key
 * 3. Base64 encode: <signature>:<expires>
 */
function generateEmbedViewToken(
  apiKey: string,
  videoId: string,
  expires: number,
): string {
  // @ts-ignore - crypto is available in the Edge runtime
  const crypto = require("crypto");

  const data = apiKey + videoId + expires;
  const signature = crypto
    .createHmac("sha256", apiKey)
    .update(data)
    .digest("hex");

  return Buffer.from(`${signature}:${expires}`).toString("base64");
}
```

### Android SDK usage

The `PlayVideo` call supports token parameters:

```kotlin theme={null}
PlayVideo(
    ...
    videoId = "abc123",
    token = token,
    expires = expires
    ...
)
```

**Flow**

<Steps>
  <Step title="Request the embed token">
    Call your backend or Edge Script from the app to request a token for the target `videoId`.
  </Step>

  <Step title="Receive the token">
    Your backend returns `{ token, expires }`.
  </Step>

  <Step title="Play the video">
    Pass the `token` and `expires` values to the `PlayVideo` call.
  </Step>
</Steps>

## Important notes

* The **Video Library API Key** must **never** be included in mobile apps.
* Embed View Token Authentication is **required** if you don't want to publicly expose your videos.
* CDN Token Authentication is applied to CDN URLs automatically if it is turned on in the video library.
