611 private links
Recently installed a new webcam by my office computer. Not long after, a thought materialised: should it not be possible to view the video feed over a remote SSH tunnel?
Indeed, here's one way to do it (I have not bothered connecting to the camera's builtin microphone, but that should be possible):
taha@asks2:~
$ ssh mkem150 "ffmpeg -i /dev/video0 -c:v libx264 -f mpegts -" | mpv -
[file] Reading from stdin...
ffmpeg version 4.4.2-0ubuntu1~18.04.sav1.4 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --prefix=/usr --extra-version='0ubuntu1~18.04.sav1.4' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-crystalhd --enable-libmfx --enable-libsvtav1 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 47325.806919, bitrate: 442368 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 442368 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x564e46b7b780] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x564e46b7b780] profile High 4:2:2, level 3.1, 4:2:2, 8-bit
Output #0, mpegts, to 'pipe:':
Metadata:
encoder : Lavf58.76.100
Stream #0:0: Video: h264, yuv422p(tv, progressive), 1280x720, q=2-31, 30 fps, 90k tbn
Metadata:
encoder : Lavc58.134.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
(+) Video --vid=1 (h264 1280x720 30.000fps)ime=00:00:00.90 bitrate=1983.6kbits/s speed=0.198x
VO: [gpu] 1280x720 yuv422p
Worked without -c:v libx264
, but noticeably poor video quality (pixelation and such).
Does not work if we remove the -f mpegts
argument.
This is a neat way to quickly generate a QR-code, for example to transfer text from computer to phone (thanks to Solène Rapenne for the original idea and implementation). On the phone, you'll of course need to use a QR-reader app, such as Binary Eye.
xclip -o -selection clipboard | qrencode -o - -t PNG | feh -g 600x600 -Z -
Using this command, whatever is in your clipboard will be encoded to QR and displayed on your monitor. Note that xclip
can pull stuff from different clipboards, and in my case the contents were not picked up with -selection default
but -selection clipboard
did the trick.
Linux (well, really the window managers, so X11 and then, i3, Wayland, etc…) have multiple clipboards. The default ones are the Primary selection one, and the Secondary one. The names are historical accidents, but the “primary” one always has a copy of the last text you selected from anywhere, which can be pasted anywhere by clicking the middle mouse button. You just select some text and that’s it - you don’t have to do anything else and you can then middle-click paste this anywhere. The “secondary” clipboard is the “normal” Cut, Copy, Paste, Ctrl+c, Ctrl+v one.
https://duncanlock.net/blog/2022/04/06/using-windows-after-15-years-on-linux/
- i3wm, tiling window manager for X11.
- sway, drop-in replacement for i3wm on Wayland.
- enlightenment, window manager, compositor and minimal desktop. Not tiling. Supports X11, experimental Wayland support.
There are many more window managers. Add more as I (re)discover them.
Guides and how-tos
- Introduction to Ansible playbooks
- Playbooks vs roles, and explain the difference between task, role, play and playbook
- How to install and configure Ansible on Ubuntu 18.04 - DigitalOcean
- Linux hardening using idempotency with Ansible
Ansible playbooks and roles
- I haven't published all roles that I've written, but all the roles that I do publish are collected at codeberg.org/ansible
- Ansible module (Python code) to install R packages, by yutannihilation
- Ansible role to install TeXLive
- https://ansible.jeffgeerling.com/
- https://robertdebock.nl/ansible.html
Related
This could perhaps be a much more stable alternative to my reverse SSH tunnels for keeping connections with various servers, especially desktops inside FM-NET and other machines inside other LANs.
The main downside is that Tailscale is not FOSS. So perhaps we should look for other solutions built on WireGuard, or perhaps learn to configure WireGuard directly.
The command and its typical output (highlights not shown due to technical limitations in Markdown):
me@host:~/ansible/playbooks
$ find . -type f -name "playbook.log" -exec sh -c 'tac {} | grep -m 1 -A1 "^Playbook last committed by"' \; | grep --color -E "^|git/ansible/[A-Za-z]+?/[A-Za-z-]+?.yml|(19|20)[0-9][0-9]-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}"
Playbook last committed by me@host on Fri Apr 17 22:02:15 2020 +0200 (afd13a3b3b3f43d3f84bb16b1c91a6b5bec2cfe1)
2020-04-19 00:40:30,925 p=32526 u=me n=ansible | task path: /home/me/ansible/playbooks/luxor/playbook-host.yml:99
Playbook last committed by me@host on Wed Jan 29 14:34:38 2020 +0100 (5157cd051e276abfe99e93c37a8ad0c79dd4d3dc)
2020-03-29 01:39:34,874 p=14553 u=me n=ansible | task path: /home/me/ansible/playbooks/damietta/playbook-heliopolis.yml:31
Playbook last committed by me@host on Tue Feb 18 17:30:19 2020 +0100 (ae6c02965f4471d8089c5e4d2a427cb0cbfbc6b8)
2020-02-23 19:58:30,188 p=1050 u=me n=ansible | task path: /home/me/ansible/playbooks/abydos/playbook-webserver.yml:35
Playbook last committed by me@host on Sun Jan 5 09:44:27 2020 +0100 (26392ab778deaf86430f36bc7aed942ae04a938c)
2020-01-08 13:26:35,647 p=me u=27195 | changed: [hunan.domain.se -> localhost] => {"changed": true, "cmd": "git log --pretty=\"Playbook last committed by %cn on %cd (%H)\" -1 >> playbook.log", "delta": "0:00:00.003510", "end": "2020-01-08 13:26:35.628135", "rc": 0, "start": "2020-01-08 13:26:35.624625", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
Playbook last committed by me@host on Thu Mar 26 14:57:00 2020 +0100 (2c9aa2030192c2942c5dfb0bcf5976f46fefd774)
2020-04-01 15:44:19,057 p=10821 u=me n=ansible | task path: /home/me/ansible/playbooks/alexandria/playbook.yml:137
The first find
command lists all playbook.log
files below the current directory (recursing into child directories). tac
is the opposite of cat
and lists each file backwards (from last line to first). We use grep
to look for a string ("Playbook last committed") that my Ansible playbooks always insert into the log-file at the end of a run. Note the use of the -A1
flag that gets the matched line and one line after (but because we used tac
, we actually get the line before, which is what we want). The final grep
uses extended regular expressions (-E
) to color highlight several parts of the output (while displaying all of the output, that's what the initial caret does - it effectively matches all lines).
Pretty neat, if I may say so myself.
Some of the refs I consulted to figure out this one-liner:
https://serverfault.com/questions/197123/getting-the-last-match-in-a-file-using-grep
https://unix.stackexchange.com/questions/112159/grep-from-the-end-of-a-file-to-the-beginning
https://stackoverflow.com/questions/307015/how-do-i-include-a-pipe-in-my-linux-find-exec-command
https://superuser.com/questions/914856/grep-display-all-output-but-highlight-search-matches
https://unix.stackexchange.com/questions/366/convince-grep-to-output-all-lines-not-just-those-with-matches
https://unix.stackexchange.com/questions/37313/how-do-i-grep-for-multiple-patterns-with-pattern-having-a-pipe-character
https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended