Skip to content

Latest πŸ—žοΈ

Thursday, August 27

Git Commits

dash commits 4 ohnsh/dash
  • 8:48 pm β€” John Sherrell <dev@ohn.sh>

    next: paginate thumbnail strips on non-date routes. (I may adapt it so on date routes it simply bumps the date forward or backward.) Page state is tracked in the query string, which makes views linkable and keeps fetching on the server. (For now--since this is a live feed, asynchronously refreshing thumbnails on the client is the logical behavior.) Got some practice with tailwind, generating loading skeletons.

  • 12:45 pm β€” John Sherrell <dev@ohn.sh>

    next: cleaned up some debugging code I forgot about in sensor-chart, converted sensor data fetch from `unstable_cache` to `use cache`.

  • 12:00 pm β€” John Sherrell <dev@ohn.sh>

    next: enabled cache components, surfacing several issues due to stricter requirements to not block rendering the static shell. The fixes are somewhat superficial since I haven't reached a point where optimization makes much sense (everything can and will change in the coming weeks anyway). But anyway, it builds.

  • 5:01 am β€” John Sherrell <dev@ohn.sh>

    next: moved chart demo to ChartDemo component.

YouTube

Wednesday, August 26

Git Commits

dash commits 1 ohnsh/dash
  • 9:52 pm β€” John Sherrell <dev@ohn.sh>

    next: more icon accessibility tweaks. Moved generic svg description from <title> to aria-label so that it doesn't override contextual link tooltip text.

itsa-me commits 1 ohnsh/itsa-me
  • 8:54 pm β€” John Sherrell <dev@ohn.sh>

    Switch in link to dash.ohn.sh, replacing scratch.ohn.sh Also bump dependencies and remove cssnano, which I don't still use.

days commits 1 ohnsh/days
  • 6:24 pm β€” John Sherrell <dev@ohn.sh>

    Add comments to Slideshow.astro component, add button:hover styles.

YouTube

Tuesday, August 25

Using a fake HomeKit switch to automate capturing real sensor data

of

In Apple Home, an action runs whenever the Homebridge dummy switch is "pressed" (every 15 minutes). The action sends a JSON payload to dashd (the backend server/database) consisting of HomePod sensor readings and a timestamp.
In Homebridge, the virtual switch is set to trigger every 15 minutes, and also to create a local webhook where it can be triggered on-demand.
Main settings panel for virtual switch in Apple Home.
Apple Home provides a settings panel for the Homebridge virtual switch, including actions that can be run on single press, double press, and long press.

UPDATE: Ouch, a tvOS/HomePod 27 bug breaks the automation. Sounds like a fix is coming in 27.2.

View full post…

Git Commits

days commits 5 ohnsh/days
  • 4:30 pm β€” John Sherrell <dev@ohn.sh>

    CE

  • 2:37 pm β€” John Sherrell <dev@ohn.sh>

    Minor post edit.

  • 11:17 am β€” John Sherrell <dev@ohn.sh>

    Remove Latest Streams section from /latest (default route). The component was pointing to YouTube live streams, which are getting stale.

  • 11:07 am β€” John Sherrell <dev@ohn.sh>

    Edit title of latest post and change to sentence-case to be consistent with other recent posts.

  • 11:00 am β€” John Sherrell <dev@ohn.sh>

    New post about homebridge/homekit automation to capture sensor data on schedule. Created a bare-bones Slideshow.astro component that uses Alpine.js for reactive state. Installed Astro Alpine integration. Bumped dependencies.

dash commits 5 ohnsh/dash
  • 9:50 pm β€” John Sherrell <dev@ohn.sh>

    next: social icon accessibility tweaks. Descriptive text now in a[aria-label], with the generic icon description in svg > title (ignored inside of aforementioned links).

  • 7:13 pm β€” John Sherrell <dev@ohn.sh>

    next: Tweak new icons.

  • 6:31 pm β€” John Sherrell <dev@ohn.sh>

    next: Add GitHub icon and link to project repository to sidebar.

  • 5:57 pm β€” John Sherrell <dev@ohn.sh>

    next: move my global styles into tailwind's base layer so they can be overridden by tailwind utilities.

  • 5:48 pm β€” John Sherrell <dev@ohn.sh>

    next: Add YouTube link to sidebar using Feather YouTube icon. Tweak global CSS so that global link style (accent color, underline) does not apply to links that contain an <svg>.

Monday, August 24

Git Commits

dash commits 5 ohnsh/dash
  • 7:54 pm β€” John Sherrell <dev@ohn.sh>

    vod: fix bug in video.sh in which a full path was used where a basename was appropriate (it had never been apparent because I basically always pass it files in the current directory).

  • 7:53 pm β€” John Sherrell <dev@ohn.sh>

    next: new ActionButton component that calls a server action in `startTransition` and displays a loading spinner.

  • 1:14 pm β€” John Sherrell <dev@ohn.sh>

    next: tweak scale of charts.

  • 5:19 am β€” John Sherrell <dev@ohn.sh>

    dashd: add CORS handling to new sensor GET route.

  • 12:06 am β€” John Sherrell <dev@ohn.sh>

    next: tweak front page, add revalidate button, limit chart data to last 24 hours (96 records).

Sunday, August 23

Git Commits

dash commits 9 ohnsh/dash
  • 10:51 pm β€” John Sherrell <dev@ohn.sh>

    next: chart demo now on home route. Add `headless` option to VODView to prevent it from rendering an empty player. Now used whenever there's no video specified in the query string on the home route.

  • 9:07 pm β€” John Sherrell <dev@ohn.sh>

    next: alternate implementation of SensorChart in which the server fetches the data and passes a promise down via props. Factor out the UI and provide the different implementations via wrappers SensorChartPromise and SensorChartEffect.

  • 6:01 pm β€” John Sherrell <dev@ohn.sh>

    next: fix types so project will build on vercel.

  • 5:50 pm β€” John Sherrell <dev@ohn.sh>

    next: move sensor demo up to /scratch/sensor

  • 5:48 pm β€” John Sherrell <dev@ohn.sh>

    next: playing with x-axis formatting. Ruled out stateful formatters that detect date changes. This relies on them being called in timestamp order, and it turns out they're not. Also creates stale closure risk.

  • 3:40 pm β€” John Sherrell <dev@ohn.sh>

    next: flexible grid layout for charts, bump font-size down, use "none" | "snap125" for `niceTicks` prop to solve most axis issues (they tend to render nice, round numbers).

  • 12:25 pm β€” John Sherrell <dev@ohn.sh>

    next: wrap charts in div and render optional title; handle explicit abort signal gracefully to prevent unhandled rejections.

  • 5:08 am β€” John Sherrell <dev@ohn.sh>

    next: new demo chart interface at /scratch/recharts/sensor that consumes the new dashd temperature/humidity sensor API and plots the data using Recharts.

  • 1:54 am β€” John Sherrell <dev@ohn.sh>

    dashd: Added /sensor prefix to tunnel route config. POST /sensor saves readings to the database, and GET /sensor queries the database. Query parameter loc=location_name limits queries to a specific location (e.g. 'encore_main'), and last=n limits results to the n most recent.

Saturday, August 22

Git Commits

dash commits 3 ohnsh/dash
  • 9:30 pm β€” John Sherrell <dev@ohn.sh>

    vod: fixed a couple of silly bugs in video.sh. `count` is now local (but initialized from the environment) so that it's re-computed after the script sleeps in watch mode. And now actually using `status` after saving it, instead of incorrectly repeating `$?`.

  • 4:08 pm β€” John Sherrell <dev@ohn.sh>

    dashd: migrated sensor db to use cleaner column names, added location for second homepod (bedroom).

  • 1:16 am β€” John Sherrell <dev@ohn.sh>

    dashd: now logging sensor readings to an sqlite db.

