What If the EU Never Existed?

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Video framegrab showing an alternate history map of Europe in mid-to-late 20th century. West Germany has formed an economic union with several neighbouring states, while France and Italy have elected Communist governments and are within the Soviet sphere of influence.

This video, which I saw on Nebula but which is also available on YouTube, explores a hypothetical alternate history in which the Schuman Plan/European Coal & Steel Community never happened, and the knock-on effects lead to no EU, a more fragmented Europe, and an ultimately more-fractured and more-complicated Europe of the late 20th/early 21st century.

Obviously it’s highly-speculative and you could easily come up with your own alternative alternative history! But the Twilight Struggle player in me as well as the alternate history lover (and, of course, European Union fan) especially loves the way this story is told.

It’s worth remembering that for the last half-millenium or more, the default state of Europe has been to be fighting one another: if not outright war then at least agressive economic and political rivals. Post-WWII gave Europe perhaps its longest ever period of relative peace, and that’s great enough that all of the other benefits of a harmonised and cooperative union are just icing on the cake.

EU Made Simple is a fantastic channel in general, and I’d recommend you give it a look. It ties news and history in with its creators outlook, but it’s always clear which bits are opinion and it’s delightfully bitesized. For Europeans-in-exile in this post-Brexit age, it’s hopeful and happy, and I like it.

Happy Europe Day, one and all.

Variable-aspect adaptive-bitrate video… in vanilla HTML?

The video below is presented in portrait orientation, because your screen is taller than it is wide.

The video below is presented in landscape orientation, because your screen is wider than it is tall.

The video below is presented in square orientation (the Secret Bonus Square Video!), because your screen has approximately the same width as as its height. Cool!

This is possible (with a single <video> element, and without any Javascript!) thanks to some cool HTML features you might not be aware of, which I’ll briefly explain in the video. Or scroll down for the full details.

Variable aspect-ratio videos in pure HTML

I saw a 2023 blog post by Scott Jehl about how he helped Firefox 120 (re)gain support for the <source media="..."> attribute. Chrome added support later that year, and Safari already had it. This means that it’s pretty safe to do something like this:

<video controls>
  <source src="squareish.mp4"
        media="(min-aspect-ratio: 0.95) and (max-aspect-ratio: 1.05)" />
  <source src="portrait.mp4"
        media="(orientation: portrait)" />
  <source src="landscape.mp4" />
</video>
This code creates a video with three sources: squareish.mp4 which is shown to people on “squareish” viewports, failing that portrait.mp4 which is shown to people whose viewports are taller than wide, and failing that landscape.mp4 which is shown to anybody else.

That’s broadly-speaking how the video above is rendered. No JavaScript needed.

Browsers only handle media queries on videos when they initially load, so you can’t just tip your phone over or resize the window: you’ll need to reload the page, too. But it works! Give it a go: take a look at the video in both portrait and landscape modes and let me know what you think1.

Adding adaptive bitrate streaming with HLS

Here’s another cool technology that you might not have realised you could “just use”: adaptive bitrate streaming with HLS!

You’ve used adaptive bitrate streaming before, though you might not have noticed it. It’s what YouTube, Netflix, etc. are doing when your network connection degrades and you quickly get dropped-down, mid-video, to a lower-resolution version2.

Turns out you can do it on your own static hosting, no problem at all. I used this guide (which has a great description of the parameters used) to help me:

ffmpeg -i landscape.mp4 \
       -filter_complex "[0:v]split=3[v1][v2][v3]; [v1]copy[v1out]; [v2]scale=w=1280:h=720[v2out]; [v3]scale=w=640:h=360[v3out]" \
       -map "[v1out]" -c:v:0 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
       -map "[v2out]" -c:v:1 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
       -map "[v3out]" -c:v:2 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
       -map a:0 -c:a:0 aac -b:a:0 96k -ac 2 \
       -map a:0 -c:a:1 aac -b:a:1 96k -ac 2 \
       -map a:0 -c:a:2 aac -b:a:2 48k -ac 2 \
       -f hls -hls_time 2 -hls_playlist_type vod -hls_flags independent_segments -hls_segment_type mpegts \
       -hls_segment_filename landscape_%v/data%02d.ts \
       -master_pl_name landscape.m3u8 \
       -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" landscape_%v.m3u8
This command splits the H.264 video landscape.mp4 into three different resolutions: the original “v1” (1920×1080, in my case, with 96kbit audio), “v2” (1280×720, with 96kbit audio), and “v3” (640×360, with 48kbit audio), each with a resolution-appropriate maximum bitrate, and forced keyframes every 48th frame. Then it breaks each of those into HLS segments (.ts files) and references them from a .m3u8 playlist.

The output from this includes:

  • Master playlist landscape.m3u8, which references the other playlists with reference to their resolution and bandwidth, so that browsers can make smart choices,
  • Playlists landscape_0.m3u8 (“v1”), landscape_1.m3u8 (“v2”), etc., each of which references the “parts” of that video,
  • Directories landscape_0/, landscape_1/ etc., each of which contain
  • data00.ts, data01.ts, etc.: the actual “chunks” that contain the video segments, which can be downloaded independently by the browser as-needed

Bringing it all together

We can bring all of that together, then, to produce a variable-aspect, adaptive bitrate, HLS-streamed video player… in pure HTML and suitable for static hosting:

<video controls>
  <source src="squareish.m3u8"
         type="application/x-mpegURL"
        media="(min-aspect-ratio: 0.95) and (max-aspect-ratio: 1.05)" />

  <source src="portrait.m3u8"
         type="application/x-mpegURL"
        media="(orientation: portrait)" />

  <source src="landscape.m3u8"
         type="application/x-mpegURL" />
</video>
You could, I suppose, add alternate types, poster images, and all kinds of other fancy stuff, but this’ll do for now.

That’ll “just work” in Safari and a handful of mobile browsers… but won’t display anything for most desktop browsers. Boo!

One solution is to also provide the standard .mp4 files as an alternate <source>, and that’s fine I guess, but you lose the benefit of HLS (and you have to store yet more files). But there’s a workaround:

Polyfill full functionality for all browsers

If you’re willing to use a JavaScript polyfill, you can make the code above work on virtually any device. I gave this a go, here, by:

  1. Including the polyfill hls.js, and
  2. Adding some JavaScript code that detects affected `<video>` elements and applying the fix if necessary:
// Find all <video>s which have HLS sources:
for( hlsVideo of document.querySelectorAll('video:has(source[type="application/x-mpegurl"]), video:has(source[type="vnd.apple.mpegurl"])') ) {
  // If the browser has native support, do nothing:
  if( hlsVideo.canPlayType('application/x-mpegurl') || hlsVideo.canPlayType('application/vnd.apple.mpegurl') ) continue;

  // If hls.js can't help fix that, do nothing:
  if ( ! Hls.isSupported() ) continue;

  // Find the best source based on which is the first one to match any applicable CSS media queries
  const bestSource = Array.from(hlsVideo.querySelectorAll('source')).find(source=>window.matchMedia(source.media).matches)

  // Use hls.js to attach the best source:
  const hls = new Hls();
  hls.loadSource(bestSource.src);
  hls.attachMedia(hlsVideo);
}
It makes me feel a little dirty to make a <video> depend on JavaScript, but if that’s the route you want to go down while we wait for HLS support to become more widespread (rather than adding different-typed sources) then that’s fine, I guess.

This was a fun dive into some technologies I’ve not had the chance to try before. A fringe benefit of being a generalist full-stack developer is that when you’re “between jobs” you get to play with all the cool things when you’re brushing up your skills before your next big challenge!

(Incidentally: if you think you might be looking to employ somebody like me, my CV is over there!)

Footnotes

1 There definitely isn’t a super-secret “square” video on this page, though. No siree. (Shh.)

2 You can tell when you get dropped to a lower-resolution version of a video because suddenly everybody looks like they’re a refugee from Legoland.

A Surprisingly Shit Bathroom

This bathroom at the holiday home where some fellow volunteers and I are doing some Three Rings work, this week, has a few unusual quirks, including this surprisingly-shit bathroom:

  • The door has a lock… but there’s a second door which doesn’t.
  • Oh, and the first door’s lock doesn’t actually do anything. The door can still be opened from the outside.

Kebab Menu Accessibility

Hanging with my team at our meetup in Istanbul, this lunchtime I needed to do some accessibility testing…

(with apologies to anybody who doesn’t know that in user interface design, a “kebab menu” is one of those menu icons with a vertical line of three dots: a vertical ellipsis)

Wavey Dan

I was experimenting with VP8/VP9 WebM video transparency and I made a stupid thing: a URL that, if you go to it, means you’ll he followed around my blog by a video of me just hanging out in the corner of the page – https://danq.me/?fool_id=06

I’ve added it to my list of “stupid/random things that can happen if you visit my blog on April Fools’ Day”: https://danq.me/fools/

