Skip to content

Instantly share code, notes, and snippets.

@neilyoung
Last active August 7, 2023 06:10
Show Gist options
  • Save neilyoung/bc67892ec79a0f8de44b46642e7dceeb to your computer and use it in GitHub Desktop.
Save neilyoung/bc67892ec79a0f8de44b46642e7dceeb to your computer and use it in GitHub Desktop.
DEPRECATED - Kurento Media Server compiled from scratch on ARM architectures

Full source compile of Kurento Media Server on ARM architectures

Introduction

Note: This gist has lately be updated with instructions for compiling KMS on a Ubuntu 64-bit ARM Server 20.04.3, running in a VMWare instance on a MacBook-Pro 2021, Apple-Silicon. This is a perfect setup for local developments requiring a KMS instance "nearby". If instructions differ from the main stream they are marked with UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON

For staging some code for developing I was looking for a device, which I could put into my DMZ and which was able to run my WebRTC Signaling Server, a TURN server and the Kurento Media Server.

And since I don't own an X86_64 Intel bare bone, I was looking, if one already did compile the entire code base of KMS on ARM. I found a promising (and helpful) issue in the Kurento bugtracker, which was a good start, but not sufficient and not fully running at all.

I did choose to use one of my many Raspberry PIs. I didn't want to spend money for a cloud instance... The first two tasks have been setup relatively quick and easy on a Raspberry PI 3A+ (well, ok, not the fastest, but OK), but the KMS was a special thing: Kurento does not officially provide binaries or docker containers for ARM architectures and so all attempts to install KMS as easy as it is with Ubuntu and X86_64 failed perfectly.

Nearly the same instructions can also be used to compile Kurento on a Jetson Nano using a special XUbuntu version or even a "self-made" Ubuntu 18.04 image (https://pythops.com/post/create-your-own-image-for-jetson-nano-board.html). When there are differences in the instructions, those are explicitly marked with RASPBERRY-PI-OS, XUBUNTU-JETSON , UBUNTU-18.04-JETSON or UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON.

One of the latest attempts to bring KMS into new worlds was started, when I purchased a new MacBook Pro, now after close ten years with my beloved MBP End 2013... It was really worth the money, also, since my MPB wasn't fit anymore for Monterey. So I attempted to run this gist on a Ubuntu 20.04 64-bit ARM server running in a VMWare instance on my MBP. This gist was a perfect match for this and I finally also updated the instructions for this architecture, which is named UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON inhere. BTW: The compilation of all this took 30 minutes on my MBP :)

For the Nano I really recommend the UBUNTU-18.04-JETSON solution, since it is lightweight and fast. But there are some hurdles to overcome, until you have your own image. You will be able to have your own setup in 2 hours, if not less with this OS. I could imagine, that the UBUNTU-18.04-JETSON instructions would also work for the regular Nvidia Jetson Nano SD image, just you have to remove the existing OpenCV 4.1.1 installation and would also have to install OpenCV 3.4.16 from source (to be validated).

I spent some days on this (mostly waiting on compilation results), trying to find a way, circumventing issues, always close to give up, but since I have some very good experiences with Kurento I really didn't want to give up here. And in the end it was worth it. It works!

Surprisingly there is not that much to do in order to fully support ARM for Kurento. Just a little fix here and there and good.

I wouldn't recommend this solution for productive for performance reasons, at least not based on RPI 3A+, but there are a lot of powerful ARM devices out, we'll see.

Don't be discouraged by the mass of instructions. I have tried to make it as easy as possible to follow, you just basically need a device and a lot of patience. I think I have followed this gist several times already and it never failed (what of course means nothing at all).

Preparations

For UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON

  • You would need a Virtual Machine Manager on your MacBook. At time of writing this gist there is only a realistic option in either using Paralells or a free version of VMWare. I don't really like Parallels for their pricing and update policy, so I opted for the free VMWare, which was installed with a snip.

  • Download the Ubuntu 20.04 64-bit ARM server image and fire up an instance in VMWare.

  • It is recommended to give the VM at least 8GB RAM and 4 cores. The virtual hard drive should not be smaller than 25 GB. Furthermore it will be a good idea to use a the Bridged Network configuration to make your VM instance available in your network.

  • SSH to the instance and follow this gist.

For RASPBERRY-PI-OS

  • RPI 3A+ (minimum), Raspberry PI OS Buster (OS Lite, no desktop)

  • Flash OS on minimum 16 GB fast SD (e.g. this one), attach a USB ETH adapter and Internet (or use Wifi)

  • Issue touch ssh in the ./boot directory of the SD, this will automatically enable the SSH server on the PI at first boot

  • if no USB ETH adapter is available, place a valid wpa_supplicant.conf file into the ./boot directory of the SD

  • wpa_supplicant.conf (fill the <placeholders> with your values)

country=<two-letter-country-code>
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
       ssid="<ssid>"
       psk="<password>"
       key_mgmt=WPA-PSK
}
  • Find device on your network after startup (IP address)

  • SSH to device (user: pi, password: raspberry)

  • Make basic setup via sudo raspi-config (new password, timezone, etc.)