Friday, August 21

Git Commits

itsa-me commits 1 ohnsh/itsa-me
  • 3:04 am β€” John Sherrell <dev@ohn.sh>

    Links that could go somewhere.

dash commits 2 ohnsh/dash
  • 2:15 am β€” John Sherrell <dev@ohn.sh>

    dashd: new route, POST /mx/sensor, to which sensor data can be sent by automation. Data is currently logged to a jsonl file, but soon it will be an sqlite database. Auth is checked against a static token passed in the environment.

  • 12:14 am β€” John Sherrell <dev@ohn.sh>

    Testing recharts.

Thursday, August 20

First pass at an interactive picture-in-picture video component

Much of the video that winds up on dash.ohn.sh is recorded in a very particular format (in OBS Studio), consisting of four 1080p tiles, each representing an β€œangle” of the same scene. Two of those angles are screen captures, which are difficult to read when limited to one quarter of a video player. Luckily, the web platform provides a bunch of tools to process video and create custom video players. The above demo shows a first pass at a solution, implemented as an interactive React component.

Concept

The basic idea is to display one quadrant at a time in a main view that occupies most of the video player, with the other three quadrants shown picture-in-picture style along one edge. Clicking a picture-in-picture view swaps it with the main view. Clicking the main view toggles all of the picture-in-picture views on/off as a group, which is important because they do obscure part of the main view when enabled.

View full post…

Git Commits

