Streamer une caméra sur internet

J’avais des caméras raspberry pi. Toutes les minutes je prenais une photo et je la stockait pour ensuite l’afficher sur mon site internet. Ayant refait l’isolation de ma maison, je n’ai jamais pris la peine de les remettre, mais suite à la demande de plusieurs voisins qui appréciaient de venir sur mon site pour voir la situation à Montpreveyres, je me suis dirigé vers une nouvelle solution.

Installation de la caméra

J’ai acheté une caméra sur digitec à 80.- de très bonne qualité, la Reolink RLC-410W . J’ai mis sur mon routeur une ip statique. La caméra n’est pas ouverte sur l’extérieur.

Après l’avoir installée, j’ai cherché le lien RTSP:
rtsp://{user}:{password}@{ipdelacaméra}:554/h264Preview_01_main
Beaucoup de caméras ont un lien similaire!

On peut ouvrir ce lien RTSP par exemple dans VLC (media, open network stream). Mais le lien RTSP ne peut pas être vu directement dans un navigateur.

Installation d’un logiciel pour streamer la caméra sur un browser

Il y a un logiciel opensource permettant de voir une caméra sur un site internet (depuis un serveur linux): RTSPtoWeb. J’ai crée un nouvel utilisateur sur mon serveur et je lance ce programme depuis cet utilisateur. ( go run *.go ).

On peut rajouter différents flux sur {ipdevotreserveur}:8083 – ce port n’est pas ouvert sur l’extérieur! J’ai donc rajouté dessus mes différentes caméras.

Ouverture sur l’extérieur (sur https / sécurisé).

J’ai lié mon nom de domaine cam.nuage.ch à une ip dynamique correspondant à mon système à la maison (CNAME). J’ai aussi configuré mon routeur pour rediriger le port 80 (http) et 443 (https) sur ce système.

J’ai ensuite rajouté depuis apache2 (le serveur d’application que j’utilise) un proxy sur ce port.
Je demande un mot de passe sauf pour le stream de la caméra!

Dans /etc/apache2/sites-available/monsite.conf, j’ai mis:

<VirtualHost *:80>   
    ServerAdmin gabriel.klein@nuage.ch
    ServerName cam.nuage.ch

    <Location />
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/htpasswd
        Require valid-user
        satisfy any
        deny from all
    </Location>

    <Location /stream/19c5065b-8904-4293-9fe3-87858b5c0a8d/channel/0/webrtc>
        Allow from All
        Satisfy Any
    </Location>

    <Location /stream/19c5065b-8904-4293-9fe3-87858b5c0a8d/channel/0/hls>
        Allow from All
        Satisfy Any
    </Location>

    ProxyRequests On
    ProxyPreserveHost on

    ProxyPass / http://localhost:8083/
    ProxyPassReverse / http://localhost:8083/


    ErrorLog /var/log/apache2/error-cam.nuage.ch.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/apache2/access-cam.nuage.ch.log combined
<VirtualHost>

Remplacez 19c5065b-8904-4293-9fe3-87858b5c0a8d par votre propre identifiant de caméra!

Je redémarre mon serveur

/etc/init.d/apache2 reload).

Ensuite je sécurise mon serveur de caméra avec

certbot -tvv –apache -m gabriel.klein@nuage.ch –redirect –hsts –uir –reinstall -d cam.nuage.ch

Je peux maintenant accéder à mon flux vidéo depuis

https://cam.nuage.ch/stream/19c5065b-8904-4293-9fe3-87858b5c0a8d/channel/0/hls/live/index.m3u8

Rajouter ma caméra sur wordpress / mon site internet

J’ai essayé WebRtc, mais malheureusement pas compatible avec mon téléphone et certains navigateurs. Donc je me suis dirigé sur le format HLS.

J’ai rajouté dans ma page wordpress un block html.

<input type="hidden" name="hls-url" id="hls-url" value="https://cam.nuage.ch/stream/19c5065b-8904-4293-9fe3-87858b5c0a8d/channel/0/hls/live/index.m3u8">

<p><video id="wc-video" autoplay="" muted="" playsinline="" controls="" style="max-width: 100%; max-height: 100%;"></video></p>

<script>

      document.addEventListener('DOMContentLoaded', function () {
        const videoEl = document.querySelector('#wc-video')
        const hlsUrl = document.querySelector('#hls-url').value

        if (Hls.isSupported()) {
          const hls = new Hls()
          hls.loadSource(hlsUrl)
          hls.attachMedia(videoEl)
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
          videoEl.src = hlsUrl
        }
      })