For XUBUNTU-JETSON-NANO

  • Flash the above mentioned XUbuntu version on a fast 16 GB (minimum) SD using Etcher or similar tools

  • Make a basic non-headless setup

  • Install an OpenSSH server by sudo apt-get install openssh-server, reboot and SSH to the box for further processing

For UBUNTU-18.04-JETSON-NANO

  • Follow the instructions in the pythops repo. For 18.04 you need to checkout this commit after the clone.

  • SSH to the Jetson Nano, once it is up.

Required system software and libs

You should be able to follow this gist line by line by simply copying the lines from here and paste it into the SSH console to the PI. You will need a couple of hours..

sudo apt update && sudo apt upgrade -y
sudo apt-get install git cmake pkg-config automake debhelper default-jdk gdb openssh-client maven wget autoconf python3-pip python-dev ffmpeg bison flex gtk-doc-tools -y
sudo apt-get install uuid-dev libvpx-dev libsoup2.4-dev libopus-dev libsigc++-2.0-dev libglibmm-2.4-dev libglib2.0-dev libffi-dev libevent-dev libboost-all-dev libtool gettext libfam-dev gobject-introspection libgirepository1.0-dev libasound2-dev libvorbis-dev libvisual-0.4-dev libogg-dev libtheora-dev libpango1.0-dev libvpx-dev  -y
sudo pip3 install meson ninja

For RASPBERRY-PI-OS and UBUNTU-18.04-JETSON

sudo apt install libopencv-dev

The marathon begins

I had a problem with gtk-doc during these steps, builds didn't go through, so I remove the entry --enable-gtk-doc from particular make files on the go. This has no impact on functionality.

Some instructions are using a "wild" construct like this:

cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2]; exit}'

Please run this beforehand in order to see, if it returns the expected result cmake-x.xx.

This is just to find the installed CMAKE version, since Kurento is trying to find some files in a subfolder named by using the major and minor version of CMAKE.

The build process follows the module list and dependencies outlined here https://doc-kurento.readthedocs.io/en/latest/dev/dev_guide.html#build-from-sources and some sniffing was involved too. I'm sure it is not as stream-lined as it should be, but it works for me. Please don't scramble the order of steps here. There might be dependencies in later steps.

You will occasionally find entries like this:

sed -i 's/ --enable-gtk-doc//' ./autogen.sh

This should not harm. I couldn't somehow compile the doc.

And before somebody asks: Yes, I also tried to use the kms-omni-build project after resolving the dependencies. I couldn't make it compile.

Be patient at some points: Even if it seems stuck, it is alive :).

Step 1: For RASPBERRY-PI-OS

# Swap
sudo dphys-swapfile swapoff
# Increase swap size by changing variable CONF_SWAPSIZE to 2048 and reboot
sudo sed -i 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=2048/' /etc/dphys-swapfile
sudo sync && sudo reboot

Step 1: For XUBUNTU-JETSON-NANO and UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON

  • Optional: Lift the clock rate and install monitoring software on Jetson Nano only, of course
# Raise clock rate
sudo jetson-clocks
# Install "htop" equivalent "jtop"
sudo -H pip install -U jetson-stats
  • Install OpenCV 3.4.16 from source (latest v3 at time of writing). KMS needs OpenCV < 4
sudo apt install build-essential cmake git pkg-config libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev -y
sudo apt install libjpeg-dev libpng-dev libtiff-dev gfortran openexr libatlas-base-dev python3-dev python3-numpy libtbb2 libtbb-dev libdc1394-22-dev -y

mkdir ~/opencv-build && cd ~/opencv-build
git clone https://github.com/opencv/opencv.git
cd ~/opencv-build/opencv
git checkout 3.4.16
mkdir build && cd build
# Note: No Python bindings, did not compile
cmake -D CMAKE_BUILD_TYPE=RELEASE           \
        -D CMAKE_INSTALL_PREFIX=/usr/local  \
        -D WITH_CUDA=OFF                    \
        -D INSTALL_C_EXAMPLES=OFF           \
        -D INSTALL_PYTHON_EXAMPLES=OFF      \
        -D OPENCV_GENERATE_PKGCONFIG=ON     \
        -D BUILD_EXAMPLES=OFF               \
        -DBUILD_opencv_python2=OFF          \
        -DBUILD_opencv_python3=OFF ..
make -j$(nproc)
sudo make install
# Important:
sudo apt remove libx264-dev -y

Step 1: For UBUNTU-18.04-JETSON

# Raise clock rate
sudo jetson-clocks
# If you need to have Python OpenCV bindings
sudo apt install python3-opencv
# The editor of your choice
sudo apt install nano

Step 2: Create a working directory

# Creata the base  build dir
mkdir ~/kms-build

Step 3: openssl - we need an older version for gstreamer-plugins-bad

cd ~/kms-build
git clone git://git.openssl.org/openssl.git
cd openssl/
git checkout tags/OpenSSL_1_0_2u
./config -fPIC --prefix=/usr shared
make -j$(nproc) && sudo make install && sudo ldconfig

Step 4: jsoncpp

cd ~/kms-build
git clone https://github.com/Kurento/jsoncpp.git
cd jsoncpp/
mkdir build && cd build

# Attention!
# For RASPBERRY_PI_OS. TODO: Check if RASPBERRY would also work with SHARED_LIB
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles" ..
# For XUBUNTU_JETSON_NANO _and_ UBUNTU-18.04-JETSON _and_ UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS=ON -G "Unix Makefiles" ..
# For all platforms:
make -j$(nproc) && sudo make install && sudo ldconfig

Step 5: librtsp

cd ~/kms-build
git clone https://github.com/Kurento/libsrtp.git
cd libsrtp
./configure && make && sudo make install && sudo ldconfig

Step 6: openh264 - Kurento says, the maximum version they can use is 1.5.0

cd ~/kms-build
git clone https://github.com/cisco/openh264.git
cd openh264/
git checkout tags/v1.5.0
make -j$(nproc) OS=linux ARCH=`uname -m`
sudo make install && sudo ldconfig

Step 7: libusrsctp

cd ~/kms-build
git clone https://github.com/Kurento/libusrsctp.git
cd libusrsctp
./bootstrap && ./configure enable_warnings_as_errors=no && make -j$(nproc) && sudo make install && sudo ldconfig

Step 8: gstreamer

cd ~/kms-build/
git clone https://github.com/Kurento/gstreamer.git
cd gstreamer
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh && make -j$(nproc) && sudo make install && sudo ldconfig

Step 9: gst-plugins-base

cd ~/kms-build/
git clone https://github.com/Kurento/gst-plugins-base.git
cd gst-plugins-base/
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh && make -j$(nproc) && sudo make install && sudo ldconfig

Step 10: gst-plugins-good

cd ~/kms-build/
git clone https://github.com/Kurento/gst-plugins-good.git
cd gst-plugins-good/
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh && make -j$(nproc) && sudo make install && sudo ldconfig

Step 11: gst-plugins-bad

cd ~/kms-build/
git clone https://github.com/Kurento/gst-plugins-bad.git
cd gst-plugins-bad
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh
# Don't proceed after this step, read next paragraph first

There is a problem with an erroneous reference to gstreamer-1.0 in an auto-generated Makefile, where it would require a reference to gstreamer-1.5. This will cause the make of player fail. Let's fix that:

sed -i 's/gstreamer-1.0/gstreamer-1.5/' ./gst-libs/gst/player/Makefile

Proceed with the build:

make -j$(nproc) && sudo make install && sudo ldconfig

Step 12: gst-plugins-ugly

cd ~/kms-build/
git clone https://github.com/Kurento/gst-plugins-ugly.git
cd gst-plugins-ugly/
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh && make -j$(nproc) && sudo make install && sudo ldconfig

Step 13: libnice