dash commits 8 ohnsh/dash
  • 4:21 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: more accessibility improvements to CropOverlay. The static data structure that defines the crop regions now includes descriptive text that is ised in `aria-label` attributes.

  • 3:19 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: improve accessibility in CropOverlay by wrapping interactive <canvas> elements in <button>s that are given the onClick actions.

  • 12:59 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: make focus outline styles work in Safari, too, it an annoyingly fragile way. The fixes currently only apply to the VODPlayer views; the sidebar is next.

  • 12:41 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: improve styling of links and buttons in VODPlayer views by creating room for browser-default focus outlines inside scroll containers, where they are otherwise clipped. Update buttons underneath VODPlayer to simply brighten on hover rather than use outline styles that could be confused with focus.

  • 10:56 am β€” John Sherrell <dev@ohn.sh>

    @dash/next: CropOverlay: make pipEnabled true by default (when overlay is activated). Add `cursor: pointer` to "See more" button in sidebar.

  • 1:55 am β€” John Sherrell <dev@ohn.sh>

    @dash/next: fixed another layout bug, this time for landscape mobile viewports. At some point, I changed `overflow: hidden` to `overflow: clip` on the <video> wrapper element, which removed the flexbox min-size reset associated with scroll containers. I'm now setting `min-height: 0` directly.

  • 1:15 am β€” John Sherrell <dev@ohn.sh>

    @dash/next: better CSS handling of VODPlayer when no source selected. Uses `vh` unit for both width and max-height in order to limit the size while maintaining a reasonable aspect ratio. (Unfortunately, `aspect-ratio` itself doesn't seem to constraing width when `max-height` is reached.)

  • 1:06 am β€” John Sherrell <dev@ohn.sh>

    @dash/next: fixed min-height bug that caused VODPlayer to overflow the viewport in portrait mode at mobile sizes.

days commits 4 ohnsh/days
  • 10:34 pm β€” John Sherrell <dev@ohn.sh>

    Tag markdown code blocks as typescript for syntax highlighting.

  • 8:52 pm β€” John Sherrell <dev@ohn.sh>

    Document typos, vale, and cspell usage (spellcheckers / prose linters).

  • 8:17 pm β€” John Sherrell <dev@ohn.sh>

    CropOverlay demo video was too large for `wrangler deploy`; moved to a new R2 bucket.

  • 7:55 pm β€” John Sherrell <dev@ohn.sh>

    New post about CropOverlay component in @dash/next, along with demo video. Ran `typos` on project and fixed a few typos.

Wednesday, August 19

Git Commits

dash commits 7 ohnsh/dash
  • 11:54 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: reasonably functional picture-in-picture view now implemented in CropOverlay component. The option to activate it appears when viewing the quad-tile 4K videos I record in OBS. When activated, a quadrant from the underlying video is cropped out and overlaid on top, covering most of the video but leaving room for the controls underneath. Clicking the overlay brings up picture-in-picture views of the other three quadrants. Clicking one of the PiP views swaps it into the main canvas. Clicking the main canvas switches off picture-in-picture, and clicking the button below the video player toggles the overlay as a whole.

  • 9:35 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: quick fix to VODPlayer segments list; add `padding: 1px` to make room for outline around active segment.

  • 9:21 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: VODPlayer has a new div.footer that consolidates under-video content. It is a grid container with three columns so that the crop button, when present, is always left-aligned, and the segment timestamps, when present, are always centered.

  • 7:50 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: new CropOverlay component that renders a cropped quadrant of an underlying <video> in a <canvas>. Currently, it can be activated by a button that's only rendered underneath 4K videos. Clicking the canvas causes the other three quadrants in picture-in-picture views on the same canvas. This should be improved by using a different <canvas> for each view, and making them interactive so that they can be swapped with the main view on click/tap.

  • 5:03 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: add aria-expanded and aria-controls attributes to InventoryList "See more" button.

  • 4:24 pm β€” John Sherrell <dev@ohn.sh>

    @dash/next: make sidebar archive menu expandable. By default, it displays the 8 most-recent days and a "See more" button.

  • 12:25 am β€” John Sherrell <dev@ohn.sh>

    next: simplified layout by not limiting <article> to viewport height. The main player is now contstrained by explicit rules on itself, whereas before it was constrained by the container and the flex-basis of the thumbstrip section beneath.

days commits 1 ohnsh/days
  • 3:48 pm β€” John Sherrell <dev@ohn.sh>

    Finished 8/18 post about Silero VAD.

Tuesday, August 18

dash.ohn.sh β€” Automated content filtering powered by Silero VAD

For a new project, I have a video processing pipeline that prepares raw camera footage for publishing, extracts metadata, and syncs everything to a Cloudflare R2 bucket. The newest feature is voice activity detection with Silero VAD, which I’m running on the CPU via onnxruntime-node. Here it is taking around 20 seconds to analyze several hours of footage on my Mac Mini.

The model takes a tensor representing 512 samples of 16-kHz, single-channel audio (roughly 30 ms) and returns a score indicating the probability that the window contains speech (β€œvoice activity”). In the pipeline, audio is extracted from source recordings and normalized with ffmpeg, then fed through the model piece by piece. The raw scores are filtered through a state machine (during a speech segment, a given sample is more likely to register as speech) to produce a list of timestamps representing segments of the video that contain speech.

View full post…

Git Commits

dash commits 3 ohnsh/dash
  • 2:30 pm β€” John Sherrell <dev@ohn.sh>

    next,vod: add optional `tags` array to VODVideo schema, surface videos with the property on the root route along with those with detected speech.

  • 1:21 pm β€” John Sherrell <dev@ohn.sh>

    next: change format and style of VODPlayer timestamp. It's now absolutely positioned within the video frame, at bottom right.

  • 10:27 am β€” John Sherrell <dev@ohn.sh>

    next: handle wyze filenames (HH.mp4) when computing timestamps by falling back to a function that takes a date and filename. Pass the current inventory record to the thumbstrip component rendering it so that it can be filtered on the client.

days commits 1 ohnsh/days
  • 4:25 pm β€” John Sherrell <dev@ohn.sh>

    New post about Silero VAD, bump Astro version.