🦄
Bubbaloop
  • 🦄Bubbaloop
  • 🚀Quickstart
  • 💊Stats API
  • 🍰Pipeline API
  • Examples
    • 🌈Hello World
    • 📷Camera Recording
  • 🍄Model Inference (experimental)
  • Tutorials
    • Home Security App
Powered by GitBook
On this page
  • Edit the pipeline file
  • Start the server
  • Start streaming
  • Visualize the streaming
  • Start Recording
  • Stop recording
  • Get the recorded data and Visualize
  1. Examples

Camera Recording

Example showing how to stream data from cameras and log into disk

PreviousHello WorldNextModel Inference (experimental)

Last updated 1 month ago

The Bubbaloop platform includes a cameras pipeline functionality which allows to stream and record data from multi camera streams and serialize in disk including the video frames metadata such as the timestamps.

Edit the pipeline file

In order to customize the recording pipeline we need to follow the steps below, eg to adjust our RTSP streams configuration:

1

Update the pipeline in

Go to an update the config parameter by specifying the path to the pipeline ron file that you want to use for the recording task.

We provide as an example a couple of pipelines to record from one and multiple cameras. See: cameras_1.ron , cameras_2.ron , etc.

#[copper_runtime(config = "src/cu29/pipelines/cameras_1.ron")]
struct CamerasApp {}
2

Customize the pipeline file

You can definitely customize the ron file e.g to update the camera parameters like the source_uri to point to your RTSP camera; or enable disable the broadcasting.

The RTSP url it's expected to be as in the following format

"rtsp://<username>:<password>@<ip>:<port>/<stream>

The channel_id must be a valid usize number and must be not repeated.

These are ron files examples to use with single and multicam with broadcasting included

(
    tasks: [
        (
            id: "cam0",
            type: "crate::cu29::tasks::VideoCapture",
            config: {
                "source_type": "rtsp",
                // URL of the RTSP camera
                // rtsp://<username>:<password>@<ip>:<port>/<stream>
                "source_uri": "rtsp://tapo_entrance:123456789@192.168.1.141:554/stream2",
                "channel_id": 0,
            }
        ),
        (
            id: "enc0",
            type: "crate::cu29::tasks::ImageEncoder",
        ),
        (
            id: "logger",
            type: "crate::cu29::tasks::RerunLoggerOne",
            config: {
                // Path to the directory where the recordings will be stored
                "path": "/tmp/",
            }
        ),
        (
            id: "bcast0",
            type: "crate::cu29::tasks::ImageBroadcast",
        ),
    ],
    cnx: [
        (src: "cam0", dst: "enc0", msg: "crate::cu29::msgs::ImageRgb8Msg"),
        (src: "enc0", dst: "logger", msg: "crate::cu29::msgs::EncodedImage"),
        (src: "enc0", dst: "bcast0", msg: "crate::cu29::msgs::EncodedImage"),
    ]
    ,
    logging: (
        slab_size_mib: 1024, // Preallocates 1GiB of memory map file at a time
        section_size_mib: 100, // Preallocates 100MiB of memory map per section for the main logger.
        enable_task_logging: false,
    ),
)
(
    tasks: [
        (
            id: "cam0",
            type: "crate::cu29::tasks::VideoCapture",
            config: {
                "source_type": "rtsp",
                // URL of the RTSP camera
                // rtsp://<username>:<password>@<ip>:<port>/<stream>
                "source_uri": "rtsp://tapo_entrance:123456789@192.168.1.141:554/stream2",
                "channel_id": 0,
            }
        ),
        (
            id: "cam1",
            type: "crate::cu29::tasks::VideoCapture",
            config: {
                "source_type": "rtsp",
                // URL of the RTSP camera
                // rtsp://<username>:<password>@<ip>:<port>/<stream>
                "source_uri": "rtsp://tapo_terrace:123456789@192.168.1.151:554/stream2",
                "channel_id": 1,
            }
        ),
        (
            id: "enc0",
            type: "crate::cu29::tasks::ImageEncoder",
        ),
        (
            id: "enc1",
            type: "crate::cu29::tasks::ImageEncoder",
        ),
        (
            id: "bcast0",
            type: "crate::cu29::tasks::ImageBroadcast",
        ),
        (
            id: "bcast1",
            type: "crate::cu29::tasks::ImageBroadcast",
        ),
        (
            id: "logger",
            type: "crate::cu29::tasks::RerunLoggerTwo",
            config: {
                // Path to the directory where the logs will be stored
                "path": "/tmp/",
            }
        ),
    ],
    cnx: [
        (src: "cam0", dst: "enc0", msg: "crate::cu29::msgs::ImageRgb8Msg"),
        (src: "cam1", dst: "enc1", msg: "crate::cu29::msgs::ImageRgb8Msg"),
        (src: "enc0", dst: "logger", msg: "crate::cu29::msgs::EncodedImage"),
        (src: "enc1", dst: "logger", msg: "crate::cu29::msgs::EncodedImage"),
        (src: "enc0", dst: "bcast0", msg: "crate::cu29::msgs::EncodedImage"),
        (src: "enc1", dst: "bcast1", msg: "crate::cu29::msgs::EncodedImage"),
    ]
    ,
    logging: (
        slab_size_mib: 1024, // Preallocates 1GiB of memory map file at a time
        section_size_mib: 100, // Preallocates 100MiB of memory map per section for the main logger.
        enable_task_logging: false,
    ),
)
(
    tasks: [
        (
            id: "cam0",
            type: "crate::cu29::tasks::VideoCapture",
            config: {
                "source_type": "v4l2",
                "source_uri": "/dev/video0",
                "source_fps": 30,
                "image_cols": 640,
                "image_rows": 480,
            }
        ),
        (
            id: "rerun",
            type: "crate::cu29::tasks::RerunLogger",
            config: {
                // Path to the directory where the logs will be stored
                "path": "/tmp/",
                // IP address of the rerun server
                "ip": "192.168.1.144",
                // Port of the rerun server
                "port": 9876,
            }
        )
    ],
    cnx: [
        (src: "cam0", dst: "rerun", msg: "crate::cu29::msgs::ImageRgb8Msg"),
    ]
    ,
    logging: (
        slab_size_mib: 1024, // Preallocates 1GiB of memory map file at a time
        section_size_mib: 100, // Preallocates 100MiB of memory map per section for the main logger.
    ),
)