cd ~/kms-build/
git clone https://github.com/Kurento/libnice.git
cd libnice

At least up to version 0.1.18 there is a configuration issue in libnice, which twice references gstreamer-1.0 instead of the required gstreamer-1.5. This in turn will lead to the situation, that the gstreamer nice plugin is not properly build and the Media Server will not work.

In order to overcome this, apply this patch for the poor:

sed -i 's/gstreamer-1.0/gstreamer-1.5/' gst/meson.build
sed -i 's/gstreamer-base-1.0/gstreamer-base-1.5/' meson.build

This will ensure, that the plugin is properly built. It is still copied to the wrong place, but this will have to be fixed later. For now proceed with the build steps below:

meson setup builddir && cd builddir
ninja && sudo ninja install && sudo ldconfig
# Copy the gstreamer plugin to the proper place
sudo cp /usr/local/lib/`gcc -dumpmachine`/gstreamer-1.5/libgstnice.so /usr/local/lib/gstreamer-1.5/

Step 14: gst-libav

cd ~/kms-build/
git clone https://github.com/Kurento/gst-libav.git
cd gst-libav
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
# This autogen step may take _really_ long!!
# Make the progress a bit more transparent 
sed -i 's/git submodule update/git submodule update --progress/' ./autogen.sh
./autogen.sh && make -j$(nproc) && sudo make install && sudo ldconfig

Step 15: openwebrtc-gst-plugins

cd ~/kms-build/
git clone https://github.com/Kurento/openwebrtc-gst-plugins.git
cd openwebrtc-gst-plugins
sed -i 's/ --enable-gtk-doc//' ./autogen.sh
./autogen.sh
./configure
make
sudo make install && sudo ldconfig

Step 16: kurento-module-creator

cd ~/kms-build
git clone https://github.com/Kurento/kurento-module-creator
cd kurento-module-creator
mvn package
sudo install target/kurento-module-creator-jar-with-dependencies.jar /usr/bin -v
sudo install scripts/kurento-module-creator /usr/bin -v
sudo mkdir -p /usr/local/share/`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2]; exit}'`/Modules/
sudo install target/classes/FindKurentoModuleCreator.cmake /usr/local/share/`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2]; exit}'`/Modules/ -v
# Test
kurento-module-creator

Step 17: kms-cmake-utils

cd ~/kms-build
git clone https://github.com/Kurento/kms-cmake-utils
cd kms-cmake-utils
mkdir build && cd build
cmake ..
sudo make install

Step 18: kms-jsonrpc

cd ~/kms-build
git clone https://github.com/Kurento/kms-jsonrpc
cd kms-jsonrpc
mkdir build && cd build
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j 4 && sudo make install && sudo ldconfig

Step 19: kms-core

cd ~/kms-build
git clone https://github.com/Kurento/kms-core
cd kms-core
mkdir build && cd build
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j$(nproc) && sudo make install && sudo ldconfig

Step 20: kms-elements

cd ~/kms-build
git clone https://github.com/Kurento/kms-elements
cd kms-elements
mkdir build && cd build
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j$(nproc) && sudo make install && sudo ldconfig

Step 21: kms-filters

cd ~/kms-build
git clone https://github.com/Kurento/kms-filters.git
cd kms-filters
mkdir build && cd build
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j$(nproc) && sudo make install && sudo ldconfig

Step 22: websocketpp - we need an older version for kurento-media-server

cd ~/kms-build
git clone https://github.com/zaphoyd/websocketpp.git
cd websocketpp

# For RASPBERRY_PI_OS _and_ UBUNTU-18.04-JETSON
git checkout tags/0.7.0

# For UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON _and_ XUBUNTU_JETSON_NANO
git checkout tags/0.8.2

# For all platforms
mkdir build && cd build
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j$(nproc) && sudo make install && sudo ldconfig

Step 23: kurento-media-server - it's all just about this...

cd ~/kms-build
git clone https://github.com/Kurento/kurento-media-server.git
cd kurento-media-server
mkdir build && cd build

# For UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON _and_ XUBUNTU_JETSON_NANO 
# Patch CMakeList.txt so that it accepts 0.8.2 version
sed -i 's/find_package(websocketpp 0.7.0 REQUIRED)/find_package(websocketpp 0.8.2 REQUIRED)/' ../server/transport/websocket/CMakeLists.txt

