The RtmpStreamer class is designed for high-performance video streaming to RTMP servers and local display, leveraging GStreamer and OpenCV. It is ideal for applications in live broadcasting and real-time video processing, providing seamless frame capture and synchronization. The class ensures efficient and thread-safe operation, making it suitable for demanding streaming environments.
To build and run the DynRT project, you need to have the following dependencies installed:
- Meson Build System: Version 1.1.0 or higher
- Ninja Build System: Version 1.10.0 or higher
- C++: C++17 standard
- g++ compiler*
- Python3
- GStreamer 1.0: Version 1.20 or higher
- OpenCV 4: Version 4.0 or higher
- Threads: Required for multithreading support
- GStreamer App 1.0: Version 1.0 or higher
- fmt: Version 7.1.3 or higher
- Cython: Version 3.0.0 or higher
- NumPy: Version 1.2X.0
One of the easiest ways to install the dependencies is to run it via a package manager. Here are the tested installation methods.
sudo apt-get update
sudo apt-get install -y g++ libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio libopencv-dev libfmt-dev python3-dev python3-pip
python3 -m pip install --prefix /usr/local/ cython numpy meson ninja
A lot of the libraries can also be installed from source. Here are a few links to their installation instructions:
after cloning down git clone https://github.com/acoustic-warfare/DynRT-streamer
and moving into the repo cd DynRT-streamer
, the library can be built and installed with default settings like this:
meson setup build --native-file native-file.ini
ninja -C build
sudo ninja -C build install
sudo ldconfig
(NOTE: python bindings are not generated by default. Read on for information about how to generate them.)
for meson specific options such as C++ standard or installation directory, you can read more here.
The project specific options available are:
python-bindings
(boolean), desc: Wether or not to generate python bindings for librarybuild-tests
(boolean) desc: If tests should be builtbuild-examples
(boolean) desc: If code examples should be built (NOTE: will crash on build if library has not been built and installed before)
meson setup build -Dpython-bindings=true -Dbuild-tests=false --native-file native-file.ini
After the setup has been completed, the library can be built with the following command:
ninja -C build
It can then be installed with
sudo ninja -C build install
Before the library can be used by other executables and libraries, it must be exposed to the dynamic linker. run ldconfig
to configure the dynamic linker.
yet to be implemented
C++ usecase with comments:
#include <future>
#include <opencv2/core/mat.hpp>
#include <opencv2/opencv.hpp>
#include <rtmp.hpp>
#define SCREEN_WIDTH 1920
#define SCREEN_HEIGHT 1080
typedef cv::Point3_<uint8_t> Pixel;
int main(int argc, char *argv[]) {
// Initialize the Streamer with a width of 1920 and height of 1080 and
// determine where to send the RTMP stream to
RtmpStreamer streamer(SCREEN_WIDTH, SCREEN_HEIGHT,
"rtmp://ome.waraps.org/app/stream-name");
streamer.start_stream();
// Generate a frame and colormap it
cv::Mat frame(SCREEN_HEIGHT, SCREEN_WIDTH, CV_8UC1);
cv::applyColorMap(frame, frame, cv::COLORMAP_JET);
// This control unit takes input from the terminal and controls the state of
// the streamer
auto control_unit =
std::async(std::launch::async,
&RtmpStreamer::async_streamer_control_unit, &streamer);
// Used for color manipulation
static int count = 0;
while (true) {
// do some color manipulation on the frame
frame.forEach<Pixel>([](Pixel &pix, const int *position) {
pix.x = count < 10 ? 255 : 0;
pix.y = 10 <= count && count < 20 ? 255 : 0;
pix.z = count >= 20 ? 255 : 0;
});
// Pass the frame on to the streamer pipeline to be shown locally and/or
// sent up to RTMP server. Streamer does not take ownership of the frame
// and does not change anything in the frame.
streamer.send_frame(frame);
count = (count + 1) % 30;
// Only returns when user has typed "quit" in the terminal
if (control_unit.wait_for(std::chrono::milliseconds(10)) ==
std::future_status::ready) {
return 0;
}
}
return 0;
}
Python example with commens
from rtmp_streamer import PyRtmpStreamer
import numpy as np
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 1000
if __name__ == "__main__":
# Initialize the streamer with a with and a height for the video input
# and the Server to stream to
streamer = PyRtmpStreamer(SCREEN_WIDTH, SCREEN_HEIGHT,
"rtmp://ome.waraps.org/app/streamname")
# Only start the rtmp stream
streamer.start_rtmp_stream()
# create a frame to display
frame = np.zeros((SCREEN_HEIGHT,SCREEN_WIDTH, 3))
while True:
streamer.send_frame(frame.tobytes())