Start the server

just serve
[2025-04-13T12:22:53Z INFO  bubbaloop::api::server] 🚀 Starting the server
[2025-04-13T12:22:53Z INFO  bubbaloop::api::server] 🔥 Listening on: 0.0.0.0:3000
[2025-04-13T12:22:53Z INFO  bubbaloop::api::server] 🔧 Press Ctrl+C to stop the server

Start streaming

just start-pipeline cameras 0.0.0.0 3000
Result: {
  "message": "Pipeline recording started"
}

Visualize the streaming

python examples/python-streaming/client.py \
   --host 0.0.0.0 --port 3000 --cameras 0 # 1 (for multi cam)

Start Recording

Send a request to server to start recording from the cameras

just start-recording 0.0.0.0 30000

Client terminal

Result: {
  "message": "Pipeline recording started"
}

Stop recording

To stop the pipeline, use the stop-pipeline command:

just stop-pipeline recording 0.0.0.0 3000

Client terminal

Result: {
  "message": "Pipeline recording stopped"
}

Server terminal

[2025-04-13T12:10:45Z DEBUG bubbaloop::api::handles::pipeline] Request to stop pipeline: recording
[2025-04-13T12:10:45Z DEBUG bubbaloop::cu29::pipelines::recording] Recording pipeline stopped
[2025-04-13T12:10:45Z DEBUG re_log_encoding::file_sink] Log stream written to /tmp/1744545975.rrd

Get the recorded data and Visualize

You can copy to your home directory (or via ssh) the recorded files into your computer.

scp bubbaloop777:/home/nvidia/1735941642.rrd ~/data

Open the file directly wth rerun to introspect the recording

rerun 1735941642.rrd

Start the camera pipeline and log using .

You can use the example to visualize the streams in real-time using Rerun.

📷
cameras.rs
cameras.rs
rerun.io
python-streaming