-
Booting Crankshaft-NG from USB
09/01/2024 at 22:04 • 0 commentshttps://getcrankshaft.com/ Is a software bundle for using a Raspberry Pi and attached touchscreen display as a DIY Android Auto head unit. The project has been dormant for a couple of years, but that hasn't stopped me from poking around at it. One of the clever things they do is mount the boot and root filesystem read-only to minimize the chance of SD card corruption, which is one of the banes of SD cards with Linux. The selectively make the filesystems writable when they need to store some persistent thing, like a config update. The usual reason for wanting to operate from a USB thumb drive is minimized. However, because of the physical geometry of my screen and the case I printed for it, it's a tremendous amount of trouble to get the SD card out and back in once things are assembled.
So, I want to skip the SD card and operate directly from a USB thumb drive. I'm using a Raspberry Pi 3B+, which can boot from USB out of the box. Some things in the Crankshaft layer assume you are using an SD card and prevent booting and operating from USB. I've worked through the changes needed to get it working, and here are the details.
There are the usual two Linux filesystems involved: the boot filesystem and the root filesystem. Crankshaft assumes those are /dev/mmcblk0p1 and /dev/mmcblk0p2 (SD card partitions), respectively. The USB drive will typically have those same filesystems on /dev/sda1 and /dev/sda2, respectively. That's not guaranteed if you have other things involved, so it's better to identify them by the partition UUID. I assume you're doing your image-making on some Linux machine. With the USB drive plugged into that machine, you can get the partition UUIDs via the blkid command:
$ blkid /dev/sda1: LABEL_FATBOOT="boot" LABEL="boot" UUID="BBBB-AAAA" TYPE="vfat" PARTUUID="abcdefab-01" /dev/sda2: LABEL="rootfs" UUID="ffffffff-eeee-dddd-cccc-bbbbbbbbbbbb" TYPE="ext4" PARTUUID="abcdefab-02"
The thing we're interested in is the PARTUUID. The following steps assume you have the partitions of your thumb drive actually mounted on some Linux machine. You may need to be root to do some of the steps, depending on your local configuration of that Linux machine.
Caution: It's possible to end up with partitions on different devices having the same partition UUID. Using both devices on the same host can result in a lot of confusion and chaos. The smart thing to do for that case is to change the partition UUIDs on at least one of them. This thread has some good information about how to do that: https://askubuntu.com/questions/1250224/how-to-change-partuuid
In the root directory of the "boot" filesystem (/dev/sda1 in my example), there is a text file cmdline.txt that supplies command line parameters to the kernel at boot time. It's quite long but looks something like this:
console=tty3 root=/dev/mmcblk0p2 ro rootfstype=ext4 ....
With a text editor, change the "root=" part to reference your root filesystem partition (/dev/sda2 in my example). Instead of a device name, use the partition UUID. For example,
console=tty3 root=PARTUUID=abcdefab-02 ro rootfstype=ext4 ....
With no SD card inserted, the RPi's boot sequence stuff will find the boot partition on your thumb drive, and the above change will tell it where to find the root partition. But more tricks are needed.
In the "etc" directory of the root filesystem is the standard fstab file that tells Linux what filesystems to mount where. For the Crankshaft image, it will look something like this:
proc /proc proc defaults,noatime,nodiratime 0 0 /dev/mmcblk0p1 /boot vfat ro,defaults,noatime,nodiratime 0 2 /dev/mmcblk0p2 / ext4 defaults,noatime,nodiratime 0 1 ramfs /tmp ramfs size=128m,nodev,nosuid,noatime,nodiratime 0 0 ramfs /var/tmp ramfs size=16m,nodev,nosuid,noatime,nodiratime 0 0 ramfs /var/log ramfs size=16m,nodev,nosuid,noatime,nodiratime 0 0
(followed by several more "ramfs" mounts, which are irrelevant for this discussion)....
Read more » -
comskip for docker emby
04/27/2024 at 22:33 • 0 commentsThis is a description of how I have set up commercial skipping during playback of my emby recordings.
I have a few ways of recording live/linear TV. I have both good antenna OTA reception for local channels and various (legal/paid) accesses to other channels. The two server applications I use most for playing or recording live TV are Channels DVR and emby. I run both of them in docker containers on the same Raspberry Pi 4.
There is a popular application called comskip that analyzes video files and uses several tunable heuristics to detect commercial advertisement breaks. It can output the list of breaks in any of several standard or quasi-standard formats. Probably the most popular output format is EDL, edit decision list. Commercial skipping is a two-part process. First, the video file is analyzed (which to some extent can be done while it's being played or recorded). Second, when the video is played, the player understands the results of the analysis and provides for either manual or automatic skipping of commercial breaks.
Channels DVR has support for comskip built in, both for the analysis and playback. It's easily configured via the web GUI. emby does not have comskip built in, but it can be added via the sophisticated Emby.Comskipper plugin. The plugin provides the playback skipping based on EDL files. (It also recognizes some specially designated advertising chapter markers sometimes present in video files, though that has nothing to do with comskip.) The author provides detailed and complete instructions for how to hook in the comskip analysis piece to the emby server.
Although I run emby in a docker container, I wanted to run comskip either in its own container or on the host system. I didn't find a convenient comskip docker image, so I used the glue described below to run comskip on the host RPi 4. Running comskip with 3 threads, the CPU cores are loaded at about 75% each during actual analysis. For now, I only run a single comskip job at a time.
comskip-inotify.sh
This is a short shell script that manages the kick-off of comskip jobs. Jobs can be triggered in one of two ways.
- When the script starts, it looks for video files in the emby recording area that do not have a companion EDL file. This is a decent enough catch-up technique for crashes, reboots, etc.
- After that, it waits for the arrival of new video files from emby. That's done via the inotify-wait tool watching for creation events in the entire emby recording area.
For either job type, a job is created using task spooler. It's a straightforward queuing tool available in most Linux package repositories.
There are a couple of odds and ends to deal with in the script.
- Creating of new directories is ignored.
- It only acts on ".ts" files. I think (but I'm not sure) that all emby recordings are TS files.
- Jobs created in the first step are marked with "FIND" in the queued job. Jobs created for new files are marked with "WAIT". This is mostly for the benefit of manual monitoring of the queue.
- "WAIT" jobs are pushed to the head of the queue, ahead of all queued "FIND" jobs. That doesn't interrupt any already running job.
- Task sppoler standard output files and "finished" entries are deleted from time to time to get rid of clutter.
Without further ado, here is comskip-inotify.sh:
#!/bin/bash # Top level directory under which emby puts the Live TV recordings (default can be overridden on the command line) RECORDINGS=${1:-/mnt/red-drive/emby/programdata/data/livetv/recordings/} consider_one_file() { DIRECTORY=${1} FILE=${2} HOWCOME=${3} case ${HOWCOME} in FIND) # only process files with a .ts extension where there is not already an EDL file if [ "${FILE}" != "${FILE%.ts}" -a ! -e "${DIRECTORY}${FILE%.ts}.edl" ] then queue_one_comskip ${HOWCOME} "${DIRECTORY}" "${FILE}" fi ;; WAIT) # only process files with a .ts-READY extension if [ "${FILE}" != "${FILE%.ts-READY}" ] then rm -f "${DIRECTORY}${FILE}" queue_one_comskip ${HOWCOME}...
Read more » -
Moving from Google Voice to Google Messages
10/11/2023 at 20:45 • 0 comments((I'm moving the content formerly on this page to Instructables to reach a wider audience. And here it is: https://www.instructables.com/HOWTO-Moving-From-Google-Voice-GV-to-Google-Messag/))
Thanks for following my #wESP32: Wired ESP32 with Ethernet and PoE project!