Video Recorder (beta)
Allows you to define Tracks that will be continuously recorded from the video sources you select. The tracks are recorded in segments and these segments are uploaded to the cloud if and when desired. By default all segments are uploaded right away. This can be controlled dynamically on the robot via the API exposed by the capability on the robot described below.
Supports the same video sources as WebRTC Video, incl. v4l cameras, rtsp streams, ROS topics, as well as arbitrary custom gstreamer source pielines.
The capability provides a web UI from where available recordings can be played and reviewed. A calendar UI shows for which days and times recordings are available.
Robot API
The API on the robot is current available via ROS topics as well as a primitive file-based API.
State variables:
keep
: is a number indicating how many seconds back from the current time segments should be uploaded to the cloud. The default is1
which means new segments should be uploaded, but retained past segments should be ignored. Set to0
to indicate no upload at all (until changed), i.e., to indicate that the currently gathered video segments are not interesting enough to upload. These segments will still be available on the robot until the retention period is reached (currently one hour).idle
: indicates whether the robot is currently idle and ready to upload video segments to the cloud. The default istrue
. When set tofalse
, upload will be paused. Any segments that are marked to be kept will be gathered during this time and uploaded once the robot is marked as idle again.paused
: if set totrue
will pause all recordings but without interrupting the shared memory stream potentially used by other processes. Unlike settingkeep
to 0, this will entirely stop recording, i.e., even locally on the robot nothing will be recorded. Example use cases of this is at night or more generally speaking at times when you know the robot isn't doing anything interesting that you may later want to look at.
ROS
To set these values via ROS, simple publish a message to topic
/transitive/video_recorder/KEY
with the appropriate type and value where KEY
is the name of the state variable. For instance, ros2 topic pub --qos-durability volatile /transitive/video_recorder/idle std_msgs/msg/Bool "{data: false}"
would set idle
to false
. Similarly, ros2 topic pub --qos-durability volatile /transitive/video_recorder/keep std_msgs/msg/Int8 "{data: 60}"
would set keep
to 60
.
File-based API
The same values shown above can be set via a simple, file-based API in ~/.transitive/packages/@transitive-robotics/video-recorder/API
. To set a value, simple write a file into that directory with the name of the field and the content of the value. For instance, echo false > ~/.transitive/packages/@transitive-robotics/video-recorder/API/idle
would set idle
to false. Similarly,
echo 60 ~/.transitive/packages/@transitive-robotics/video-recorder/API/keepwould set
keepto
60`.
Front-end (web) API
On the front-end, i.e., in the browser, the capability provides a simple API for getting the available recordings:
async getRecordings({
start: Number, // e.g., 1748908800000
end: Number, // e.g., 1748995200000
})
This will fetch all the recordings between start
and end
, both of which are times specified in milliseconds since the epoch, i.e., like Date.now()
. If the duration between start and end is less than a day, then the result will be a list of recordings for that day. Otherwise the result will be a list of days and the tracks for which there exists recordings on those days.
Example
import { CapabilityContext, CapabilityContextProvider }
from '@transitive-sdk/utils-web';
const ShowRecordings = ({jwt}) => {
const context = useContext(CapabilityContext);
context.getRecordings({start: 1748908800000, end: 1748995200000}).then(console.log);
};
const MyComponent = ({jwt}) =>
<CapabilityContextProvider jwt={jwt}>
<ShowRecordings />
</CapabilityContextProvider>;
Device Sharing
In order to allow other processes to use the input devices used by the video recorder, e.g., for video-streaming or CV processing, the Video Recorder capability "tee"s the stream and exposes the shared stream via shared memory from where it can be consumed by other processes. The file location of the shared memory is /tmp/.transitive-video-recorder/shm/TRACK_NAME
.
Example
For instance, if there is an active video recorder running named "ForwardCamera" then this camera feed could still be used in Transitive's Remote Teleop capability using a custom source pipeline as follows:
<remote-teleop-device id="superbots"
jwt="eyJh...."
count="1"
type="custom"
source="shmsrc is-live=true socket-path=/tmp/.transitive-video-recorder/shm/ForwardCamera.sock do-timestamp=true ! application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)JPEG ! rtpjpegdepay ! jpegdec ! videoconvert"
/>
In the near future we will automatically detect these shared sources in these other capabilities and make them available in the sources menu.
Configuration
You can configure the capability on the robot via the ~/.transitive/config.json
file (see https://transitiverobotics.com/docs/guides/config/) using the fields described below -- values shown are the default being used if not configured.
{
"@transitive-robotics/video-recorder": {
// How long videos are retained on the robot if they are not marked as `keep`,
// in minutes.
"localRetention": 60,
// Initial `keep` value. Set to 0 to discard video segments by default, i.e.,
// unless explicitly requested to be kept by setting to a value of > 0 via
// the Robot API described above.
"keep": 1,
// Initial `idle` value. Set to false to avoid uploading videos to the cloud
// unless later changed to `true` via the Robot API.
"idle": true,
// Initial `paused` value.
"paused": false,
}
}
If you want to access the recordings on the robot directly, you can find them in ~/.transitive/packages/@transitive-robotics/video/record/recordings
.