Skip to main content
Version: QTrobot V3

Video

The /qtrobot/media/video/... services and topics play video on the same two lanes used for Audioforeground (FG) and background (BG) — except instead of volume, FG has an alpha (transparency) control and is blended on top of the opaque BG layer. These examples assume the gateway from Connection is already running — see the Python Video tutorial for the full architecture diagram and the reasoning behind the asymmetric BG-opaque/FG-alpha design.

Foreground alpha (transparency)

ros2 service call /qtrobot/media/video/fg/set_alpha qtrobot_interfaces/srv/MediaVideoFgSetAlpha "{value: 1.0}"

# Half-transparent
ros2 service call /qtrobot/media/video/fg/set_alpha qtrobot_interfaces/srv/MediaVideoFgSetAlpha "{value: 0.5}"

There's no separate BG alpha — BG is always the fully-opaque bottom layer.

Play a background video file

A file path must exist on the robot itself (not on your laptop) for these examples to work.

ros2 service call /qtrobot/media/video/bg/file/play qtrobot_interfaces/srv/MediaVideoBgFilePlay \
"{uri: '/home/qtrobot/robot/data/emotions/QT/kiss.avi'}"

Pause and resume

ros2 service call /qtrobot/media/video/bg/file/pause qtrobot_interfaces/srv/MediaVideoBgFilePause "{}"
ros2 service call /qtrobot/media/video/bg/file/resume qtrobot_interfaces/srv/MediaVideoBgFileResume "{}"
ros2 service call /qtrobot/media/video/bg/file/cancel qtrobot_interfaces/srv/MediaVideoBgFileCancel "{}"

Play a video file with its audio track

ros2 service call /qtrobot/media/video/fg/file/play qtrobot_interfaces/srv/MediaVideoFgFilePlay \
"{uri: '/home/qtrobot/robot/data/emotions/QT/happy.avi', with_audio: true}"

with_audio: true routes the video's audio track onto the FG audio lane (see Audio) at the same time the frames play.

Stream raw video

Publish ImageFrameRaw messages directly to a lane's stream topic instead of playing a file — useful for piping in live or generated frames from another ROS2 node, such as the RealSense topics covered in Camera:

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from qtrobot_interfaces.msg import ImageFrameRaw


class VideoStreamer(Node):
def __init__(self):
super().__init__('video_streamer')
self.pub = self.create_publisher(ImageFrameRaw, '/qtrobot/media/video/fg/stream', 10)

def publish_frame(self, width: int, height: int, rgba_bytes: bytes):
msg = ImageFrameRaw(width=width, height=height, encoding='rgba8', data=rgba_bytes)
self.pub.publish(msg)


def main():
rclpy.init()
node = VideoStreamer()
# node.publish_frame(...) for each frame you want to push to the FG lane
node.destroy_node()
rclpy.shutdown()


if __name__ == '__main__':
main()

Like audio, stream frames are dropped on a lane while a file is playing on that same lane.

Next steps

Continue with the Microphone tutorial, or see the full media namespace in the ROS2 API Reference.