Archive for September, 2021

HOWTO: Using your GoPro Hero8, 9 and 10 as a webcam on Linux over USB-C WITHOUT the Media Mod. Now you can!

This was a challenge/goal of mine and true to form, I rarely give up until I’ve figured something out, or coded a workaround. As Mark Rober so eloquently said, 2m10s into this video about the NICEST Car Horn Ever:

“The good news is that as an engineer, if something isn’t exactly how you want it… you just make it exactly how you want it.”

Some points straight from the start:

  • The GoPro does not support connecting TO WiFi networks. Full stop. Period. It can’t be a wireless client, only an AP.
    • The hardware is fully capable of connecting to existing WiFi networks but GoPro restricts this, and there’s no foreseeable way around it without hacking into the firmware and reflashing it with a replacement.
    • You can connect TO the GoPro as it presents its own WiFi network, but you cannot connect your GoPro to any existing WiFi network in range.
    • A $12 smart plug can connect to an existing WiFi network, but a $400 action cam from GoPro cannot. #facepalm
  • To connect the GoPro via HDMI directly, you need their $79 Media Mod hardware.
    • It’s essentially a frame that wraps around the GoPro, and exposes USB-C, micro-HDMI and an audio port for the device.
    • All of these are accessible via the single USB Type-C port that the Media Mod docks into. A USB Type-C to micro-HDMI adapter will not work when plugged into the bare GoPro USB Type-C port.
    • I tried 3 different models, they were all rejected and ignored.
  • GoPro Hero 5, 6 and 7 models supported native HDMI out. The Hero 8, 9 and 10 do not.
    • You need the additional Media Mod to get native HDMI out.
    • Anything greater than 1080p will require HDMI out.

So let’s dive in and get this working!

First thing you’ll need, is a USB cable. This can be a native USB Type-C to USB Type-C cable, or USB Type-C to USB Type-A, whatever your specific hardware (laptop or PC) requires.

You’ll want this cable to be relatively long, if you’re using this as a webcam, so you can position it where you need it, without being limited by cable length. There are an infinite number of choices and colors for these cables on Amazon and other retailers.

Just make sure you get a good quality, shielded cable for this purpose.

Once you have that, you’ll need to open up the battery door and pop that off, or, alternatively you can leave it ajar, with the battery inserted. I don’t like the door hanging half-off at a 45-degree angle, so I pried mine off. Since I also own the Media Mod, this was something I’ve already done 100 times.

To remove the door, you just open the door all the way until it won’t go any higher, than you give it gentle twist from front of camera to back, and it will pop off the hinge. If you’re used to how a Garmin watch band is removed from the watch face, it’s similar to that.

Next, you’ll want to go into the GoPro settings, and make sure the connection type is not “MTP” (used when mounting your GoPro as a “storage” device to retrieve photos, videos from your device. We’re not doing that here, so go the menus and swipe up, go to Settings ? Connections ? USB Connection ? GoPro Connect.

Now let’s make a quick change to your host’s networking to support giving this device a DHCP address when you connect it to your machine. To do that, you’ll use one of the following constructs:

If using netplan,. your configuration should look something like this, in a new file called /etc/netplan/02-gopro.yaml:

network:
  version: 2
  renderer: networkd
  ethernets:
    usb0:
      dhcp4: yes

If you’re using the legacy ifupdown style configuration, you’ll want to add the following to /etc/network/interfaces (or /etc/sysconfig/network for RPM-based distributions):

auto usb0
iface usb0 inet dhcp

To activate that, you can do a sudo netplan apply and it will render that configuration and restart systemd-networkd for you to acquire a DHCP lease when the camera is plugged in via USB. For legacy ifupdown, you’ll want to just restart your networking service with systemctl or service.

When you do plug your camera in, you should see something like the following in dmesg:

[20434.698644] usb 1-1.4.2: new high-speed USB device number 24 using xhci_hcd
[20434.804279] usb 1-1.4.2: New USB device found, idVendor=2672, idProduct=0052, bcdDevice= 4.04
[20434.804283] usb 1-1.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[20434.804284] usb 1-1.4.2: Product: HERO9
[20434.804285] usb 1-1.4.2: Manufacturer: GoPro
[20434.804285] usb 1-1.4.2: SerialNumber: Cxxxxxxxxxx123
[20434.811891] cdc_ether 1-1.4.2:1.0 usb0: register 'cdc_ether' at usb-0000:00:14.0-1.4.2, CDC Ethernet Device, 22:68:e2:ca:88:37

If you plugged in your camera and netplan/ifupdown assigned it a DHCP lease, you should now see something like:

15: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
    link/ether aa:80:23:e6:6d:9a brd ff:ff:ff:ff:ff:ff
    inet 172.23.141.54/24 brd 172.23.141.255 scope global dynamic usb0
       valid_lft 864000sec preferred_lft 864000sec
    inet6 fe80::a880:23ff:fee6:6d9a/64 scope link 
       valid_lft forever preferred_lft forever

You’re almost there!

Now we need to check out an upstream Github repository that includes some helper scripts/code to bring this camera online, attach a running ffmpeg process to it, and begin streaming it to a device in /dev/.

Clone the gopro_as_webcam_on_linux repository somewhere on your machine that will persist (not in /tmp which gets purged at each new boot).

$ git clone https://github.com/jschmid1/gopro_as_webcam_on_linux
Cloning into 'gopro_as_webcam_on_linux'...
remote: Enumerating objects: 78, done.
remote: Counting objects: 100% (78/78), done.
remote: Compressing objects: 100% (57/57), done.
remote: Total 78 (delta 34), reused 46 (delta 17), pack-reused 0
Unpacking objects: 100% (78/78), 32.04 KiB | 1.69 MiB/s, done.

If you go into that newly cloned repository and run the following command, you should see a new device get created that you can talk to. Make sure to change the IP to the one you observed when running the ip a s usb0 command above (bolded above and below for emphasis).

$ sudo ./gopro webcam -i 172.23.141.54 -a -n 
Running GoPro Webcam Util for Linux [0.0.3]

       Launch Options     
==========================
 * Non-interactive:  1
 * Autostart:        1
 * Preview:          0
 * Resolution:       3840p
 * FOV:              linear
 * IP Address:       172.23.141.54
==========================

v4l2loopback is loaded!
v4l2loopback was unloaded successfully.
v4l2loopback was successfully loaded.

Further down in the output, just before it begins to launch ffmpeg and start encoding the stream, you should see two lines that look like this:

[swscaler @ 0x56073e173740] deprecated pixel format used, make sure you did set range correctly
Output #0, video4linux2,v4l2, to '/dev/video42':

That /dev/video42 is the important part for your streaming tools. If you use Open Broadcaster Studio (OBS), that’s the camera device you’ll want to connect to when you choose “Video Capture”, when creating a camera in your scene.

If you want to preview/play this stream that ffmpeg is creating for you, you can use mplayer to do that, as follows:

mplayer tv:// -tv driver=v4l2:device=/dev/video42 outfmt=mjpg

This will open a new, live, preview window you can use to fine-tune your scene, layout and positioning of the camera.

I have my camera sitting on an extremely long microphone boom arm with an extra ‘forearm’ to reach up and over my monitors from behind (many thanks go to ATARABYTE for this idea and the link to the Heron 5ft Articulating Arm Camera Mount [note: affiliate link to give her credit]).

So that’s it!

Once you have the camera on the network with an IP you can route to, you can use the gopro script from Joshua Schmid’s GH repository to create a device that can then be used by ffmpeg or OBS to stream that camera’s feed to other locations.

Keep in mind, there is a subtle 0.5s delay, but it’s not terrible. If you’re recording the stream, you can adjust the audio so it lines up in OBS with the latency/delay features. If you’re using this live, I would recommend not using this as a front-facing camera, and only use it as a secondary/backup or overhead cam (my specific use case is as an overhead cam for close-up work).

The GoPro, being an “Action Cam” also does not have autofocus, so anything closer than about 12″, will start to blur out. If you need autofocus, consider using a mirrorless DSLR camera and a decent lens. To connect that to your Linux machine, you can use an Elgato CamLink 4k device. I use this as well, with my main streaming setup, and it works fantastic on Linux, with no drivers or setup required.

HOWTO: Remove Burn-in and Ghosting on your LCD Panel

With the pandemic continuing and no real end in sight, those of us who work from home are putting in extended hours at work, and extended hours on our computers and office equipment, including our eyes and monitors.

My monitors have started to develop burn-in and ghosting on parts of the screen where I keep common apps running like my browser windows, chat apps and other services.

Modern monitors lack the “degaussing” feature that was popular years ago on older CRT monitors to help remove those ghost images.

Fear not! There’s still a way to help remove ghosting, and it doesn’t involve running a screensaver! You can run an “LCD scrub” behind your windows as you work (or in a cron job, systemd unit or other time-based scheduler). Here’s how!

First, install the xscreensaver-data-extra package from your favorite package archive. In Ubuntu, that’s a simple sudo apt install xscreensaver-data-extra command. Then, run the following one-liner to target your ‘root’ window (Desktop):

/usr/lib/xscreensaver/lcdscrub -random -noinstall -window -window-id \
   $(xwininfo -root -tree | grep Desktop | awk '{print $1}') -spread 10

This will run the lcdscrub utility in your ‘root’ display, scrubbing the screen behind all of your current windows. Of course, you can close those windows around and make it more effective.

Here’s a quick video showing how this works:

lcdscrub saving my desktop display from ghosting and burn-in

Running this on a regular basis is a good idea, so you can avoid the kind of burn-in that can prematurely age your display. Since it may be difficult (or expensive) to replace monitors with chip and electronic shortages, you’ll want to extend the life as long as you can, before inventory becomes available for replacements.

Using an Elgato Stream Deck XL for Desktop and Livestream Productivity

I recently rebooted my home office to support a lot more professional, studio-quality AV.

This included moving away from the onboard laptop webcam to a dedicated USB webcam for better quality. I chose the Logitech BRIO Ultra HD because it could do 1080p as well as 4k, if needed, and had a very wide FOV. I also moved from a USB microphone to an XLR microphone. I originally started with an Audio -Technica AT2020USB (Cardioid Condenser) USB mic, but moved over to the XLR version of the same mic, the Audio-Technica AT2041SP (Condenser) mic.

At the same time, I added an audio mixer, a Mackie ProFx6 v3. I originally bought the Focusrite Scarlett 18i8 (3rd Gen), but I could never get it to do anything at all, and even with a TRiTON FedHead attached, the audio was so low, and full of hissing background noise, it was unacceptable.

So that covered audio and video, but I needed a better way to present these into my meetings, work and personal, using Zoom, Teams, Google Meet and other tools.

Enter OBS, the Open Broadcaster Software. Since I use Linux, a lot of the free and commercial Windows alternatives were off the list, so I had to use OBS. With OBS, I can connect my cam to my Linux laptop and then create a ‘virtual’ camera that would be shared out via OBS, that I can configure in each video app I need. This allows me to add ‘scenes’ (more on this in another blog post) as well as overlays and other features to my video feed.

Currently, I have several cams set up, and can switch between them with a single keystroke, mouse click, or (as I’ll explain shortly), with a button-press on my Elgato Stream Deck XL. I have these set up with captions, an active clock (ticking each second visibly on my camera) and some other features.

I still use the Logitech Brio camera, but it’s now a secondary cam, replaced by a new primary cam, the Sony A6100.

I bought this camera with the kit lens, and quickly realized I needed a better f-stop than the kit lens had. I wanted to go down to f/1.4 or f/1.2, from the f/3.5-5.6 that the kit lens had. I upgraded that lens to a Sigma 16mm f/1.4 about a week later, and I couldn’t be happier with the results. It’s shockingly crisp and the AF (AutoFocus) is the fastest I’ve seen on a lens in this class.

There’s much more to my environment I’ll talk about later, but this is the main pillars of my tools and studio.

I don’t have the mic going through OBS at the moment, but that’s coming soon. Once I do that, I can do some pre-processing of the audio and clean up background noise, increase gain and make the sound quality MUCH better.

That’s the high level change: Upgraded cams, mic, added a mixer, routed it all through OBS and manage it there. There’s so much that can be done with OBS, and I’ll do a whole series on that later.

Now let’s talk about how I’ve incorporated the Stream Deck XL into my workflow. This is normally a Windows/Mac only device, with dedicated software for those platforms. That won’t work for me, since I use Linux for everything. I found Timothy Crosley‘s project ‘streamdeck-ui‘, a Python project, does almost exactly what the Elgato native software does, with some additional features that Elgato doesn’t have. It was drop-in simple to get it up and running.

The XL has 32 buttons on its face, and with streamdeck-ui, I can have up to 10 pages of actions for those buttons, giving me a total of a whopping 320 possible buttons/actions to choose from.

I started configuring the first page for the most-used actions I would need with OBS, including:

  • Launch OBS itself
  • Open my normal work/desktop productivity apps, including Mattermost, Slack, Telegram, IRCCloud, Discord
  • Open media apps I need; Google docs/sheets/drive, Spotify, Pandora, Dropbox and others

Then the other fun began. I wanted a way to target specific applications and stuff keystrokes into those apps. The first need was to be able to DM any of my teammates with a single button press.

I needed to find a way to “find” the Mattermost (or Slack) window on the desktop, target that window, raise it, then send keystrokes to that window, for example /msg SuperManager Good morning! I have a question...

To do this, I needed to create a shell script as a wrapper around wmctrl, xwininfo, and xdotool to do what I needed. I had to create a second script, similar to the first, to target specific public channels in Mattermost. Each of these is subtly different; one uses /msg and the other uses /join ~$channel before stuffing in keystrokes for actions.

Here’s an example:

#!/bin/bash 

dm=$1
wmctrl -xa Mattermost 
mm=$(xwininfo -root -tree | awk '/Mattermost/ {print $1}'); 
xdotool windowfocus ${mm} type "/msg $dm";
xdotool windowfocus ${mm} key KP_Enter

I can then call that from a streamdeck-ui button action with: mm-dm @SuperManager and it will find and open Mattermost, target that private conversation window, and I can start typing away.

The next extension of this of course, was to create custom buttons on the Stream Deck itself, for each member of my team. I have a separate page (32 buttons) with photos from our internal corporate directory, one photo per-button, for each member of my team, cross-teams, management and so on. A single press on their photo, will find Mattermost, target that window, and begin a DM with them.

It’s the Stream Deck equivalent of a visual phone directory.

I also created forward/back buttons for switching between pages on the XL, which you can see here in the screenshot below. I have the ‘Switch Page’ action configured to switch to the previous or next pages, as needed. On Page 1, there’s only one button there, ‘Next Page’, which switches to Page 2. On all other pages, it goes forward or back, and page 10 wraps back to Page 1.

I also have the XL set up for my streaming environment, Govee Lyra and Govee Aura lights that live behind me on camera, uxplay for using my iPad Mini as a ‘lightboard’ during meetings. Here’s an example of how this looks with an actual glass lightboard.

I figured out how to do this without any of the complexities of actual glass, markers or extra hardware. Just Linux, OBS, my iPad, Stream Deck and uxplay. Works fantastic! I’ll do a whole post on that later.

The most-recent addition I figured out, literally this afternoon after fumbling to find my active Meet window and mute my mic, was how to use a single button on the Stream Deck XL, to mute and unmute my Google Meet calls. It’s similar to the way I’m targeting my Mattermost (Slack, Telegram, IRCCloud, etc.) windows, but instead, I’m targeting the top-most Google Chrome window that has Meet running in it. The script, tied to a ‘mute/unmute’ button, looks like this:

wmctrl -xa Chrome
chrome=$(xwininfo -root -tree | awk '/Meet .* Google Chrome/ {print $1}')
xdotool windowfocus ${chrome} key "ctrl+d";

That’s it. I configured streamdeck-ui with a single button press to toggle that on and off.

So that’s it for now, some great ideas to use a Stream Deck XL along with your regular desktop apps and productivity tools, to enhance even more productivity out of your environment.

Bad Behavior has blocked 885 access attempts in the last 7 days.