Video streaming from Raspberry Pi with UV4L

Here I describe how to set up secure video streaming using Raspberry Pi and a dedicated camera with UV4L. This post is written in tutorial–like form and the set–up presented here will be used in my other projects.

Retrieving video from camera is not that hard. For this you can use UV4L. It is an open source initiative which aims to deliver user space for real or virtual video input or video output (after UV4L project website). In other words, it will create a device inside /dev/ which can be directly accessed to get video from it. So let’s jump straight to installing the required software.

Installing UV4L

First, we need to add UV4L repository keys:

curl http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add -

add project repositories to our local source list:

sudo bash -c "echo \"deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main\" >> /etc/apt/sources.list"

Now we can update local repository list and install necessary packages:

sudo apt-get update && sudo apt-get install uv4l uv4l-server uv4l-raspicam uv4l-raspicam-extras

Starting server

To start UV4L you need to run following command:

sudo service uv4l_raspicam start

Analogically to stop the server you can run following command:

sudo service uv4l_raspicam stop

Starting server at boot time

To facilitate management of UV4L we can start the UV4L service at boot. There are two ways of doing it. One is to modify rc.local file like this:

sudo bash -c "echo \"sudo service uv4l_raspicam start\" >> /etc/rc.local"

The other possibility is to use update-rc.d to start UV4L server at boot using udpate-rc.d. This is how you would do this:

sudo update-rc.d -f uv4l_raspicam enable

Also do stop UV4L from starting at boot you would do something like this:

sudo update-rc.d -f uv4l_raspicam disable

 

Enabling camera interface

There is also a preliminary step which has to be done before working with the camera. The camera interface has to be turned on. Unless it is already turned on you have to use raspi-config command, like this:

sudo raspi-config

There you can navigate through the interface and set camera interface to Enabled. After that reboot RPi and you are good to go. I assume that the camera is already connected to the mini computer.

Accessing UV4L web server

Now, you can test if the UV4L is working properly. If you have installed uv4l-server then there is a small web server which will allow you to test UV4L installation. By default the server is working on port number 8080. To test the server you need to enter this URL address inside your browser:

RPI_LOCAL_IP:8080

if you are accessing RPi from local network at a different computer. The RPI_LOCAL_IP is IP address of Raspberry PI, probably but not limited to something like this 192.168.0.x.

or

localhost:8080

if you are running it on your Raspberry Pi. However, I recommend testing it on a different computer.

You should see something similar to:

what you are interested in are two tiles: “MJPEG/Stills stream” and “Control panel”. Let’s start with the later. If you click on the nice two gears you should see something like this:

You can set resolution of the video and some other parameters like brightness or rotation. In my case, I had to rotate the image because I have mounted the camera upside down. After saving the configuration go to MJPEG/Stills stream. There you will see a live stream from the camera. There is one thing worth noting, when you have live stream active, it is open on another tab in your browser, you will not be able to save the configuration. First you have to close the live stream, save configuration and then reopen the video tab.

The MJPEG/Stills stream is used to display live stream. What is nice about it is that you can use a direct URL for this http://localhost:8080/stream.

Securing UV4L

Since sharing live stream publicly is not necessarily a good idea we should do two things:

  • add some authorization, so people who do not know the password won’t be able to log into uv4l server and change something,
  • encrypt the connection itself, thus even if someone is sniffing your network, the traffic will be safe.

Let’s start with the first one. U4VL can have up to three predefined user types:

  • admin, this user can to everything, change parameters, start live stream, everything what UV4L is capable of,
  • config, he can change configuration file,
  • user, he can only start live stream without modifying the parameters.

The password is not stored in open form it is encrypted as md5 hash. To create a md5 hash you can use Python and those lines:

import hashlib
import getpass

password = getpass.getpass("Enter password: ");
hashlib.md5(str.encode(password)).hexdigest();