</script>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

Remplacez 19c5065b-8904-4293-9fe3-87858b5c0a8d par votre propre identifiant de caméra!

Et succès (après quand même plusieurs heures de recherche….).

J’espère que cet article va vous aider, même si il reste techniquement assez complexe.

Réparation de mon boiler

Depuis quelques mois mon chauffe-eau pompe à chaleur / boiler (Atlantic Explorer) me faisait parfois une erreur bizarre – erreur 22.

Parfois on pouvait le relancer en le déconnectant et en le reconnectant, solution temporaire – non idéale.

En cherchant un peu (et en utilisant le mode test sur le contrôleur du boiler), j’ai remarqué que le ventilateur en mode “lent” ne tournait plus. En le tournant a la main, on pouvait “démarrer la rotation” et une fois lancé il ne s’arrête plus. Je n’ai pas de friction ou de bruit laissant penser qu’il y a un problème de frottement.

A l’intérieur du boiler, on voit que le ventilateur est branché à une grosse boîte noire (condensateur). Cette boîte peut être facilement débranchée! Sur cette boîte, la capacité du condensateur est de 1.5μF – celui qui est à côté fait 4μF. En vérifiant avec mon voltmètre – surprise! La capacité n’est que de 0.15μF, celui d’à côté ne fait que 2μF au lieu de 4μF.

Cela explique pourquoi avec un courant alternatif le ventilateur n’arrive pas à tourner. Vu la facilité avec laquelle on peut changer cette capacité, c’est une panne qui doit être relativement commune dans ce produit!

J’ai demandé une offre Atlantic qui ne m’a renvoyé vers ses revendeurs… qui m’ont toujours pas répondus après une semaine 🙂 Finalement j’ai acheté sur “la bonne combine”, prix 5.- (5€). On peut trouver une autre version compatible sur conrad.ch.

Après remplacement, mon boiler marche très bien depuis 2 jours!

Plus d’information sur le rôle du condensation dans un moteur monophasé.

Use Let’s Encrypt to secure Linux servers for free

A SSL web certificate is a way to secure your website by encrypting the communication between you and the computer a server is running on and be (almost) sure that what you see was not modified. You see that a communication is encrypted when you have a “https://” at the beginning of a website.

As an example, my website is secured as you see in the URL.

Let’s Encrypt is a free certificate provider.

Why should you secure your site?

  • Because it’s free with Let’s Encrypt! It was very expensive a few years ago, but now you can get a good certificate for free.
  • Because your site looks more serious when running on https://
  • Because you care about your visitors.
  • Because it’s easy 🙂 setting a SSL certificate was really hard a few years ago.
  • Because you will get a higher ranking on Google and other search engines.

How to secure it if you are just paying a hosting provider?

If you don’t manage your domain (what most people do), many providers provide a let’s encrypt certificate for free with just a few clicks!

As an example

How to secure your domain if you have a VPS or dedicated server?

This tutorial will focus on debian / ubuntu using apache2.

The first step is to install a virtual host running on http (out of the scope of this article). You should be able to access your website using http://www.yourdomain.ch

You then need to install certbot and python3-certbot-apache.

apt-get install certbot python3-certbot-apache

You can then easily create a https version of your domain running.

sudo certbot -tvv --apache -m you@yourmail.com --redirect --hsts --uir --reinstall -d www.yourdomain.ch

If you have multiple alias of the same domain.

sudo certbot -tvv --apache -m you@yourmail.com --redirect --hsts --uir --reinstall -d www.yourdomain.ch -d yourdomain.ch

I highly suggest to keep different domains separated! Run the same command on all of them and don’t use alias for domains that have different purposes.

And restart apache using

sudo service apache2 restart

Now when you write http://www.yourdomain.ch, you should be automatically forwarded to https://www.yourdomain.ch

The certificate are only valid 3 months… but it’s a good thing 🙂 You need to have a script to renew the certificate automatically.

Test that the “renew command” is working correctly.

sudo certbot renew

You should see something like: Cert not yet due for renewal.

Add a cron to the user root and add a line to update the certificate. The certificate is updated only if needed!

sudo crontab -e
34 02 * * * (certbot renew; service apache2 restart) &>>/tmp/certbot.log

Now your certificate is (should) setup correctly, and you don’t have to care about it anymore.

Import old DV videos to your computer (Linux)

The goal of this article is to explain how to transfer Digital Videos (DV) from your camera to your computer on Linux.

