Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bd73182
Reorganize files
bjsowa Oct 9, 2025
bf4af8e
Clean up include directives by including only what's used
bjsowa Oct 9, 2025
26c1322
Clean up package.xml depend tags
bjsowa Oct 9, 2025
17ea6f6
Load streamer plugins using pluginlib
bjsowa Oct 10, 2025
e5903e0
Move checking for compressed topics to the plugin itself
bjsowa Oct 10, 2025
1da7991
Add snapshot streamer plugins
bjsowa Oct 10, 2025
ec8347c
Add ros_compressed snapshot streamer plugin
bjsowa Oct 10, 2025
72d483e
Detect content type in ros_compressed snapshot streamer
bjsowa Oct 10, 2025
18be8e2
Fix libav streamer factory
bjsowa Oct 10, 2025
90f3ed1
Update listing available topics
bjsowa Oct 10, 2025
3437fee
List snapshot streamers
bjsowa Oct 10, 2025
0e8f668
Add missing includes
bjsowa Oct 10, 2025
c4a90b2
Revise class naming conventions
bjsowa Oct 10, 2025
0e12cc8
Move base classes to web_video_server_streamers library
bjsowa Oct 10, 2025
bd1489b
Reformat for humble
bjsowa Oct 10, 2025
f2467b8
Add some docstrings
bjsowa Oct 12, 2025
1d41e26
Use snake_case for method names
bjsowa Oct 12, 2025
db07bd9
boundry -> boundary
bjsowa Oct 12, 2025
bf22ec0
decodeImage -> decode_image
bjsowa Oct 13, 2025
55a53cb
Move base streamer classes to streamers namespace
bjsowa Oct 18, 2025
7121805
Reduce duplicated code
bjsowa Oct 19, 2025
e9cfad2
Add virtual destructor
bjsowa Oct 19, 2025
f0103d0
Include what you use
bjsowa Oct 19, 2025
463b756
Update copyright headers
bjsowa Oct 19, 2025
c0177a4
Export project dependencies
bjsowa Oct 19, 2025
54bbd89
Add missing copyright header
bjsowa Oct 19, 2025
e2752fb
Pass reference to get_available_topics
bjsowa Oct 19, 2025
7c39972
Remove redundant ImageTransport object
bjsowa Oct 19, 2025
36cbb92
Fix restream frames feature
bjsowa Oct 20, 2025
1c7502c
Pass weak node pointer to streamers to avoid cyclic dependency
bjsowa Oct 20, 2025
79b965f
Fix formatting for humble
bjsowa Oct 20, 2025
dd82d45
Add myself to authors
bjsowa Oct 20, 2025
10607cb
Update README, add custom streamer plugin tutorial
bjsowa Nov 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions AUTHORS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Original Authors
----------------
# Original Authors

* Mitchell Wills (mwills@wpi.edu)
* Mitchell Wills <mwills@wpi.edu>

Contributors
------------
# Contributors