# For all platforms:
cmake -DCMAKE_MODULE_PATH=/usr/local/share/"`cmake --version | awk '{split($0,a," "); split($a[3],a,"."); print "cmake-"a[1]"."a[2];exit}'`"/Modules -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/. ..
make -j$(nproc) && sudo make install && sudo ldconfig

# *** YOU ARE DONE HERE IF THE BUILD PASSES OK ***

# In case the build fails:

# For XUBUNTU_JETSON_NANO
# There is a compatibiltiy problem between the installed libboost-all-dev (1.71) and the Kurento required websocketpp 0.7.0. So we have to use the master branch of websocketpp, which holds 0.8.2 nowadays. This in turn will make troubles on linking kurento-media-server:

# [100%] Linking CXX executable kurento-media-server
# /usr/bin/ld: cannot find -lBoost::filesystem
# /usr/bin/ld: cannot find -lBoost::system
# /usr/bin/ld: cannot find -lBoost::thread
# /usr/bin/ld: cannot find -lBoost::program_options
# /usr/bin/ld: cannot find -lBoost::unit_test_framework
# /usr/bin/ld: cannot find -lBoost::log
# /usr/bin/ld: cannot find -lBoost::filesystem
# /usr/bin/ld: cannot find -lBoost::system
# /usr/bin/ld: cannot find -lBoost::thread
# collect2: error: ld returned 1 exit status

# It is a bit risky, but the libs are installed, they just have other names. So to fix this, run these commands when the build step has faile and repeat it.

# Check, which files have to be altered, should be the same as listed below:

grep -Ril "lBoost" .

# Alter each file:

sed -i 's/-lBoost::/-lboost_/g' ./server/CMakeFiles/kurento-media-server.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_server_events.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_server_json_session.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_registrar.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_server_duplicate_requests.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_server_json.dir/link.txt
sed -i 's/-lBoost::/-lboost_/g' ./test/CMakeFiles/test_config_read.dir/link.txt

# Finally repeat the build for XUBUNTU_JETSON_NANO _and_ UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON
make -j$(nproc) && sudo make install && sudo ldconfig

Step 24: Disable swap (if it was enabled)

sudo dphys-swapfile swapoff

Step 25: And so it ends - don't miss this step

The modules for gstreamer-1.5 have been properly compiled, but finally installed to /usr/lib/gcc -dumpmachine/gstreamer-1.5/. By this they can neither be recognized as valid gstreamer plugins nor later be found by.

  • Copying it to the right place does solve this problem:
sudo cp /usr/lib/`gcc -dumpmachine`/gstreamer-1.5/* /usr/local/lib/gstreamer-1.5/
sudo cp /usr/local/lib/`gcc -dumpmachine`/gstreamer-1.5/* /usr/local/lib/gstreamer-1.5/
  • Test your work:
gst-inspect-1.5 | grep -E "nice|^kms*"

This should show you the nice plugin as well as a good bunch of kms* plugins.

  • Provide some configuration files for the proper start of the server:
cd ~
sudo mkdir -p /etc/kurento/modules/kurento
sudo cp ~/kms-build/kurento-media-server/kurento.conf.json /etc/kurento
sudo cp ~/kms-build/kms-core/build/config/kurento/* /etc/kurento/modules/kurento
sudo cp ~/kms-build/kms-elements/build/config/kurento/* /etc/kurento/modules/kurento

sudo chmod 777 /etc/kurento/kurento.conf.json
sudo chmod 777 /etc/kurento/modules/kurento/*

# All relevant configuration will be in /etc/kurento and /etc/kurento/modules/kurento

The first "Hello Kurento"

kurento-media-server --version
# Should give (as of today)
Kurento Media Server version: 6.16.1~8.g1b883ba
Found modules:
    'core' version 6.16.1~14.g2c77dfb8
    'elements' version 6.16.1~18.g0807a71
    'filters' version 6.16.1~3.gec9da10

Let's setup of a harder test

  • Start up the server
# A lot of debugging
export GST_DEBUG=",Kurento*:7,KurentoWebSocket*:4"
kurento-media-server
  • From another console or SSH window:
# For XUBUNTU_JETSON_NANO
sudo apt install curl
# For all platforms:
# Install node
curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -
sudo apt-get install -y nodejs

# Setup the test
mkdir kms-test && cd kms-test
npm init --yes
npm i kurento-client
  • Edit index js
nano index.js
  • Paste the following test code into index.js and save:
const kurento = require('kurento-client')

const test = async () => {
    try {
        let kurentoClient = await kurento('ws://localhost:8888/kurento', { failAfter: 5 })
        let pipeline = await kurentoClient.create('MediaPipeline')
        await pipeline.setLatencyStats(true)
        let webRtcEndpoint = await pipeline.create('WebRtcEndpoint')

        await Promise.all(
                [webRtcEndpoint.setMinVideoSendBandwidth(500),
                webRtcEndpoint.setMaxVideoSendBandwidth(5000),
                webRtcEndpoint.setMinVideoRecvBandwidth(500),
                webRtcEndpoint.setMaxVideoRecvBandwidth(5000)
            ])

        webRtcEndpoint.on('ConnectionStateChanged', (event) => {
            console.log(`ConnectionStateChanged ${JSON.stringify(event)}`)
        })
        webRtcEndpoint.on('MediaStateChanged', (event) => {
            console.log(`MediaStateChanged ${JSON.stringify(event)}`)
        })
        webRtcEndpoint.on('IceComponentStateChange', (event) => {
            console.log(`IceComponentStateChange state ${event.state}, streamId ${event.streamId}, componentId ${event.componentId}`)
        })
        webRtcEndpoint.on('NewCandidatePairSelected', (event) => {
            console.log(`NewCandidatePairSelected, server ${event.candidatePair.localCandidate}`)
            console.log(`NewCandidatePairSelected, client ${event.candidatePair.remoteCandidate}`)
        })
        webRtcEndpoint.on('IceCandidateFound', (event) => {
            console.log(`IceCandidateFound ${event.candidate.candidate}, sdpMid: ${event.candidate.sdpMid}`)
        })
        webRtcEndpoint.on('IceGatheringDone', (event) => {
            console.log(`IceGatheringDone`)
        })

        await webRtcEndpoint.connect(webRtcEndpoint)
        console.log(await webRtcEndpoint.generateOffer())
        await webRtcEndpoint.gatherCandidates()

    }
    catch (e) {
        console.error(e)
    }
}

test()
  • Run it:
node index.js

You should see an SDP answer and ICE candidates.

Start as a service

  • Stop a probably running instance of KMS (the thing in the other console)

  • Create a log directory in your /home/ubuntu:

cd ~
mkdir kms-logs
  • Simple service setup (tested on UBUNTU-18.04-JETSON and UBUNTU-20.04-ARM-SERVER-VM-APPLE-SILICON):
cd /etc/systemd/system
sudo nano kurento-media-server.service
  • Paste this into:
[Unit]
Description=Kurento Media Server

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu
ExecStart=/usr/bin/kurento-media-server --gst-debug-level=2 --gst-debug="Kurento*:4,kms*:4" --logs-path=/home/ubuntu/kms-logs
Restart=always

[Install]
WantedBy=multi-user.target
  • Save and proceed with installation:
sudo systemctl daemon-reload
sudo systemctl start kurento-media-server.service
sudo systemctl status kurento-media-server.service
# Enable start on every reboot
sudo systemctl enable kurento-media-server.service
  • You should now already hav a log file in your ~/kms-logs dir

  • Alternatively you can omit the --logs-path entry and "tail" the current log by:

journalctl -xefu kms

Clean up

If you don't intend to ever touch one of the compiled modules you can safely delete the ~/opencv-build directory (if existent) and everything from ~/kms-build.

Open problems

No known so far.

@neilyoung
Copy link
Author

Meanwhile this gist is available as Ansible playbook, at least tested on a ARM VM on my MBP. Dramatically decreases installation time

@neilyoung
Copy link
Author

... and it supports OpenCV4 too

@tony-p
Copy link

tony-p commented May 16, 2022

Is there a fundamental reason for the raspberry pi requiring version 3A+? Or just not tested and possibly require more steps?

I have an old Raspberry PI B lying round and would be interested in trying to put it on there (for a pretty simple application)

@neilyoung
Copy link
Author

@tony-p I don't think so. I guess this was around when I was trying it. Most likely you will have to wait very long. Take care of a good swap area. This is for the compilation.

The runtime requirements are a bit different. I guess you will not be happy with the transcoding performance of such an old device. If you are just not doing transcoding on the KMS it might work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment