API Reference

Our Live View API empowers you to seamlessly stream real-time video from your cameras, whether locally or over the internet, ensuring you have access to critical footage whenever and wherever you need it.

  • Local Streaming with HLS: Stream high-quality video locally using the HLS (HTTP Live Streaming) protocol. HLS is a widely adopted standard that provides reliable and smooth playback across a broad range of devices and video players. This protocol is optimized for delivering consistent performance, making it ideal for local video streaming needs.
  • Remote Streaming with WebRTC: Access your cameras remotely with near-zero latency using the WebRTC protocol. WebRTC is an industry-standard for real-time communication, enabling instantaneous video streaming over the internet. This feature is crucial for applications where timely access to video feeds is critical, such as security monitoring or live event broadcasting.

This example show you how to get a live video stream from a camera over the Webrtc protocol.

Prerequisites

To use this endpoint, you'll need:

  • A valid Lumana api key.
  • A valid Live View token.
  • A camera id.

Generating a Lumana API key:

There are two options to generate Lumana API key:

  1. In the platform go to: Organizations Settings -> API Keys -> Generate Key.
  2. Via the Lumana API:
$ curl --location 'https://access.lumana.ai/v1/api-key' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "api-key-name",
    "expiresIn": 30,
    "email": "your-email",
    "password": "your-password"
    ,"orgId": "your-org-id"
}'

Generating Lumana Live View token for a camera:

curl --location 'https://access.lumana.ai/v1/live-view/participants' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <Lumana API Key>' \
--data '{
  "cameraId": "camera-id",
  "expiresIn": 300 
}'

Getting camera id

You can get cameraId by using the API or by going to the platform -> Edit camera -> Camera Id

Stream Live from camera:

Once you have the token you should start streaming in the first 3 minutes as otherwise for security reasons the token will be invalided. You can stream the live view from the camera using this player example. Where the Lumana Live View url is https://stream.lumana.ai and the Lumana Live View token is the one generated in the previous step.

A simple example for playing Webrtc can be done with the below html file example:
Enter the Live View Token and connect to the live stream.


<!DOCTYPE html>
<html lang="en">
<script src="https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js"></script>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Live View Video Player</title>
  <style>
    /* General styles */
    body {
      margin: 0;
      font-family: Arial, sans-serif;
      background-color: #121212;
      color: #fff;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      padding: 20px;
      box-sizing: border-box;
    }

    /* Video container */
    #video-container {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 50vh; /* Adjusted height for better fit */
      background-color: #000;
      border-radius: 10px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
      margin-bottom: 50px; /* Increased space between video and controls */
    }

    video {
      width: 80%;
      max-width: 800px;
      border-radius: 10px;
    }

    /* Controls container */
    #controls {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 100%;
      max-width: 620px;
    }

    /* Token input styling */
    #token-input, #url-input {
      width: 100%;
      height: 50px;
      font-size: 18px;
      padding: 10px;
      border-radius: 5px;
      border: 2px solid #333;
      background-color: #1e1e1e;
      color: #fff;
      margin-bottom: 10px; /* Space between input fields */
      box-sizing: border-box;
    }

    /* Connect button styling */
    #connect-btn {
      width: 100%;
      height: 60px;
      font-size: 20px;
      background-color: #007bff;
      color: #fff;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      transition: background-color 0.3s ease;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
      margin-top: 10px; /* Space between button and inputs */
    }

    #connect-btn:hover {
      background-color: #0056b3;
    }
  </style>
    <h1>Live View Player</h1>
</head>
<body>
  <!-- Controls container -->
  <div id="controls">
    <input type="text" id="url-input" value="https://stream.lumana.ai" placeholder="Live View URL">
    <input type="text" id="token-input" placeholder="Live View Token">
    <button id="connect-btn">Connect</button>
  </div>

  <!-- Video container -->
  <div id="video-container">
    <video id="video-player" autoplay playsinline></video>
  </div>
</body>

<script type="module">
    async function connectToLiveView() {
      const liveViewURL = document.getElementById('url-input').value;
      const token = document.getElementById('token-input').value;

      if (!liveViewURL || !token) {
        alert('Please enter both Live View URL and Token');
        return;
      }


      try {
        const room = new LivekitClient.Room({
        // automatically manage subscribed video quality
        adaptiveStream: true,

        // default capture settings
        videoCaptureDefaults: {
            resolution: LivekitClient.VideoPresets.h720.resolution,
        },
        });

        room.prepareConnection(liveViewURL, token);

        // set up event listeners
        room.on(LivekitClient.RoomEvent.TrackSubscribed, handleTrackSubscribed)
            .on(LivekitClient.RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
            .on(LivekitClient.RoomEvent.Disconnected, handleDisconnect)
            .on(LivekitClient.RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished);

        // connect to room
        await room.connect(liveViewURL, token);
        console.log('connected to room', room.name);

        function handleTrackSubscribed(track, publication, participant) {
            console.log('handleTrackSubscribed', track.kind);

        if (track.kind === LivekitClient.Track.Kind.Video) {
            const videoElement = document.getElementById('video-player');
            track.attach(videoElement);
        }
        }

        function handleTrackUnsubscribed(track, publication,participant) {
            track.detach().forEach(element => element.remove());
        }

        function handleLocalTrackUnpublished(publication, participant) {
          // when local tracks are ended, update UI to remove them from rendering
          publication.track.detach();
        }

        function handleDisconnect() {
        console.log('disconnected from room');
        }
      } catch (error) {
        console.error('Error connecting to Live View:', error);
        alert(`Failed to connect ${JSON.stringify({liveViewURL, token}, null, 2)}` );
      }
    }
    document.getElementById('connect-btn').addEventListener('click', connectToLiveView);
  </script>
</body>
</html>