> This page is for version 0.1.0.
> For other versions, use one of these documentation indexes:
> - 0.2.0 (Latest) (default): https://docs.nvidia.com/nim/computer-vision/semantic-split/0.2.0/llms.txt
> - 0.1.0: https://docs.nvidia.com/nim/computer-vision/semantic-split/0.1.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nim/computer-vision/semantic-split/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nim/computer-vision/semantic-split/_mcp/server.

# Quickstart Guide

## Downloading the NIM

Download the Semantic Split C-RADIO NIM image with the following command.

```bash
docker pull
gitlab-master.nvidia.com:5005/nim/nim-factory/nv-semantic-split-cradio:24.11-21590864
```

<Note>
The NIM image is 11.81 GB and the download time depends on your internet connection speed.
</Note>

## Prepare External Data Mounts for I/O

The Semantic Split C-RADIO NIM expects data that is local to the machine where the NIM is executing. Hence, the input videos must be locally accessible by the NIM and the output clips will be created in local storage. The user of the NIM is responsible for the management of that data. External data locations can be mounted for reading and writing purposes in the NIM (e.g., inputs can be read from and results will be written to these locations).

This NIM requires mounting at-least three external folders (i.e. folders existing outside of the NIM) at the following three locations inside the NIM:

- `/data`: This location inside the NIM is the root where all input data will be accessed from.
- `/results`: This location inside the NIM is the root where all results will be written to.
- `/opt/nim/cache`: This location inside the NIM is used to store various files needed by the NIM that are downloaded and cached on the first run of the NIM.

## Set the Ownership of Data Mounts

The Semantic Split C-RADIO NIM image uses the user-id `1000`. To make sure the external data mounts for the cache, the data, and the results work properly inside the NIM, you must change the user and group of those folders and then use them for mounting in the docker command. Use the following commands on the host system where the NIM is supposed to launch, before launching it, to set the folder access permissions:

```bash
sudo chown -R 1000:1000 /path/to/data/folder/on/host
sudo chown -R 1000:1000 /path/to/results/folder/on/host
sudo chown -R 1000:1000 /path/to/cache/folder/on/host
```

## Launch the NIM

Use the following command to launch the Semantic Split C-RADIO NIM:

```bash
export NGC_API_KEY=<NGC API Key>
docker run --rm --runtime=nvidia --gpus all --shm-size 2g \
    -p 8000:8000 -e NGC_API_KEY \
    -v <data folder on host machine>:/data \
    -v <results folder on host machine>:/results:rw \
    -v <cache folder on host machine>:/opt/nim/.cache \
    -t gitlab-master.nvidia.com:5005/nim/nim-factory/nv-semantic-split-cradio:24.11-21590864
```

After the NIM is running, you should see an output similar to the following:

```java
"timestamp": "2024-12-12 01:38:15,688", "level": "INFO", "message": "Serving endpoints:
  0.0.0.0:8000/v1/health/live (GET)
  0.0.0.0:8000/v1/health/ready (GET)
  0.0.0.0:8000/v1/metrics (GET)
  0.0.0.0:8000/v1/license (GET)
  0.0.0.0:8000/v1/metadata (GET)
  0.0.0.0:8000/v1/manifest (GET)
  0.0.0.0:8000/video_split (POST)"
"timestamp": "2024-12-12 01:38:15,688", "level": "INFO", "message": "{'message': 'Starting HTTP Inference server', 'port': 8000, 'workers_count': 1, 'host': '0.0.0.0', 'log_level': 'info', 'SSL': 'disabled'}"
```

## Check the NIM’s Health

Leave the current terminal open with the NIM running, open a new terminal, and use the following methods to query the health check end-point. This might take a couple of minutes.

## Invoke By Using cURL

```bash
curl -X 'GET' \
    'http://localhost:8000/v1/health/ready' \
    -H 'accept: application/json'
```

Expected Result if the NIM’s health is good:

```bash
{"description":"Triton readiness check","status":"ready"}
```

## Invoke By Using Python

```python
import requests
r = requests.get("http://localhost:8000/v1/health/ready")
if r.status_code == 200:
    print("NIM is healthy!")
else:
    print("NIM is not ready!")
```

Expected Result if the NIM’s health is good:

```bash
NIM is healthy!
```

## Submit a Video Splitting Request

The endpoint to split videos is `/video_split`, and it takes the following two body parameters:

1. `input_paths` - A list of paths to the raw videos.
    
    1. These paths should be relative to the mount point `/data`
    2. The request must be formatted to the expected input data json format.

2. `results_dir` - a directory inside the NIM that points towards the folder where you want to store the transcoded output videos. This should be relative to the mount point `/results`

This is a blocking synchronous request. Results are only returned after all the videos are processed successfully. If the pipeline fails for any reason, a 500 internal server error message is returned and the NIM must be restarted to receive any further requests. To restart the NIM after a failure, see [Troubleshooting](/nim/computer-vision/semantic-split/0.1.0/troubleshooting).

There is a delay between when the NIM is started, and when it becomes ready to receive video split requests. Before you submit a video split request, check the health of the NIM to ensure that it is ready.

## Invoke By Using cURL

```bash
curl -s -X POST -H 'Content-Type: application/json' http://0.0.0.0:8000/video_split \
--data '{
    "input_paths": [
        "/data/path/to/input1.mp4",
        "/data/path/to/input2.mp4",
        ...
        "/data/path/to/inputN.mp4",
    ],
    "results_dir": "/results"
}'
```

## Script to generate curl request

You can use the following **bash** script to generate a pre-formatted `curl` video splitting request provided that the following is true:

- The data folder on the host machine contains only valid input video files.
- How to call: `generate_json_request.sh <data folder on host machine> | tee json_request.sh`

**generate_request.sh**

```bash
#!/bin/bash

readarray -t video_files < <(ls $1)

echo 'curl -s -X POST -H 'Content-Type: application/json' http://0.0.0.0:8000/video_split \'
echo '--data '"'{"
echo ' "input_paths": ['
for (( i=0; i<${#video_files[@]}-1; i++ )); do
  echo '"/data/'${video_files[i]}'"',
done
echo '"/data/'"${video_files[-1]}"'"'
echo '   ],'
echo '  "results_dir": "/results"'
echo " }' "
```

## Invoke By Using Python

```python
import requests
import json
import time

# Define the URL and the header
url = 'http://0.0.0.0:8000/video_split'
headers = {'Content-Type': 'application/json'}

# Define the data payload
data = { 
"input_paths": [ 
"/data/path/to/input1.mp4", 
"/data/path/to/input2.mp4", 
...,
"/data/path/to/inputN.mp4"
],
"results_dir": "/results/test_1/" 
}

# Convert the data to JSON format
json_data = json.dumps(data)

start_time = time.time()
# Make the POST request
response = requests.post(url, headers=headers, data=json_data)

# Check if the response was successful
if response.status_code == 200:
    # Parse the JSON response
    response_data = response.json()
    # Print the parsed data (or handle it as needed)
    print(response_data)
    end_time = time.time()
    throughput = response_data['total_frames_processed']/(end_time - start_time)
    print(f"Throughput: {throughput:0.2f} FPS")
else:
    print(f"Failed to get a successful response: {response.status_code}")
    print(response.text)
```

For complete documentation of the API specification of the Semantic Split C-Radio NIM, see [API Reference](/nim/computer-vision/semantic-split/0.1.0/api-reference/video-splitting/video-split-post).

## Get Video Splitting Results

After a successful run of the video splitting pipeline, a JSON response consisting of various details about the results is returned. The JSON has the following structure:

1. int: total_frames_processed : a count of all the frames processed in this run so far
2. int: total_output_frames : a count of all the frames in the output clips generated by the pipeline
3. dict: result
    - keys are the path of the video
    - values are a dictionary consisting of
        - int: num_clips
        - list\[dict\]: clip
            - int: clip_span with start and end index
            - str: clip path

```java
{
  "total_frames_processed": 7351,
  "total_output_frames": 2194,
  "results": {
    "/data/path/to/input1.mp4": {
      "num_clips": 5,
      "clips": [
        {
          "span": {
            "start_frame_idx": 82,
            "end_frame_idx": 744
          },
          "path": "/results/test_1/input1_000082_000744.mp4"
        },
        {
          "span": {
            "start_frame_idx": 1530,
            "end_frame_idx": 1931
          },
         "path": "/results/test_1/input1_001530_001931.mp4"
        },
        {
          "span": {
            "start_frame_idx": 2006,
            "end_frame_idx": 2220
          },
          "path": "/results/test_1/input1_002006_002220.mp4"
        }
      ]
    }
  }
}
```