├── webrtc_ros ├── web │ ├── .gitignore │ ├── index.html │ ├── viewer.html │ ├── viewer.js │ ├── index.js │ └── webrtc_ros.js ├── .gitignore ├── msg │ └── IceServer.msg ├── srv │ └── GetIceServers.srv ├── src │ ├── webrtc_ros_server_node_test.cpp │ ├── webrtc_ros_server_node.cpp │ ├── webrtc_ros_message.cpp │ ├── webrtc_ros_server_nodelet.cpp │ ├── ros_video_renderer.cpp │ ├── sdp_message.cpp │ ├── ice_candidate_message.cpp │ ├── configure_message.cpp │ ├── webrtc_ros_json_parser.cpp │ ├── image_transport_factory.cpp │ ├── webrtc_ros_server.cpp │ ├── ros_video_capturer.cpp │ ├── webrtc_web_server.cpp │ └── webrtc_client.cpp ├── nodelet_plugins.xml ├── include │ └── webrtc_ros │ │ ├── webrtc_ros_message.h │ │ ├── ros_video_renderer.h │ │ ├── sdp_message.h │ │ ├── ice_candidate_message.h │ │ ├── webrtc_web_server.h │ │ ├── webrtc_ros_server.h │ │ ├── webrtc_ros_json_parser.h │ │ ├── configure_message.h │ │ ├── image_transport_factory.h │ │ ├── ros_video_capturer.h │ │ └── webrtc_client.h ├── package.xml ├── LICENSE_webrtc_adapter ├── launch │ └── webrtc_ros.launch ├── LICENSE ├── scripts │ └── ice_server_service.py ├── CMakeLists.txt └── WEBRTC_ROS_SIGNALING_PROTOCOL.md ├── .gitignore ├── webrtc ├── .gitignore ├── build │ ├── get_depot_tools │ ├── get_ninja │ ├── get_webrtc_source │ ├── get_gn │ ├── prepare_webrtc_build │ ├── update_cmake_config │ └── build_args.txt ├── package.xml └── CMakeLists.txt ├── .dockerignore ├── dockerfiles ├── test-script.sh ├── build_images.sh ├── dev_awsc14 ├── released ├── develop └── README.md ├── AUTHORS.md ├── README.md ├── .travis.yml ├── Dockerfile └── LICENSE /webrtc_ros/web/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt 2 | .vscode/ 3 | -------------------------------------------------------------------------------- /webrtc_ros/.gitignore: -------------------------------------------------------------------------------- 1 | async_web_server_cpp_src/ -------------------------------------------------------------------------------- /webrtc/.gitignore: -------------------------------------------------------------------------------- 1 | /build/depot_tools 2 | /build/webrtc 3 | 4 | -------------------------------------------------------------------------------- /webrtc_ros/msg/IceServer.msg: -------------------------------------------------------------------------------- 1 | string uri 2 | string username 3 | string password 4 | -------------------------------------------------------------------------------- /webrtc_ros/srv/GetIceServers.srv: -------------------------------------------------------------------------------- 1 | ## args 2 | --- 3 | ## Resp 4 | IceServer[] servers 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | webrtc/build/webrtc/ 2 | webrtc/build/depot_tools/ 3 | CMakeLists.txt 4 | .vscode/ -------------------------------------------------------------------------------- /dockerfiles/test-script.sh: -------------------------------------------------------------------------------- 1 | roslaunch video_stream_opencv video_file.launch & 2 | rosrun webrtc_ros webrtc_ros_server_node 3 | -------------------------------------------------------------------------------- /webrtc_ros/src/webrtc_ros_server_node_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /dockerfiles/build_images.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker build -f released -t webrtc_ros/released:latest . 4 | docker build -f develop -t webrtc_ros/develop:latest . 5 | docker build -f dev_awsc14 -t webrtc_ros/dev_awsc14:latest . 6 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Original Authors 2 | ---------------- 3 | 4 | * Mitchell Wills (mwills@wpi.edu) 5 | 6 | Contributors 7 | ------------ 8 | 9 | * [Russell Toris](http://users.wpi.edu/~rctoris/) (rctoris@wpi.edu) 10 | * [Timo Röhling](https://github.com/roehling) (timo.roehling@fkie.fraunhofer.de) 11 | 12 | -------------------------------------------------------------------------------- /webrtc_ros/nodelet_plugins.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A nodelet version of the webrtc_ros/webrtc_ros_server_node node. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /webrtc/build/get_depot_tools: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | run_updates=0 4 | rootdir="$(cd "$(dirname "$0")"; pwd)" 5 | if [ ! -d "$rootdir/depot_tools" ] 6 | then 7 | cd "$rootdir" 8 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 9 | elif [ "$run_updates" -eq 1 ] 10 | then 11 | git -C "$rootdir/depot_tools" pull 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /webrtc_ros/src/webrtc_ros_server_node.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | ros::init(argc, argv, "webrtc_ros_server"); 7 | 8 | ros::NodeHandle nh; 9 | ros::NodeHandle pnh("~"); 10 | 11 | webrtc_ros::WebrtcRosServer server(nh, pnh); 12 | server.run(); 13 | ros::spin(); 14 | server.stop(); 15 | } 16 | -------------------------------------------------------------------------------- /webrtc_ros/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WebRTC ROS 5 | 6 | 7 | 8 | 9 |