Screenshot of DanQ.me, with a transparent video overlay of Dan in the bottom right corner, waving.

×

Get Ready with Me: Techfluencer Edition

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

WordPress.com (via YouTube)

WTF did I just watch?

It’s possible I don’t understand social media any more. To be fair, it’s possible that I never did.

This is something between absurd and hilarious. Aside from the 100 year plan (which is fascinating, and I keep meaning to share my thoughts on), I’m not sure what it’s supposed to be advertising. Maybe it’s trying to showcase how cool it is to work with Automattic? (It’s not… exactly like it’s depicted in the video. But I’d be lying if I said that fewer than 50% of my meetings this week have included a discussion on snack foods, so maybe we are I guess at least a little eccentric.)

I think I understand what it’s parodying. And that’s fun. But… wow. You don’t see many videos like this attached to a corporate YouTube account, do you? Kudos for keeping the Internet fun and weird, WordPress.com.

The Time Travel Movie That Doesn’t Move

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

When I saw the title of this piece by The Nerdwriter pop up in my RSS reader, the first words that grabbed my attention were “time travel movie”. I’ve a bit of a thing for time travel stories in any medium, and I love a good time travel movie1. Could I be about to be introduced to one I’m not familiar with, I wondered?

Before the thumbnail loaded2, I processed the rest of the title: the movie doesn’t move. At first my brain had assumed that this was a reference to the story spanning time but not space, but now suddenly it clicked:

We’re talking about La Jetée, aren’t we?

Like many people (outside of film students), I imagine, I first came across La Jetée after seeing it mentioned in the credits of Twelve Monkeys, which adapts its storyline in several ways. And like most people who then went on to see it, I imagine, I was moved by that unforgettable experience – there’s nothing quite like it in the history of film (if we’re to call it a film, that is: its creator famously doesn’t).

Anyway: Nerdwriter1’s take on it doesn’t say anything that hasn’t already been said, but it’s a beautiful introduction to interpreting this fantastic short film and it’s highly-accessible whether or not you’ve seen La Jetée3. Give his video essay a watch.

Footnotes

1 Okay, let’s be honest, my feelings go deeper than that. Time travel movies are, for me, like pizza: I love a good time travel movie, but I’ll also happily enjoy a pretty trashy time travel movie too.

2 Right now I’m in a rural farm building surrounded by olive groves in an out-of-the-way bit of Spain, and my Internet access isn’t always the fastest. D’ya remember how sometimes Web pages used to load the text and then you’d wait while the images loaded? They still do that, here.

3 There’s spoilers, but by the time a film is 60 years old, I think that’s fair game, right?

Geohashing expedition 2024-10-22 51 -1

This checkin to geohash 2024-10-22 51 -1 reflects a geohashing expedition. See more of Dan's hash logs.

Location

Harcourt Hill Bridleway, between Cumnor and North Hinksey

Participants

Plans

I’m on sabbatical from work right now, so I’m hoping to be able to get out to this hashpoint while the kids are at school.

Expedition

After dropping the kids off at school, the geopup/hashhound and I set out for the hashpoint. Coming up the “short side” of the bridleway from Botley would be a shorter walk, but we opted to park in Cumnor and come up the “long side” of Harcourt Hill to avoid Oxford’s traffic (and the inevitable fee for parking on the city’s side of the hill).

Harcourt Hill (like my village of Stanton Harcourt) doubtless gets its name from the Harcourt Family, who supported William the Conqueror during his conquest of Great Britain back in 1066 and were ultimately granted huge swathes of land around this part of the world in recognition of their loyalty. To this day, you find “Harcourt” in a lot of place names in this neck of the woods.

The hashpoint was so easy to find, we almost walked right over it: it’s right in the centre of the footpath/bridleway. Even my dog, who often doesn’t like long walks or muddy paths, didn’t get a chance to complain before we got there. We arrived at 09:35 and took the requisite photos, which can be found below. We also kept a GPS tracklog and vlogged our experience, all of which you can see below.

I’ve not properly hashed in a long while, so it was great to get back out there!

Tracklog

My GPSr kept a tracklog.

Tracklog map showing a route from Stanton Harcourt through to Harcourt Hill (via Cumnor) and back, West of Oxford.

Video

Also available via YouTube.

Photos

A footpath becomes a zebra crossing despite there being no road to cross, just a lawn (probably there USED to be a road).
What’s the point of this crossing? Do rabbits pass very fast through this junction?
A French Bulldog stands derpily on a muddy footpath between fields, under blue-grey skies.
View East from the hashpoint (plus dog).
A footpath vanishes between fields, flanked by wild bushes.
View West from the hashpoint.
A GPS receiver shows "0 metres" to destination.
Right in the middle of the circle of uncertainty.
Dan crouches by his dog to take a selfie.
Silly grin/silly tongue-sticking-out.
× × × × × ×

Hurricane Milton

From safely outside of its predicted path, just around the Yucatan coast, Hurricane Milton seems like a forboding and distant monster. A growing threat whose path will thankfully take it away, not towards, me.

My heart goes out to the people on the other side of the Gulf of Mexico who find themselves along the route of this awakened beast.

Wave Hello Trilogy

The YouTube channel @simonscouse has posted exactly two videos.

The first came a little over ten years ago. It shows a hand waving and then wiggling its fingers in front of a patterned wallpaper:

The second came a little over five years ago, and shows a hand – the same hand? – waving in front of a painting of two cats while a child’s voice can be heard in the background:

In a comment on the latter, the producer promised that it’s be “only another 5 years until the trilogy is completed”.

Where’s the third instalment, Simon? We’re all waiting to see it!

Write Websites

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Enbies and gentlefolk of the class of ‘24:

Write websites.

If I could offer you only one tip for the future, coding would be it. The long term benefits of coding websites remains unproved by scientists, however the rest of my advice has a basis in the joy of the indie web community’s experiences. I will dispense this advice now:

Enjoy the power and beauty of PHP; or never mind. You will not understand the power and beauty of PHP until your stack is completely jammed. But trust me, in 20 years you’ll look back at your old sites and recall in a way you can’t grasp now, how much possibility lay before you and how simple and fast they were. JS is not as blazingly fast as you imagine.

Don’t worry about the scaling; or worry, but know that premature scalability is as useful as chewing bubble gum if your project starts cosy and small. The real troubles on the web are apt to be things that never crossed your worried mind; if your project grows, scale it up on some idle Tuesday.

Code one thing every day that amuses you.

Well that’s made my day.

I can’t say I loved Baz Luhrmann’s Everybody’s Free To Wear Sunscreen. I’m not sure it’s possible for anybody who lived through it being played to death in the late 1990s; a period of history when a popular song was basically inescapable. Also, it got parodied a lot. I must’ve seen a couple of dozen different parodies of varying quality in the early 2000s.

But it’s been long enough that I was, I guess, ready for one. And I couldn’t conceive of a better topic.

Y’see: the very message of the value of personal websites is, like Sunscreen, a nostalgic one. When I try to sell people on the benefits of a personal digital garden or blog, I tend to begin by pointing out that the best time to set up your own website is… like 20+ years ago.

But… the second-best time to start a personal website is right now. With cheap and free static hosting all over the place (and more-dynamic options not much-more expensive) and domain names still as variably-priced as they ever were, the biggest impediment is the learning curve… which is also the fun part! Siloed social media is either eating its own tail or else fighting to adapt to once again be part of a more-open Web, and there’s nothing that says “I’m part of the open Web” like owning your own online identity, carving out your own space, and expressing yourself there however you damn well like.

As always, this is a drum I’ll probably beat until I die, so feel free to get in touch if you want some help getting set up on the Web.

Ranking Every Elevator in the Myst Series

This is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Dustin Garner

Part of the joy of the collaborative Internet is that people can share their passion. Today’s example comes from this YouTuber who’s made an hour long video demonstrating and ranking the 35 elevators in the first five games in the Myst series.

Starting with a discussion of what defines an elevator, the video goes on to show off some of the worst of the lifts in the series of games (mostly those that are uninspired, pointless, or which have confusing interfaces) before moving on to the well-liked majority.

I only ever played the first two Myst games (and certainly haven’t played the first since, what, the mid-1990s?) and I don’t think I finished either. But that didn’t stop me watching the entirety of this video and revelling in the sheer level of dedication and focus it’ll have taken on the part of the creator. When I made my (mere 15-minute!) video describing my favourite video game Easter Egg I spent tens of hours over the prior weeks researching the quirk and its background, configuring a copy of the (elderly) game so that it’d play and record in the way I wanted, and of course playing through the game far enough to be able to fully demonstrate the Easter Egg. Dustin’s video, which doubtless involved replaying (possibly multiple times) five different games released over a 12-year window is mindblowing by comparison.

I don’t really care about the Myst series. I care even less about its elevators. But I really enjoyed this video, if only for its creator’s enthusiasm.