* [Russell Toris](http://users.wpi.edu/~rctoris/) (rctoris@wpi.edu)
* Russell Toris <rctoris@wpi.edu>
* Błażej Sowa <blazej@fictionlab.pl>
78 changes: 58 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ find_package(ament_cmake_ros REQUIRED)
find_package(async_web_server_cpp REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(image_transport REQUIRED)
find_package(pluginlib REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(rmw REQUIRED)
find_package(sensor_msgs REQUIRED)

find_package(OpenCV REQUIRED)
Expand Down Expand Up @@ -39,36 +41,60 @@ if(${cv_bridge_VERSION} VERSION_LESS "3.3.0")
add_compile_definitions(CV_BRIDGE_USES_OLD_HEADERS)
endif()

## Specify additional locations of header files
include_directories(include
${avcodec_INCLUDE_DIRS}
${avformat_INCLUDE_DIRS}
${avutil_INCLUDE_DIRS}
${swscale_INCLUDE_DIRS}
)

## Declare a cpp library
add_library(${PROJECT_NAME} SHARED
src/web_video_server.cpp
src/image_streamer.cpp
src/libav_streamer.cpp
src/vp8_streamer.cpp
src/h264_streamer.cpp
src/vp9_streamer.cpp
src/multipart_stream.cpp
src/ros_compressed_streamer.cpp
src/jpeg_streamers.cpp
src/png_streamers.cpp
src/streamer.cpp
src/utils.cpp
)

target_include_directories(${PROJECT_NAME}
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
)

## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}
PUBLIC
async_web_server_cpp::async_web_server_cpp
pluginlib::pluginlib
rclcpp::rclcpp
rmw::rmw
Boost::boost
PRIVATE
rclcpp_components::component
)

add_library(${PROJECT_NAME}_streamers SHARED
src/streamers/image_transport_streamer.cpp
src/streamers/libav_streamer.cpp
src/streamers/h264_streamer.cpp
src/streamers/jpeg_streamers.cpp
src/streamers/png_streamers.cpp
src/streamers/ros_compressed_streamer.cpp
src/streamers/vp8_streamer.cpp
src/streamers/vp9_streamer.cpp
)

target_include_directories(${PROJECT_NAME}_streamers
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
${avcodec_INCLUDE_DIRS}
${avformat_INCLUDE_DIRS}
${avutil_INCLUDE_DIRS}
${swscale_INCLUDE_DIRS}
)

target_link_libraries(${PROJECT_NAME}_streamers
${PROJECT_NAME}
async_web_server_cpp::async_web_server_cpp
cv_bridge::cv_bridge
image_transport::image_transport
pluginlib::pluginlib
rclcpp::rclcpp
rclcpp_components::component
${sensor_msgs_TARGETS}
Boost::boost
Boost::system
Expand All @@ -90,24 +116,34 @@ target_link_libraries(${PROJECT_NAME}_node

rclcpp_components_register_nodes(${PROJECT_NAME} "web_video_server::WebVideoServer")

pluginlib_export_plugin_description_file(web_video_server plugins.xml)

#############
## Install ##
#############

## Mark executables and/or libraries for installation
install(
DIRECTORY include/
DESTINATION include/${PROJECT_NAME}
)

install(
TARGETS ${PROJECT_NAME}
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_streamers
EXPORT export_${PROJECT_NAME}
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
)
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(
async_web_server_cpp
cv_bridge
image_transport
pluginlib
rclcpp
rmw
sensor_msgs
)

set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
install(
Expand All @@ -132,4 +168,6 @@ if(BUILD_TESTING)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()
ament_package(
CONFIG_EXTRAS "config-extras.cmake"
)
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# web_video_server - HTTP Streaming of ROS Image Topics in Multiple Formats
# web_video_server - HTTP Streaming of ROS Topics in Multiple Formats

This node provides HTTP streaming of ROS image topics in various formats, making it easy to view robot camera feeds and other image topics in a web browser without requiring special plugins or extensions.
This node provides HTTP streaming of ROS topics in various formats, making it easy to view robot camera feeds and other topics in a web browser without requiring special plugins or extensions.

## Features

Expand All @@ -10,10 +10,14 @@ This node provides HTTP streaming of ROS image topics in various formats, making
- VP9 (WebM)
- H264 (MP4)
- PNG streams
- ROS compressed image topics
- ROS compressed image streams
- Query snapshots of image topics in multiple formats:
- JPEG
- PNG
- ROS compressed image
- Plugin-based architecture for easy addition of new streaming formats
- Adjustable quality, size, and other streaming parameters
- Web interface to browse available image topics
- Single image snapshot capability
- Support for different QoS profiles in ROS 2

## Installation
Expand Down Expand Up @@ -109,7 +113,7 @@ http://localhost:8080/
The interface allows quick navigation between different topics and formats without having to manually construct URLs.

This page displays:
- All available ROS image topics currently being published
- All available streamable ROS topics
- Direct links to view each topic in different formats:
- Web page with streaming image
- Direct stream
Expand Down Expand Up @@ -166,19 +170,22 @@ http://localhost:8080/snapshot?topic=/camera/image_raw
| Parameter | Type | Default | Possible Values | Description |
|-----------|------|---------|----------------|-------------|
| `topic` | string | (required) | Any valid ROS image topic | The ROS image topic to stream |
| `type` | string | "jpeg" | "jpeg", "png", "ros_compressed" | Snapshot image format |
| `width` | int | 0 | 0+ | Width of output picture (0 = original width) |
| `height` | int | 0 | 0+ | Height of output picture (0 = original height) |
| `quality` | int | 95 | 1-100 | Quality for JPEG snapshots |
| `invert` | flag | not present | present/not present | Invert image when parameter is present |
| `default_transport` | string | "raw" | "raw", "compressed", "theora" | Image transport to use |
| `qos_profile` | string | "default" | "default", "system_default", "sensor_data", "services_default" | QoS profile for ROS 2 subscribers |

## About
## Creating custom streamer plugins
See the [custom streamer plugin tutorial](doc/custom-streamer-plugin.md) for information on how to write your own streamer plugins.

## About
This project is released as part of the [Robot Web Tools](https://robotwebtools.github.io/) effort.

## License
### License
web_video_server is released with a BSD license. For full terms and conditions, see the [LICENSE](LICENSE) file.

## Authors
### Authors
See the [AUTHORS](AUTHORS.md) file for a full list of contributors.
32 changes: 32 additions & 0 deletions config-extras.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) 2025, The Robot Web Tools Contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# ament_export_dependencies fails to propagate Boost components
# so we need to explicitly find Boost here
find_package(Boost REQUIRED COMPONENTS system)
Loading