For example, hash for password ‘mysecretpassword’ will be ‘4cab2a2db6a3c31b01d804def28276e6’.

When you generate those three password you can edit the configuration file. It can be found under /etc/uv4l/uv4l-raspicam.conf. Inside this file you should find lines:

server-option = --user-password=AAAAA
server-option = --admin-password=BBBBB
server-option = --config-password=CCCCC

If there are commented out remove ‘#’ at the beginning of each line and substitute AAAAA, BBBBB, CCCCC with md5 hashes. Also alter this line

server-option = --md5-passwords=no

to

server-option = --md5-passwords=yes

After restarting uv4l service the server will be protected. The next thing is to use HTTPS instead of HTTP to encrypt the traffic. This can be done by altering three lines:

### HTTPS options:
server-option = --use-ssl=yes
server-option = --ssl-private-key-file=/etc/uv4l/privkey.key
server-option = --ssl-certificate-file=/etc/uv4l/cert.pem

First one says that HTTPS should be used and the last two are paths to SSL private key and certificate respectively. There are two ways of obtaining the certificate: you can generate a self-signed one but each web browser will warn about that saying that this kind of certificate is untrusty but it will work! You can generate it with following commands:

Generate and save CSR (Certificate Signing Authority), it will prompt you for passphrase to secure the private key which will be saved to privkey.pem.

sudo openssl req -new > new.ssl.csr

Generate key for signing:

sudo openssl rsa -in privkey.pem -out new.cert.key

Generate certificate and key. The certificate will be valid for 100 days:

sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 100

Copy certificate and private key:

sudo cp new.cert.cert /etc/uv4l/cert.pem
sudo cp new.cert.key /etc/uv4l/privkey.key

The other option is to generate Letsencrypt certificate. It is as easy as this single line:

letsencrypt certonly -d EXAMPLE.COM --agree-tos --email [email protected] --no-redirect --non-interactive --apache

But it requires you to have registered domain EXAMPLE.COM. Also you should pass a valid email [email protected]. Renewing a certificate is also very straightforward:

letsencrypt rewnew

The certificates can be found under /etc/letsencrypt/live/EXAMPLE.COM/. You should be interested in files cert.pem and privkey.pem (remember to change its name to privkey.key to match the configuration in configuration file).

Additional configuration

To set up different port change following line

server-option = --port=8080

Default encoding, resolution and frame rate can be changed with those lines:

encoding = mjpeg
width = 640
height = 480
framerate = 30

Some image parameters like sharpness, contrast, brightness and saturation can be adjusted with:

sharpness = 0
contrast = 0
brightness = 50
saturation = 0

Also if you would like to rotate the image you can pass the number of degrees:

rotation = 180

Or you can flip the image horizontally or vertically:

hflip = no
vflip = yes

There are many more options. Just remember those are default parameters and can by changed with web interface!

31 thoughts on “Video streaming from Raspberry Pi with UV4L

  1. Sean

    Thanks for the instructions for creating selfsigned SSL certificates. When using Chromium on a Pi 3B, I get the following errors when trying to call another Pi 3B (Both are running UV4L and I am using the WebRTC stream page with peer being 192.168.2.29):

    [10070:10088:1004/214624.630023:ERROR:cert_verify_proc_nss.cc(942)] CERT_PKIXVerifyCert for 192.168.2.21 failed err=-8179
    [10070:10219:1004/214657.919290:ERROR:cert_verify_proc_nss.cc(942)] CERT_PKIXVerifyCert for 192.168.2.29 failed err=-8172

    I have to admit I am a beginner at this but any advice would be appreciated. The Common Name for each certificate on each machine is their respective local IP addresses. I am trying to get it to work within the LAN first and then perhaps across the Internet later. I haven’t had any luck with Jitsi. I got the WebRTC stream page to work internally. I know if it was to go over the Internet, I would have to port forward on each end. I would be able to do so. Anyway, comments, suggestions, direction would be helpful. Thanks. ?

    Reply
    1. Wojciech Domski Post author

      You can use selfsigned certificate with Chrome or any other browser. It will say that it is insecure but it is. The reason behind it is that each browser is checking a chain of relationships between certificates. Since you are generating a certificate by yourself the Chrome is unable to verify the CA of the certificate because it simply doesn’t know it. Said that, the traffic is safe, still encrypted but it will produce an alert in any web browser. Could you please tell me if you are able to visit the site or it terminates the connection completely?
      What I can recommend is using a Let’s Encrypt certificate. You have to portforward the service ports (like 80 or 443). There are scripts which will automate the process of renewing the certificate every 90 days. You have a set of instruction in my blog post where I describe how to do this. Hope it helps!
      However, if you do this completely locally then you have to bear the error message.

  2. Sean

    I cannot connect to the site at all. When I try to connect, nothing happens. I can connect locally if the remote peer is the respective IP address of the Pi I am on.

    Thanks for the info on the SSLs. (I can try the other option from Let’s Encrypt perhaps later.) I wasn’t sure if it was rejecting the connection because it did not approve of the certificates or not and this is why the connection would not happen. Below is the config file I have setup for uv4l-raspicam.conf (I placed the SSL key and pem files in a different folder than you stated in your instructions) See anything that might cause a problem?

    # You can use this file to override the built-in defaults of the options in
    # the following modules:
    # – UV4L core
    # – raspicam driver
    # – Streaming Server module.
    #
    # To get a full list of the available options with their defaults and
    # descriptions, please refer to the ‘uv4l’, ‘uv4l-raspicam’ and ‘uv4l-server’
    # manual pages, or alternatively type the following command:
    #
    # uv4l –driver raspicam –help –driver-help –server-help
    #
    # This file is parsed by uv4l through the ‘uv4l_raspicam’ system service script,
    # if installed. If you are not using the service facility to load the raspicam
    # driver, then to instruct uv4l to parse this file you must explicitly pass its
    # path to the ‘–driver-config-file’ driver option and/or to the ‘–config-file’
    # options, for example (in one line):
    #
    # uv4l […] –driver raspicam –config-file=/path/to/uv4l-raspicam.conf \
    # –driver-config-file=/path/to/uv4l-raspicam.conf
    #
    # NOTE: multi argument options must be specified with one argument per line,
    # e.g the command line option ‘–min-object-size 80 120’, in this file becomes:
    # min-object-size = 80
    # min-object-size = 120
    # another example:
    # server-option = –webrtc-stun-urls=stun:stun.l.google.com:19302
    # server-option = –webrtc-stun-urls=stun1.l.google.com:19302
    #
    # NOTE: to comment out an option override put a # at the beginning of the
    # corresponding line. Remember that any commented out option that may appear
    # on a standard installation of this file is *not* necessarily specified with
    # its default built-in value.

    ##################################
    # uv4l core options
    ##################################

    driver = raspicam
    # video_nr = 0
    auto-video_nr = yes
    # verbosity = 6
    # log-color = false
    # syslog-host = localhost
    # syslog-port = 514
    # frame-timeout = 5000
    frame-buffers = 4
    # zero_copy = yes
    # drop-bad-frames = yes
    # relaxed-ownership = yes
    # extension-presence = no

    ##################################
    # raspicam driver options
    ##################################

    encoding = h264
    # width = 640
    # height = 480
    framerate = 12
    #custom-sensor-config = 2

    ### dual camera options:
    # stereoscopic-mode = side_by_side
    # camera-number = 1
    # decimate = yes
    # swap-eyes = yes

    ### still and/or video options:
    # quality = 85
    # stills-denoise = yes
    video-denoise = no
    # raw = no

    ### h264 options:
    # profile = high
    # level = 4.2
    # bitrate = 8000000
    # intra-refresh-mode = dummy
    # intra-period = #arg
    # inline-headers = yes
    # quantisation-parameter #arg

    ### video overlay options:
    nopreview = yes
    fullscreen = no
    # osd-layer = 2
    # opacity = 255
    ### preview window :
    preview = 480
    preview = 240
    preview = 320
    preview = 240

    ### post-processing options:
    # text-overlay = yes
    # text-filename = /usr/share/uv4l/raspicam/text.json
    # object-detection = yes
    # object-detection-mode = accurate_tracking
    # min-object-size = 80
    # min-object-size = 80
    # main-classifier = /usr/share/uv4l/raspicam/lbpcascade_frontalface.xml
    # secondary-classifier =/usr/share/uv4l/raspicam/lbpcascade_frontalface.xml

    ### image settings options:
    # sharpness = 0
    # contrast = 0
    # brightness = 50
    # saturation = 0
    # iso = 400
    # vstab = yes
    # ev = 0
    # exposure = auto
    # flicker = off
    # awb = auto
    # imgfx = none
    # metering = average
    # rotation = 0
    # hflip = no
    # vflip = no
    # shutter-speed = 0
    # drc = off
    # red-gain = 100
    # blue-gain = 100
    # text-annotation = HelloWorld!
    # text-annotation-background = yes
    ### ROI normalized to [0, 1]
    # roi = 0
    # roi = 0
    # roi = 1
    # roi = 1
    ### ISP blocks
    # black-level-compensation = yes
    # lens-shading = yes
    # automatic-defective-pixel-correlation = yes
    # white-balance-gain = yes
    # crosstalk = yes
    # gamma = yes
    # sharpening = yes

    ### TC358743 HDMI to MIPI converter options:
    # tc358743 = no
    # tc358743-i2c-dev = /dev/i2c-1
    # tc358743-init-command = /usr/share/uv4l/raspicam/tc358743_init.sh
    # tc358743-no-signal-fallthrough = no
    # tc358743-edid-file = #path
    # record = no
    # recording-dir = /usr/share/uv4l/recordings
    # recording-bitrate = 800000

    ### advanced options:
    # statistics = yes
    # output-buffers = 3

    ### License Key associated to serial number (from –serial-number):
    # license-key = #arg

    #################################
    # streaming server options
    #################################

    ### path to a separate config file that will be parsed by the streaming server
    ### module directly when it’s loaded,
    ### in which you are allowed to specify all the streaming server options
    ### listed below in the short form “option=value” instead of the longer
    ### “–server-option = –option=value” form that you must use
    ### in this configuration file.
    #server-config-file = #path

    # server-option = –port=8080
    # server-option = –bind-host-address=localhost
    # server-option = –md5-passwords=no
    # server-option = –user-password=myp4ssw0rd
    # server-option = –admin-password=myp4ssw0rd
    ### To enable ‘config’ user authentication
    # server-option = –config-password=myp4ssw0rd

    ### HTTPS options:
    server-option = –use-ssl=yes
    server-option = –ssl-private-key-file=/home/pi/privkey.key
    server-option = –ssl-certificate-file=/home/pi/cert.pem

    ### WebRTC options:
    server-option = –enable-webrtc=yes
    # server-option = –enable-webrtc-datachannels=yes
    # server-option = –webrtc-datachannel-label=uv4l
    # server-option = –webrtc-datachannel-socket=/tmp/uv4l.socket
    server-option = –enable-webrtc-video=yes
    server-option = –enable-webrtc-audio=yes
    server-option = –webrtc-receive-video=yes
    # server-option = –webrtc-receive-datachannels=no
    # server-option = –webrtc-received-datachannel-socket=/tmp/uv4l.socket
    server-option = –webrtc-receive-audio=yes
    # server-option = –webrtc-received-audio-volume=5.0
    # server-option = –webrtc-prerenderer-smoothing=yes
    # server-option = –webrtc-recdevice-index=0
    # server-option = –webrtc-vad=yes
    server-option = –webrtc-echo-cancellation=yes
    # server-option = –webrtc-preferred-vcodec=0
    # server-option = –webrtc-enable-hw-codec=yes
    # server-option = –webrtc-video-format=60
    # server-option = –webrtc-hw-vcodec-minbitrate=800
    # server-option = –webrtc-hw-vcodec-maxbitrate=4000
    # server-option = –webrtc-hw-vcodec-startbitrate=1200
    # server-option = –webrtc-hw-vcodec-intra-period=1800
    # server-option = –webrtc-suspend-below-min-bitrate=no
    server-option = –webrtc-max-playout-delay=34
    # server-option = –webrtc-cpu-overuse-detection=no
    # server-option = –webrtc-combined-audiovideo-bwe=no
    # server-option = –webrtc-stun-urls=stun:stun.l.google.com:19302
    # server-option = –webrtc-stun-urls # use this for no urls
    # server-option = –webrtc-ice-servers=[{“urls”: “stun:stun1.example.net”}, {“urls”: “turn:turn.example.org”, “username”: “user”, “credential”: “myPassword”}]
    # server-option = –webrtc-stun-server=yes
    # server-option = –webrtc-tcp-candidate-policy=1
    # server-option = –webrtc-rtcp-mux-policy=0
    # server-option = –webrtc-enable-dscp=no
    # server-option = –webrtc-ignore-loopback=yes
    # server-option = –webrtc-trickle-ice=yes
    # server-option = –webrtc-stats-dir=/usr/share/uv4l/statistics/
    ### video rendering window positions and sizes on the display.
    ### for each window, default values can be optionally overridden, but if you
    ### do this you must specify one line for each of the four x, y, width, height
    ### window properties (in that order).
    ### If fullscreen is set the image is stretched to the maximum available display
    ### resolution from the specified size.
    ### window 1
    server-option = –webrtc-renderer-window=0
    server-option = –webrtc-renderer-window=0
    server-option = –webrtc-renderer-window=480
    server-option = –webrtc-renderer-window=352
    server-option = –webrtc-renderer-fullscreen=no
    server-option = –webrtc-renderer-rotation=180
    # server-option = –webrtc-renderer-opacity=255
    ### window 2
    # server-option = –webrtc-renderer2-window=480
    # server-option = –webrtc-renderer2-window=0
    # server-option = –webrtc-renderer2-window=320
    # server-option = –webrtc-renderer2-window=240
    ### window 3
    # server-option = –webrtc-renderer3-window=0
    # server-option = –webrtc-renderer3-window=352
    # server-option = –webrtc-renderer3-window=176
    # server-option = –webrtc-renderer3-window=128
    # if enabled, this overrides the size of the rendering windows:
    # server-option = –webrtc-renderer-source-size=no

    ### XMPP options:
    # server-option = –xmpp-server=lambada.jitsi.net
    # server-option = –xmpp-port=5222
    # server-option = –xmpp-muc-domain=meet.jit.si
    # server-option = –xmpp-room=room
    # server-option = –xmpp-room-password=room_password
    # server-option = –xmpp-username=me
    # server-option = –xmpp-password=mypassword
    # server-option = –xmpp-reconnect=yes
    # server-option = –xmpp-bosh-enable
    # server-option = –xmpp-bosh-tls
    # server-option = –xmpp-bosh-server
    # server-option = –xmpp-bosh-port
    # server-option = –xmpp-bosh-hostname
    # server-option = –xmpp-bosh-path
    # server-option = –xmpp-bridge-host=localhost
    # server-option = –xmpp-bridge-port=7999

    ### Janus WebRTC Gateway options:
    # server-option = –janus-gateway-url=https://janus.conf.meetecho.com
    # server-option = –janus-gateway-root=/janus
    # server-option = –janus-room=1234
    # server-option = –janus-room-pin=#pin
    # server-option = –janus-username=test
    # server-option = –janus-token=#token
    # server-option = –janus-proxy-host=#host
    # server-option = –janus-proxy-port=80
    # server-option = –janus-proxy-username=#user
    # server-option = –janus-proxy-password=#password
    # server-option = –janus-proxy-bypass=#regex
    # server-option = –janus-force-hw-vcodec=no
    # server-option = –janus-video-format=#code
    # server-option = –janus-publish=yes
    # server-option = –janus-subscribe=no
    # server-option = –janus-reconnect=yes

    ### Fine-tuning options:
    # server-option = –connection-timeout=15
    # server-option = –enable-keepalive=yes
    # server-option = –max-keepalive-requests=0
    # server-option = –keepalive-timeout=7
    # server-option = –max-queued-connections=8
    # server-option = –max-streams=3
    # server-option = –max-threads=5
    # server-option = –thread-idle-time=10
    # server-option = –chuncked-transfer-encoding=yes

    ### Advanced options:
    # server-option = –frame-timeout=5000
    # server-option = –frame-buffers=auto

    ### These options are specific to the HTTP/HTTPS Server
    ### serving custom Web pages only:
    # server-option = –enable-www-server=no
    # server-option = –www-root-path=/usr/share/uv4l/www/
    # server-option = –www-index-file=index.html
    # server-option = –www-port=8888
    # server-option = –www-bind-host-address=#host
    # server-option = –www-password=#password
    # server-option = –www-use-ssl=no
    # server-option = –www-ssl-private-key-file=#path
    # server-option = –www-ssl-certificate-file=#path
    # server-option = –www-connection-timeout=15
    # server-option = –www-enable-keepalive=no
    # server-option = –www-max-keepalive-requests=0
    # server-option = –www-keepalive-timeout=7
    # server-option = –www-max-queued-connections=8
    # server-option = –www-max-threads=4
    # server-option = –www-thread-idle-time=10
    # server-option = –www-chuncked-transfer-encoding=no
    # server-option = –www-set-etag-header=yes
    # server-option = –www-webrtc-signaling-path=/webrtc

    ### Other options:
    # server-option = –editable-config-file=#path
    # server-option = –enable-control-panel=yes
    # server-option = –enable-rest-api=yes

    Reply
    1. Wojciech Domski Post author

      Wow. Please do not past such long config files. Thanks!
      I have one other idea. Could you show me the file permissions and ownership of your cert files? I think that it might be the issue. Also what says uv4l log file?

  3. Sean

    I am so sorry… I’ve never posted before and not sure about etiquette. I’ll make a note.

    I gave full permissions to the selfsigned certificates on each Pi. This did not help.

    I found this out from the RPi Videoconferencing Demo OS site (https://www.linux-projects.org/rpi-videoconference-demo-os/):

    “Now it’s the time to install all the required certificates in your browser’s trusted certificate store. There are formal ways to do this from within the browser, but perhaps the most practical way is the following. Open the browser and visit the following three URL‘s one at a time, in this exact order: https://:8889 (blank page), https://:8080 and https://. For each of the three contacted HTTPS servers above the browser will ask you to add a security exception to the self-signed SSL server’s certificate, so that it can whitelist them once for any future use. You must accept the certificates before doing anything else.”

    Going to each Pi’s /stream/webrtc website from the other Pi and then accepting the “dangerous” site seemed to get it to work somewhat though the local broadcast is not showing and only one channel of audio is working (dangerous site setting in Chromium is turned on). May be tied to the SSL certificates somehow on each again? Don’t know. Any thoughts?

    Thanks for the ideas and help.

    Reply
  4. Sean

    Error codes from Chromium when connected:

    ERROR:video_capture_device_factory_linux.cc(132)] Not implemented reached in void media::GetSupportedFormatsForV4L2BufferType(int, media::VideoCaptureFormats *)
    ERROR:video_capture_device_factory_linux.cc(96)] Not implemented reached in std::list media::GetFrameRateList(int, uint32_t, uint32_t, uint32_t)

    and

    ERROR:h264_decoder_impl.cc(328)] avcodec_decode_video2 error: -1094995529

    UV4L Error log:

    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Camera ready!
    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Camera successfully initialized. Total memory available to the GPU: 192M
    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Close down completed, all components disconnected, disabled and destroyed
    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Camera ready!
    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Camera successfully initialized. Total memory available to the GPU: 192M
    Oct 6 10:47:11 raspberrypi uv4l[329]: [driver] Close down completed, all components disconnected, disabled and destroyed
    .
    .
    .

    Reply
  5. Sean

    I am so sorry… I’ve never posted before and not sure about etiquette. I’ll make a note.

    I gave full permissions to the selfsigned certificates on each Pi. This did not help.

    I found this out from the RPi Videoconferencing Demo OS site (https://www.linux-projects.org/rpi-videoconference-demo-os/):

    “Now it’s the time to install all the required certificates in your browser’s trusted certificate store. There are formal ways to do this from within the browser, but perhaps the most practical way is the following. Open the browser and visit the following three URL‘s one at a time, in this exact order: https://:8889 (blank page), https://:8080 and https://. For each of the three contacted HTTPS servers above the browser will ask you to add a security exception to the self-signed SSL server’s certificate, so that it can whitelist them once for any future use. You must accept the certificates before doing anything else.”

    Going to each Pi’s /stream/webrtc website from the other Pi and then accepting the “dangerous” site seemed to get it to work somewhat though the local broadcast is not showing and only one channel of audio is working. May be tied to the SSL certificates somehow on each again? Don’t know. Any thoughts?

    Thanks for the ideas and help.

    Reply
    1. Wojciech Domski Post author

      Could you do a quick test for me? Please run just the stream via HTTPS and tell me if you can see anything.
      Giving all permissions to certificate files is not necessary the best idea. But maybe it is not the case here. If you run the test get back here with results and we will figure out what to do next.

  6. Bercik

    Cześć,
    Nie bardzo mogę jakoś tego rozkminić. Widzę, że jest wersja na x86. Czy jeśli zainstaluję na VPSie to jak wrzucić strumień AV do serwera? Czy jest jakiś dodatkowy zewnętrzny encoder na modłę ffmpeg, żeby go przesłać do serwera czy kodowanie sygnału jest realizowane lokalnie, po stronie serwera? A może w ogóle coś pomieszałem?

    Reply
    1. Wojciech Domski Post author

      Nie bardzo rozumie jaką masz sytuację. Chcesz wrzucać obraz na serwer VPS i dalej go wewnątrz streamować?
      Prosiłbym również o pytania w języku angielskim dzięki temu większej liczbie osób mogę się przydać ewentualne spostrzeżenia.

  7. Sean

    When I call from A to B:

    A shows B’s video but no sound from B and no local video for A.
    B shows no video, but A’s sound is sent and, also, there is no local video for B.

    A’ camera flickers for a moment then stops when calling B.
    B’s camera stays on for duration of call.

    Reply
    1. Wojciech Domski Post author

      Thanks! To just eliminate one thing please run only the video stream not the Web RTC. To be honest I never played with Web RTC on Raspberry Pi. This way we will be sure that video streaming is source of the problem or not.

  8. Pentti

    Hello!

    I ran into a problem with the signing command for a new certificate to use HTTPS connection:

    (sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 100)

    I got an error message stating:

    “x509: Cannot open input file new.cert.csr, No such file or directory”
    “x509: Use -help for summary”

    I was wondering should I have such file on my Raspberry by default or is it something which is created during this process?

    Reply
  9. Pentti

    Thanks, I managed to sign the keys and I didn’t have any error messages, but now when i tried to connect with https i got a secure connection failed stating that: “SSL_ERROR_RX_RECORD_TOO_LONG”. At least the keys did something but I still am unable to connect to UV4L via https connection. Any advice?

    Reply
  10. Idle

    Thanks Wojciech, great post and helped get me going.
    One minor thing to mention is that rc.local ends with an `exit 0` by default, so anything just appended to it wouldn’t be reached.

    Has anyone had success getting an iPad or iPhone to connect using WebRTC? In theory it’s supported by Safari since iOS 11, but their support is slightly non-standard (only h264, no VP8, etc)

    Reply
    1. Wojciech Domski Post author

      Glad to hear that!
      Yes you are right about the rc.local. I believe that there is even a comment in every rc.local file about that 😉
      As for the WebRTC I have never used it since I didn’t need it.

  11. Rafał Siwy

    Świetny manual
    Wszystko działa jak należy dopóki mój Pi jest headless.
    Kiedy podłączę monitor hdmi – stream leci właśnie na niego a na porcie 8080/stram nie mam nic…
    Jak to skonfigurować żeby stream zawsze był wysłany do przeglądarki która go wywołuje a nie na lokalny display?
    Pozdrawiam

    Reply
    1. Wojciech Domski Post author

      Dzięki!
      Ciekawą rzecz opisujesz. Również używam RPi, jako headless i nie spotkałem się z taką sytuacją, jaką opisujesz. Będę musiał sprawdzić. Jednakże, wydaje mi się to mało prawdopodobne, że video kamery przekazywane jest na wyjście HDMI. Możliwe, że z nowymi wersjami uv4l dodali coś takiego w opcjach pliku konfiguracyjnego. Ja w momencie, w którym aktualizuję uv4l zostawiam stary plik konfiguracyjny. Wrzuć swój plik od serwera uv4l na jakiegoś pastebin’a może będę w stanie pomóc.

  12. rapha

    hey. dzieki za pomoc w zainstalowaniu certifikatu i HTTPS!
    Inne pytanko. U mnie chodzi video stream bez zadnych problemow. Ale to tylko video. Potrzebowalbym jeszcze do tego sound z mikrofonu usb. Inaczej nie moge sobie wyobrazic w jakim wypadku kogos interesuje tylko wizja bez glosu…

    Reply
    1. Wojciech Domski Post author

      UV4L bezpośrednio nie oferuje przesyłania dźwięku. Jednakże, możesz spróbować skonfigurować Web RTC, czyli dwukierunkowy kanał z obrazem i dźwiękiem. Z tego co piszesz to taka funkcjonalność Ci będzie odpowiadać.

  13. Nishad

    Hi Domski

    Great article.
    I wanted have the streaming from rpi to my Janus web server or any other server. If you could help me, it will be so great.
    I have this uv4l installed in the rpi and janus in a server somewhere.

    Reply
  14. Tom

    When I clicked at „Control Panel”, it says „An error occurred: Operation not permitted”.
    When I clicked go to „http://localhost:8080/stream”, it shows a broken image icon.
    All other things are working.
    Please throw me some light.

    Reply
  15. Daniel

    I just installed uv4l and everything that comes with it + setup ssl correctly. I’m testing a two way audio communication over webrtc by running this command:

    sudo uv4l –driver dummy –enable-server –server-option=–enable-webrtc=yes –server-option=–enable-webrtc-video=no –server-option=–use-ssl=yes –server-option=–ssl-private-key-file=/etc/uv4l/selfsign.key –server-option=–ssl-certificate-file=/etc/uv4l/selfsign.crt

    im then accesing the demo page and everything ok but the problem is the audio streaming by client to server. In particular the audio from server (server -> client) is ok, but the inverse (client -> to server) not working (using firefox as browser and permissions to mic are already added). Testing the “Call” on the server it’self works perfectly (both mic and speaker). What could be the problem?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.