WebRTC ROS

10 |

11 |

Camera Topics

12 |
    13 |

    Image Topics

    14 |
      15 | 16 | 17 | -------------------------------------------------------------------------------- /dockerfiles/dev_awsc14: -------------------------------------------------------------------------------- 1 | FROM webrtc_ros/develop 2 | 3 | LABEL description="A docker file to test the develop branch version of webrtc ROS with the fkie-forks/async_web_server_cpp:apache2_websocket_proxy_workaround" 4 | 5 | RUN cd catkin_ws/src && git clone https://github.com/fkie-forks/async_web_server_cpp.git && cd async_web_server_cpp && git checkout apache2_websocket_proxy_workaround 6 | 7 | RUN source "/opt/ros/$ROS_DISTRO/setup.bash" && cd catkin_ws && catkin_make && catkin_make install 8 | -------------------------------------------------------------------------------- /webrtc/build/get_ninja: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | rootdir="$(cd "$(dirname "$0")"; pwd)" 4 | cd "$rootdir" 5 | 6 | if ! "$rootdir/depot_tools/ninja" --version &>/dev/null 7 | then 8 | echo "Prebuilt Ninja build tool is not working, building from source" 9 | if [ ! -d ninja ] 10 | then 11 | git clone -b release https://github.com/ninja-build/ninja.git 12 | fi 13 | cd ninja 14 | python configure.py --bootstrap 15 | cp "$rootdir/ninja/ninja" "$rootdir/depot_tools/ninja" 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /webrtc_ros/web/viewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WebRTC ROS - Viewer 5 | 6 | 7 | 8 | 9 | 10 | 11 |

      WebRTC ROS - Viewer

      12 |

      13 | 14 |

      Back to topic list

      15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /webrtc/build/get_webrtc_source: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | run_updates=0 4 | rootdir="$(cd "$(dirname "$0")"; pwd)" 5 | revision="src@f183d1d9966b312006e395dc4c270639b35d26de" # Chromium M86 6 | export PATH="$rootdir/depot_tools:$PATH" 7 | if [ ! -d "$rootdir/webrtc" ] 8 | then 9 | mkdir -p "$rootdir/webrtc" 10 | cd "$rootdir/webrtc" 11 | fetch --nohooks webrtc 12 | gclient sync --nohooks --revision "$revision" 13 | elif [ "$run_updates" -eq 1 ] 14 | then 15 | cd "$rootdir/webrtc" 16 | gclient sync --nohooks --revision "$revision" 17 | fi 18 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/webrtc_ros_message.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_WEBRTC_ROS_MESSAGE_H_ 2 | #define WEBRTC_ROS_WEBRTC_ROS_MESSAGE_H_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | namespace webrtc_ros 9 | { 10 | 11 | class WebrtcRosMessage 12 | { 13 | public: 14 | static std::string kMessageTypeFieldName; 15 | 16 | static bool isType(const Json::Value& message_json, const std::string& type); 17 | static bool getType(const Json::Value& message_json, std::string* type); 18 | }; 19 | 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /dockerfiles/released: -------------------------------------------------------------------------------- 1 | FROM osrf/ros:melodic-desktop-full 2 | 3 | LABEL description="A docker file to test the released version of webrtc ROS" 4 | 5 | ARG DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update -y && apt-get upgrade -y && apt-get install -y apt-utils 7 | 8 | RUN apt-get install -y ros-melodic-video-stream-opencv wget 9 | RUN wget http://techslides.com/demos/sample-videos/small.mp4 -O /tmp/small.mp4 10 | 11 | COPY test-script.sh test-script.sh 12 | RUN chmod +x test-script.sh 13 | 14 | EXPOSE 8080 15 | 16 | RUN apt-get install -y ros-melodic-webrtc-ros 17 | 18 | CMD ./test-script.sh 19 | -------------------------------------------------------------------------------- /dockerfiles/develop: -------------------------------------------------------------------------------- 1 | FROM webrtc_ros/released 2 | 3 | LABEL description="A docker file to test the develop branch version of webrtc ROS" 4 | 5 | SHELL ["/bin/bash", "-c"] 6 | 7 | RUN mkdir catkin_ws/src -p 8 | RUN cd catkin_ws/src && git clone https://github.com/RobotWebTools/webrtc_ros.git && cd webrtc_ros && git checkout develop 9 | RUN cd catkin_ws/src/webrtc_ros/webrtc && touch CATKIN_IGNORE 10 | RUN source "/opt/ros/$ROS_DISTRO/setup.bash" && cd catkin_ws && catkin_make && catkin_make install 11 | 12 | CMD source "/opt/ros/$ROS_DISTRO/setup.bash" && source "/catkin_ws/install/setup.bash" && ./test-script.sh 13 | -------------------------------------------------------------------------------- /webrtc_ros/src/webrtc_ros_message.cpp: -------------------------------------------------------------------------------- 1 | #include "webrtc_ros/webrtc_ros_message.h" 2 | 3 | namespace webrtc_ros 4 | { 5 | 6 | bool WebrtcRosMessage::isType(const Json::Value& message_json, const std::string& expected_type) 7 | { 8 | std::string type; 9 | if (getType(message_json, &type)) 10 | return expected_type.compare(type) == 0; 11 | return false; 12 | } 13 | 14 | bool WebrtcRosMessage::getType(const Json::Value& message_json, std::string* type) 15 | { 16 | return WebrtcRosJsonParser::GetStringFromJsonObject(message_json, kMessageTypeFieldName, type); 17 | } 18 | 19 | std::string WebrtcRosMessage::kMessageTypeFieldName = "type"; 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/ros_video_renderer.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_ROS_VIDEO_RENDERER_H_ 2 | #define WEBRTC_ROS_ROS_VIDEO_RENDERER_H_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | namespace webrtc_ros 9 | { 10 | 11 | class RosVideoRenderer : 12 | public rtc::VideoSinkInterface 13 | { 14 | public: 15 | RosVideoRenderer(const image_transport::ImageTransport& it, const std::string& topic); 16 | virtual void OnFrame(const webrtc::VideoFrame& frame) override; 17 | 18 | private: 19 | RTC_DISALLOW_COPY_AND_ASSIGN(RosVideoRenderer); 20 | image_transport::ImageTransport it_; 21 | const std::string topic_; 22 | image_transport::Publisher pub_; 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /webrtc_ros/src/webrtc_ros_server_nodelet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace webrtc_ros 9 | { 10 | class WebrtcRosServerNodelet : public nodelet::Nodelet 11 | { 12 | public: 13 | ~WebrtcRosServerNodelet() 14 | { 15 | if(server_) 16 | { 17 | server_->stop(); 18 | } 19 | } 20 | 21 | void onInit() 22 | { 23 | server_.reset(new WebrtcRosServer(getNodeHandle(), getPrivateNodeHandle())); 24 | server_->run(); 25 | } 26 | private: 27 | boost::shared_ptr server_; 28 | }; 29 | 30 | 31 | } 32 | 33 | PLUGINLIB_EXPORT_CLASS(webrtc_ros::WebrtcRosServerNodelet, nodelet::Nodelet); 34 | 35 | -------------------------------------------------------------------------------- /webrtc/build/get_gn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | for PYTHON in python python3 4 | do 5 | if PYTHON=$(type -p $PYTHON) &>/dev/null 6 | then 7 | break 8 | fi 9 | done 10 | if [ ! -x $PYTHON ] 11 | then 12 | echo>&2 "cannot find Python executable" 13 | exit 1 14 | fi 15 | rootdir="$(cd "$(dirname "$0")"; pwd)" 16 | export PATH="${rootdir}/depot_tools:$PATH" 17 | cd "$rootdir/webrtc/src" 18 | 19 | if ! gn --help &>/dev/null 20 | then 21 | mkdir -p third_party/gn 22 | a="$(dpkg-architecture -qDEB_HOST_ARCH || uname -m)" 23 | rm -rf third_party/gn 24 | echo "Building GN from source." 25 | git clone https://gn.googlesource.com/gn third_party/gn 26 | cd third_party/gn 27 | git checkout 501b49a3ab4f0d099457b6e5b62c709a1d2311be 28 | CC=gcc CXX=g++ LDFLAGS=-fuse-ld=gold python build/gen.py 29 | "$rootdir/depot_tools/ninja" -C out gn 30 | cp out/gn . 31 | fi 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | webrtc_ros [![Build Status](https://api.travis-ci.org/RobotWebTools/webrtc_ros.png)](https://travis-ci.org/RobotWebTools/webrtc_ros) 2 | ================ 3 | 4 | #### Streaming of ROS Image Topics using WebRTC 5 | This node provides a WebRTC peer that can be configured to stream a ROS image topic and recieve a stream that is published to a ROS image topic. 6 | The node hosts a webserver that serves a simple test page and offers a websocket server that can be used to create and configure a WebRTC peer. 7 | 8 | For full documentation, see [the ROS wiki](http://wiki.ros.org/webrtc_ros). 9 | 10 | This project is released as part of the [Robot Web Tools](http://robotwebtools.org/) effort. 11 | 12 | ### License 13 | webrtc_ros is released with a BSD license. For full terms and conditions, see the [LICENSE](LICENSE) file. 14 | 15 | ### Authors 16 | See the [AUTHORS](AUTHORS.md) file for a full list of contributors. 17 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/sdp_message.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_SDP_MESSAGE_H_ 2 | #define WEBRTC_ROS_SDP_MESSAGE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | namespace webrtc_ros 10 | { 11 | 12 | class SdpMessage 13 | { 14 | public: 15 | static std::string kSdpFieldName; 16 | static std::string kSdpOfferType; 17 | static std::string kSdpAnswerType; 18 | 19 | static bool isSdpOffer(const Json::Value& message_json); 20 | static bool isSdpAnswer(const Json::Value& message_json); 21 | 22 | bool fromJson(const Json::Value& message_json); 23 | bool fromSessionDescription(const webrtc::SessionDescriptionInterface& description); 24 | 25 | webrtc::SessionDescriptionInterface* createSessionDescription(); 26 | std::string toJson(); 27 | 28 | SdpMessage(); 29 | 30 | std::string type; 31 | std::string sdp; 32 | 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /webrtc/build/prepare_webrtc_build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | rootdir="$(cd "$(dirname "$0")"; pwd)" 4 | export PATH="$rootdir/depot_tools:$PATH" 5 | 6 | a="$(dpkg-architecture -qDEB_BUILD_ARCH || uname -m)" 7 | case "$a" in 8 | i?86) 9 | a=x86 10 | extras="" 11 | ;; 12 | x86_64|amd64) 13 | a=x64 14 | extras="" 15 | ;; 16 | armhf|armv*) 17 | a=arm 18 | extras=" arm_float_abi=\"hard\"" 19 | ;; 20 | arm64|aarch64) 21 | a=arm64 22 | extras="" 23 | ;; 24 | *) 25 | echo>&2 "WARNING: Unknown target platform: $a, continuing anyway" 26 | ;; 27 | esac 28 | cd "$rootdir/webrtc/src" 29 | gn gen "$1" --args="is_debug=false is_clang=false is_desktop_linux=true use_system_libjpeg=true treat_warnings_as_errors=false fatal_linker_warnings=false use_gio=false use_rtti=true rtc_enable_protobuf=false rtc_include_tests=true use_sysroot=false use_custom_libcxx=false rtc_build_json=true symbol_level=0 target_os=\"linux\" host_cpu=\"$a\" current_cpu=\"$a\" target_cpu=\"$a\"$extras" 30 | 31 | -------------------------------------------------------------------------------- /webrtc/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | webrtc 4 | 59.0.4 5 | WebRTC Native API 6 | 7 | Mitchell Wills 8 | Timo Röhling 9 | 10 | BSD 11 | 12 | http://wiki.ros.org/webrtc 13 | https://github.com/RobotWebTools/webrtc_ros/issues 14 | https://github.com/RobotWebTools/webrtc_ros 15 | 16 | git 17 | cmake 18 | wget 19 | gtk2 20 | gtk3 21 | libasound2-dev 22 | libglib-dev 23 | libpulse-dev 24 | 25 | cmake 26 | 27 | 28 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/ice_candidate_message.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_ICE_CANDIDATE_MESSAGE_H_ 2 | #define WEBRTC_ROS_ICE_CANDIDATE_MESSAGE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | namespace webrtc_ros 10 | { 11 | 12 | class IceCandidateMessage 13 | { 14 | public: 15 | static std::string kIceCandidateType; 16 | static std::string kSdpMidFieldName; 17 | static std::string kSdpMlineIndexFieldName; 18 | static std::string kCandidateFieldName; 19 | 20 | static bool isIceCandidate(const Json::Value& message_json); 21 | 22 | bool fromJson(const Json::Value& message_json); 23 | bool fromIceCandidate(const webrtc::IceCandidateInterface& ice_candidate); 24 | 25 | webrtc::IceCandidateInterface* createIceCandidate(); 26 | std::string toJson(); 27 | 28 | IceCandidateMessage(); 29 | 30 | std::string sdp_mid; 31 | int sdp_mline_index; 32 | std::string candidate; 33 | 34 | }; 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/webrtc_web_server.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_WEBRTC_WEB_SERVER_H_ 2 | #define WEBRTC_ROS_WEBRTC_WEB_SERVER_H_ 3 | 4 | #include 5 | 6 | namespace webrtc_ros 7 | { 8 | 9 | class SignalingChannel { 10 | public: 11 | virtual ~SignalingChannel(); 12 | virtual void sendPingMessage() = 0; 13 | virtual void sendTextMessage(const std::string& message) = 0; 14 | }; 15 | 16 | class MessageHandler { 17 | public: 18 | enum Type { 19 | TEXT, PONG, CLOSE 20 | }; 21 | 22 | MessageHandler(); 23 | virtual ~MessageHandler(); 24 | 25 | virtual void handle_message(Type type, const std::string& raw) = 0; 26 | }; 27 | 28 | typedef MessageHandler* (*SignalingChannelCallback)(void*, SignalingChannel*); 29 | 30 | class WebrtcWebServer { 31 | public: 32 | static WebrtcWebServer* create(int port, SignalingChannelCallback callback, void* data); 33 | 34 | WebrtcWebServer(); 35 | virtual ~WebrtcWebServer(); 36 | 37 | virtual void run() = 0; 38 | virtual void stop() = 0; 39 | }; 40 | 41 | } 42 | 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | compiler: gcc 3 | matrix: 4 | include: 5 | - name: 'ROS Kinetic' 6 | dist: xenial 7 | env: CI_UBUNTU=xenial CI_ROS_DISTRO=kinetic 8 | - name: 'ROS Melodic' 9 | dist: bionic 10 | env: CI_UBUNTU=bionic CI_ROS_DISTRO=melodic 11 | 12 | branches: 13 | only: 14 | - develop 15 | 16 | before_install: 17 | - echo "deb http://packages.ros.org/ros/ubuntu ${CI_UBUNTU} main" | sudo tee -a /etc/apt/sources.list 18 | - curl http://packages.ros.org/ros.key | sudo apt-key add - 19 | - sudo apt-get update -qq 20 | - sudo apt-get install -qq dpkg python-catkin-lint python-catkin-tools python-rosdep 21 | 22 | install: 23 | - sudo rosdep init 24 | - rosdep update 25 | - mkdir -p /tmp/ws/src 26 | - ln -s `pwd` /tmp/ws/src/webrtc 27 | - rosdep install -q --from-paths /tmp/ws/src --ignore-src --rosdistro ${CI_ROS_DISTRO} -y 28 | 29 | before_script: 30 | - source /opt/ros/${CI_ROS_DISTRO}/setup.bash 31 | - catkin config -w /tmp/ws --install 32 | 33 | script: 34 | - catkin_lint /tmp/ws/src/webrtc 35 | - catkin build -w /tmp/ws -p1 -j2 --no-status -i 36 | 37 | -------------------------------------------------------------------------------- /webrtc_ros/src/ros_video_renderer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace webrtc_ros 7 | { 8 | 9 | RosVideoRenderer::RosVideoRenderer(const image_transport::ImageTransport& it, const std::string& topic) 10 | : it_(it), topic_(topic) 11 | { 12 | pub_ = it_.advertise(topic_, 1); 13 | } 14 | 15 | void RosVideoRenderer::OnFrame(const webrtc::VideoFrame& frame) 16 | { 17 | std_msgs::Header header; 18 | header.stamp = ros::Time::now(); 19 | const rtc::scoped_refptr& buffer = frame.video_frame_buffer()->ToI420(); 20 | 21 | cv::Mat bgra(buffer->height(), buffer->width(), CV_8UC4); 22 | // The ARGB function in libyuv appears to output BGRA... 23 | libyuv::I420ToARGB(buffer->DataY(), buffer->StrideY(), 24 | buffer->DataU(), buffer->StrideU(), 25 | buffer->DataV(), buffer->StrideV(), 26 | bgra.data, bgra.step, buffer->width(), buffer->height()); 27 | 28 | cv_bridge::CvImage image(header, "bgra8", bgra); 29 | pub_.publish(image.toImageMsg()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/webrtc_ros_server.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_WEBRTC_ROS_SERVER_H_ 2 | #define WEBRTC_ROS_WEBRTC_ROS_SERVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace webrtc_ros 11 | { 12 | 13 | MessageHandler* WebrtcRosServer_handle_new_signaling_channel(void* _this, SignalingChannel *channel); 14 | 15 | class WebrtcRosServer 16 | { 17 | public: 18 | WebrtcRosServer(ros::NodeHandle& nh, ros::NodeHandle& pnh); 19 | ~WebrtcRosServer(); 20 | void run(); 21 | void stop(); 22 | 23 | MessageHandler* handle_new_signaling_channel(SignalingChannel *channel); 24 | void cleanupWebrtcClient(WebrtcClient *client); 25 | 26 | std::unique_ptrsignaling_thread_; 27 | private: 28 | 29 | std::condition_variable shutdown_cv_; 30 | std::mutex clients_mutex_; 31 | std::map clients_; 32 | 33 | ros::NodeHandle nh_; 34 | ros::NodeHandle pnh_; 35 | std::string image_transport_; 36 | ImageTransportFactory itf_; 37 | 38 | boost::shared_ptr server_; 39 | }; 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /webrtc_ros/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | webrtc_ros 4 | 59.0.4 5 | A collection of ROS utilities for using WebRTC with ROS 6 | 7 | Mitchell Wills 8 | Timo Röhling 9 | 10 | BSD 11 | 12 | http://wiki.ros.org/webrtc_ros 13 | https://github.com/RobotWebTools/webrtc_ros/issues 14 | https://github.com/RobotWebTools/webrtc_ros 15 | 16 | catkin 17 | 18 | cv_bridge 19 | roscpp 20 | webrtc 21 | image_transport 22 | nodelet 23 | std_msgs 24 | async_web_server_cpp 25 | 26 | message_generation 27 | message_runtime 28 | message_runtime 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/webrtc_ros_json_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_JSON_PARSER_H_ 2 | #define WEBRTC_ROS_JSON_PARSER_H_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | namespace webrtc_ros 9 | { 10 | 11 | class WebrtcRosJsonParser 12 | { 13 | public: 14 | static bool getType(const Json::Value& message_json, std::string* type); 15 | 16 | static bool GetStringFromJsonObject(const Json::Value& in, 17 | const std::string& k, 18 | std::string* out); 19 | 20 | static bool GetValueFromJsonObject(const Json::Value& in, 21 | const std::string& k, 22 | Json::Value* out); 23 | static bool GetStringFromJson(const Json::Value& in, std::string* out); 24 | 25 | static bool GetIntFromJson(const Json::Value& in, int* out); 26 | static bool GetIntFromJsonObject(const Json::Value& in, 27 | const std::string& k, 28 | int* out); 29 | static std::string ToString(const bool b); 30 | static std::string ToString(const double b); 31 | static std::string ToString(const int b); 32 | static std::string ToString(const unsigned int b); 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /webrtc_ros/include/webrtc_ros/configure_message.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBRTC_ROS_CONFIGURE_MESSAGE_H_ 2 | #define WEBRTC_ROS_CONFIGURE_MESSAGE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | namespace webrtc_ros 10 | { 11 | 12 | struct ConfigureAction 13 | { 14 | bool fromJson(const Json::Value& action_json); 15 | void toJson(Json::Value* action_json) const; 16 | 17 | std::string type; 18 | std::map properties; 19 | 20 | static std::string kTypeFieldName; 21 | 22 | static std::string kAddStreamActionName; 23 | static std::string kRemoveStreamActionName; 24 | static std::string kAddVideoTrackActionName; 25 | static std::string kAddAudioTrackActionName; 26 | static std::string kExpectStreamActionName; 27 | static std::string kExpectVideoTrackActionName; 28 | }; 29 | 30 | class ConfigureMessage 31 | { 32 | public: 33 | static std::string kActionsFieldName; 34 | static std::string kConfigureType; 35 | 36 | static bool isConfigure(const Json::Value& message_json); 37 | 38 | bool fromJson(const Json::Value& message_json); 39 | std::string toJson() const; 40 | 41 | ConfigureMessage(); 42 | 43 | std::vector actions; 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /dockerfiles/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfiles 2 | 3 | These dockerfiles are useful for testing the webrtc ros package. 4 | 5 | To run them, you will need to: 6 | 1. Install Docker: (official docs)[https://docs.docker.com/v17.09/engine/installation/linux/docker-ce/ubuntu/] or (simplified)[https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04] 7 | 2. Build the images: `bash build_images.sh` 8 | 3. Run the image: `docker run -p 8080:8080 --name webrtc_ros/` 9 | 4. Open your web-browser and go to http://localhost:8080/ 10 | 5. Kill the container when done with `docker kill ` 11 | 12 | Notes: 13 | - `container name` can be whatever you want 14 | - `dockerfile` should come from the list below 15 | - you could choose to not give the docker container an image when running. You would then want to get the name with `docker container ls` when you are ready to kill it. 16 | - if you want to run with an interactive terminal, use: `docker run -p 8080:8080 -it webrtc_ros/` (the difference is the `-it` for interactive terminal mode) and then to kill, just press ctrl-c 17 | 18 | ## Available Files: 19 | These are the dockerfiles available 20 | - released: this image is the version released on the package repository 21 | - develop: this image is the version in the github develop branch 22 | - dev_awsc14: This image is the develop branch and a (fix to the apache web server)[https://github.com/GT-RAIL/async_web_server_cpp/pull/14] 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:noetic-perception 2 | 3 | 4 | # ROS dependencies 5 | RUN apt-get update && \ 6 | apt-get install -y --no-install-recommends \ 7 | ros-noetic-cv-bridge \ 8 | && \ 9 | apt-get clean && \ 10 | rm -rf /var/lib/apt/lists/* 11 | 12 | RUN apt-get update && \ 13 | apt-get install -y --no-install-recommends \ 14 | git\ 15 | curl 16 | 17 | 18 | RUN apt-get install -y --no-install-recommends python2 gmodule-2.0 libgtk-3-dev libglib2.0-dev pulseaudio libasound2-dev libpulse-dev ros-noetic-image-transport ninja-build stow 19 | 20 | RUN apt-get install -y --no-install-recommends libjpeg-turbo8 libjpeg-turbo8-dev 21 | 22 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python2 1 23 | 24 | WORKDIR /home/3rdparty/jsoncpp/ 25 | RUN git clone https://github.com/open-source-parsers/jsoncpp.git . && \ 26 | mkdir build && \ 27 | cd build && \ 28 | cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" .. && \ 29 | make && \ 30 | make install 31 | 32 | ENV LD_LIBRARY_PATH /usr/local/lib/:$LD_LIBRARY_PATH 33 | 34 | WORKDIR /home/webrtc_ws 35 | COPY . /home/webrtc_ws/src/ 36 | 37 | RUN git clone https://github.com/GT-RAIL/async_web_server_cpp.git /home/webrtc_ws/src/async_web_server_cpp/ 38 | 39 | RUN /ros_entrypoint.sh catkin_make_isolated --install --install-space "/usr/local/webrtc/" \ 40 | && sed -i '$isource "/usr/local/webrtc/setup.bash"' /ros_entrypoint.sh \ 41 | && rm -rf /home/webrtc_ws/ 42 | 43 | ENTRYPOINT ["/ros_entrypoint.sh"] 44 | -------------------------------------------------------------------------------- /webrtc_ros/LICENSE_webrtc_adapter: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, The WebRTC project authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | * Neither the name of Google nor the names of its contributors may 16 | be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /webrtc_ros/web/viewer.js: -------------------------------------------------------------------------------- 1 | function on_ready(callback) 2 | { 3 | if (document.readyState !== "loading") 4 | callback.call(document); 5 | else 6 | document.addEventListener("DOMContentLoaded", callback.bind(document)); 7 | } 8 | 9 | on_ready(function() { 10 | let Q = {}; 11 | let pv = window.location.search.substring(1).split("&"); 12 | for (let i in pv) 13 | { 14 | if (pv.hasOwnProperty(i)) 15 | { 16 | var kv = pv[i].split("=", 2); 17 | if (kv.length == 2) 18 | { 19 | Q[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]); 20 | } 21 | } 22 | } 23 | if (Q.subscribe_video) 24 | { 25 | document.getElementById("topic").textContent = Q.subscribe_video; 26 | console.log("Establishing WebRTC connection"); 27 | let conn = WebrtcRos.createConnection(); 28 | conn.onConfigurationNeeded = function() 29 | { 30 | console.log("Requesting WebRTC video subscription"); 31 | let config = {}; 32 | config.video = {"id": "subscribed_video", "src": Q.subscribe_video}; 33 | conn.addRemoteStream(config).then(function(event) { 34 | console.log("Connecting WebRTC stream to