In the past I have used a digital camera from Sony (DCR-PC101E). The movies are stored in digital video format and are transferred using FireWire.

The problem nowadays is the progressive deprecation of FireWire, DV format and way to play back videos. Same problem with the tape… they slowly degrade over time…. The other problem is some videos that are only available on my camera with no copy in other places.

How to transfer videos from my camera to my computer?

That’s the first question 🙂 happily I still have an old computer with a FireWire port (and some FireWire connectors…).

Using dvgrab I was able to import files from my camera to my computer.

dvgrab --autosplit --timestamp somefilename-

You end with very big files 🙂 In my case 1GB for 5 minutes of video.

How to transform these files to make them more “modern world” friendly?

The files are very big! About 10-15 GB for 60-90 minutes of recording. How can we make them smaller?

First I suggest to store a copy of the DV files in another place like an USB key and store this key in your archives. You may be interested to transform them back in 10, 20, 30 years 🙂

My goal was to transform them in the mp4 format – in particular h.264. Happily a very cool command on linux is ffmpeg to do that! I have decided not to use h.265 – that compress ~2x more for the same quality – as it is not yet available on many devices.

I tried many way of converting the video… but my issue was that the videos were interlaced. When using software to convert them, I often end with videos before and after conversion that look like.

Source DV file
Compressed in MP4 without filter to deinterlace them.

It doesn’t look really nice when you play them… and the MP4 compression algorithm is not able to do a really job. You have to deinterlace them. Happily there is a nice parameter in ffmpeg that do a decent job: Yadif

After many tests, here is the command I use

ffmpeg -i 'inputfile.dv' -vf yadif -vcodec libx264 -preset veryslow -profile:v main -level 3.0 -pix_fmt yuv420p -crf 23 -x264-params ref=4 -acodec aac -ac 2 -ar 44100 -ab 128k -nostdin 'output.mp4'

https://trac.ffmpeg.org/wiki/Encode/H.264

If you want to compress a bit more at the same quality, you can use H.265 – but with the risk of incompatibility on old devices (H.265 is just 5 years old). crf at 28 should visually correspond to libx264 video at CRF 23, but result in about half the file size.

ffmpeg -i 'inputfile.dv' -vf yadif -vcodec libx265 -preset veryslow -profile:v main -crf 28 -acodec aac -ac 2 -ar 44100 -ab 128k -nostdin 'output.mp4'

https://trac.ffmpeg.org/wiki/Encode/H.265 and https://x265.readthedocs.io

You can download a bash script that convert into H.265 automatically here. Copy it in your ~/bin/ folder and call videoCompressH265.sh fileToBeConverted.ext. A file called fileToBeConverted.mp4 or fileToBeconverted_compress.mp4 will be created.

To compress all files in a directory.
ls | while read l; do videoCompressH265.sh $l; done

A 1000MB DV file of 5 minutes of video is transformed to a 70 MB of MP4 file. Playing with the crf parameter, you can even make it smaller but for me it was the best trade of between loose of quality and size.

You can tweak a bit the crf between 17 (visually perfect quality) and 28 (bad quality). The range is exponential, so increasing the CRF value +6 results in roughly half the bitrate / file size, while -6 leads to roughly twice the bitrate.

Same snapshot after compression using this command.

You see that the quality due to the compression algorithm is not as good as the original video… but in reality it’s really hard to see a difference when you see the two videos. You may even prefer the compressed video as it looks less “noisy”.

Example of a door†† before and after compression by the mp4 algorithm. You see the “noise” of the camera in the “uncompressed version”. I personally prefer the “compressed” version.
†

I hope this command is useful and will help you to find the right balance between compression and quality.

Some other commands that may be useful

Join multiple files (fast) (same encoding, resolution): Store in list.txt all the video you want to merge as: file ‘filename’ and run: ffmpeg -f concat -safe 0 -i list.txt -c copy autralieconcat.mp4

Cut videos lossless (fast): ffmpeg -i originalvideo.mp4 -ss 0:0:4 -t 0:1:10 -vcodec copy -acodec copy outputvideo.mp4

Cut videos and compress: Install VidCutter and cut a video into clips. Save projet and open the *.vcp file using a text editor. You will find the start and end of your cuts. Add to your command line -ss (start) and ffmpeg [...] -ss 30 -t 10 [...]. -ss is the start in seconds, -t is the duration. Example: ffmpeg -i imput.mp4 -ss 116.833 -t 1859.617 -vcodec libx265 -preset slow -crf 28 -acodec aac -ac 2 -ar 44100 -ab 128k -nostdin output.mp4