ExceLint is working again

I do a lot of work with spreadsheets. Some are pretty simple, and I can inspect them by hand. Some are enormously complicated – hundreds of rows, dozens of columns, etc. It’s not practical to inspect/test them manually.

Enter ExceLint. It’s an add-in to Microsoft Excel that “lints” a spreadsheet. (A “linter” is a program that picks off ‘bits of fluff’.) The ExceLint team reports they regularly find errors, some material, in spreadsheets they test. (I was pretty lucky – there were a couple minor errors, but I was OK.)

ExceLint requires you to “side-load” a manifest.xml file that points to the resource files the add-in uses. The ExceLint home page describes the side-load process. It stopped working a while ago, so I just started to hope my good spreadsheet-fu continued. But then I decided to do a bit of troubleshooting, and found that ExceLint retrieved its code from a defunct server running on azure.com. I fixed it a couple ways:

  1. I created a Dockerfile that built the resources for the add-in on the local computer. Side-loading a manifest file that points to localhost allowed the add-in to work again.
  2. I realized that the resources – the files loaded by Excel – could be served by a static https server anywhere . So I created a new GitHub Action to build those files with each commit, and then to use Github Pages to serve those files.

You can now use ExceLint again, using publicly served resources from Github. You can even test at https://excelint.github.io/ExceLint-addin. The result isn’t terribly interesting – it displays the ExceLint logo, with a spinner that runs forever.

PRQL Dockerfile works again

The PRQL project provides a simple, powerful, pipelined SQL replacement. To make it easier to share the development environment, there is a Dev Container that bundles the dozens of components into a single container. This makes it easier for new person to start using the project: they don’t have to collect the proper (sometimes conflicting) versions of the tools on their computer.

The Dev Container had been working fine for over a year. I recently noticed that there was a new version of Docker Desktop (old: 4.29.0; new: 4.30.0). After the upgrade, some of the services – the Playground and the “Book” (the documentation) – were not available from the Dev Container.

The fix was to force those services to bind to the address 0.0.0.0 (not “localhost”, not 127.0.0.1) in the task file that configures them. See the PRQL repo for details.

All the “reasons” that bufferbloat isn’t a problem

As we take a shot at opening people’s eyes to bufferbloat, we should know some of the “objections” we’ll run up against. Even though there’s terrific technical data to back up our research, people seem especially resistant to thinking that bufferbloat might affect their network, even when they’re seeing problems that sound exactly like bufferbloat symptoms. But first, some history:

The very idea of bufferbloat is simply unbelievable. Jim Gettys in 2011 [1] couldn’t believe it, and he’s a smart networking guy,. At the time, it seemed incredible (that is “not credible” == impossible) that something could induce 1.2 seconds of latency into his home network connection. He called in favors from technical contacts at his ISP and at Bell Labs who went over everything with a fine-toothed comb. It was all exactly as spec’d. But he still had the latency. 

This led Jim and Dave Täht to start the investigation into the phenomenon known today as “bufferbloat” – the undesirable latency that comes from a router or other network equipment buffering too much data. Over several years, a group of smart people made huge improvements: fq_codel was released 14 May 2012 [3]; it was incorporated into the Linux kernel shortly afterward. CAKE came in 2015, and the Wi-Fi fixes that minimize bufferbloat the drivers arrived in 2018. In 2021 cake-autorate [4] arrived to handle varying capacity ISP links. All these techniques work great: in 2014, my 7mbps DSL link was quite usable. And when the pandemic hit, fq_codel on my OpenWrt router allowed me to use that same 7mbps DSL line for two simultaneous zoom calls. 

As one of the authors of [2], I am part of the team that has tried over the years to explain bufferbloat and how to fix it. We’ve spoken with vendors. We’ve spent untold hours responding to posts on assorted boards and forums with the the bufferbloat story. 

With these technical fixes in hand, we cockily set about to tell the world about how to fix bufferbloat. We assumed it would be an easy task. Our efforts have been met with skepticism at best, or stony silence. What are the objections? 

  • This is just the ordinary behavior: Of course things will be slower when there’s more traffic (Willfully ignoring orders of magnitude increase in delay.)
  • Besides, I’m the only one using the internet. (Except when my phone uploads photos. Or my computer kicks off some automated process. Or I browse the web. Or …)
  • It only happens some of the time. (Exactly. That’s probably when something’s uploading photos, or your computer is doing stuff in the background.)
  • Those bufferbloat tests you hear about are bogus. They artificially add load, which isn’t a realistic test. (…and what do you experience if you actually are downloading a file?)
  • Bufferbloat only happens when the network is 100% loaded. (True. But when you open a web page, your browser briefly uses 100% of the link. Is this enough to cause momentary lag?)
  • It’s OK. I just tell my kids/spouse not to use the internet when I’m gaming. (Huh?)
  • I have gigabit service from my ISP. (That helps, but if you’re complaining about “slowness” you still need to rule out bufferbloat in your router.)
  • I can’t believe that router manufacturers would ever allow such a thing to happen in their gear. (See the Jim Gettys story above.)
  • I mean… wouldn’t router vendors want to provide the best for their customers? (Not necessarily – implementing this (new-ish) code requires engineering effort. They’re selling plenty of routers using the decade-old software. The Boss says, “would we sell more if we make these changes? Probably not.”)
  • Why would my ISP provision/sell me a router that gave crappy service? They’re a big company, they must know about this stuff. (Maybe. We have reached out to all the vendors. But remember they profit if you decide your network feels too slow and you upgrade to a higher capacity device/plan.)
  • But couldn’t I just tweak the QoS on my router? (Maybe. But see [5])
  • Besides, I just spent $300 on a “gaming router”. I just bought the most expensive/best possible solution on the market. (And you’re concerned that you still have lag?)
  • You’re telling me that a bunch of pointy-headed academics are smarter than commercial router developers – who sold me that $300 router? I can’t believe it. (Well, these fixes seem to solve the problem when it replaces vendor firmware…)
  • And then you say that I should throw away that gaming router and install some “open source firmware”? What the heck is that? And why should I believe you? (Same answer as above.)
  • What if it doesn’t solve the problem? Who will give me support? And how will I get back to a vendor-supported system? (Valid point – the first valid point)
  • Aren’t there any commercial solutions I can just buy? (Not at the moment. IQrouter was a shining light here – available from Amazon, simple setup, worked a treat – but they have gone out of business. And of course, for the skeptic, this is proof that the “fq_codel-stuff” isn’t really a solution – it seems just like snake oil.)

So… All these hurdles make it hard to convince people that bufferbloat could be the problem, or that they can fix for themselves.

A couple of us have reached out to Consumer Reports, wondering if they would like a story about how vendors would prefer to sell you a shiny new router (or new bigger ISP plan) than fix your bufferbloat. This kind of story seemed to be straight up their alley, but we never heard back after an initial contact. Maybe they deserve another call…

The recent latency results from Starlink give me a modicum of hope. They’re a major player. They (and their customers) can point to an order of magnitude reduction in latency over other solutions. It still requires enough “regular customers” to tell their current ISP that they are switching to Starlink (and spend $600 to purchase a Dishy plus $100/month) to provide a market incentive.

Despite all this doom and gloom, I remain hopeful that things will get better. We know the technology exists for people to take control of their network and solve the problem for themselves. We can continue to respond on forums where people express their dismay at the crummy performance and suggest a solution. We can hope that a major vendor will twig to this effect and bring out a mass-market solution.

I think your suggestion of speaking to eSports people is intriguing. They’re highly motivated to make their personal networks better. And actually solving the problem would have a network effect of bringing in others with the same problem. 

Good luck, and thanks for thinking about this.

This is a slightly edited version of a post first published on the bloat and starlink lists.

Rich Brown

[1] https://courses.cs.washington.edu/courses/cse550/21au/papers/bufferbloat.pdf

[2] https://www.bufferbloat.net/projects/bloat/wiki/What_can_I_do_about_Bufferbloat/

[3] https://lists.bufferbloat.net/pipermail/cerowrt-devel/2012-May/000233.html

[4] https://github.com/lynxthecat/cake-autorate

[5] https://www.bufferbloat.net/projects/bloat/wiki/More_about_Bufferbloat/#what-s-wrong-with-simply-configuring-qos

Using ffmpeg to massage image, audio, and video

I regularly record public meetings in my town and post them on Youtube. This allows residents who could not attend the meeting in person to see what occurred. It also supports creation of accurate minutes.

I like to add a label (showing the committee name and date) and a timecode (a running clock showing the current time in the meeting). I found a free program Shutter Encoder that does this. It works well, but has a detailed (very fussy) user interface that requires a long set of steps for every new video.

Since I only deal with a couple variations of the recordings, I decided to write scripts that use the ffmpeg program directly to accomplish these repeated, well-defined tasks.

I now move the video/audio files into this directory and issue a command like the one below, and wait a few minutes. The resulting video is ready for uploading to Youtube.

 sh ./AddTimecode.sh "Lyme Committee Meeting-6Feb2024" 09:58:00 

Here are the notes I use to remind myself how to make the videos using my Mac. This information and the resulting scripts are also available on my github repo.

NB: You may need to install the ffmpeg program. Download a pre-built binary from ffmpeg.org, or read more on that site for getting a version for your computer.

Add image, label, and timecode to an audio track

To convert an audio-only recording into a video suitable for uploading to Youtube, this script combines a static JPEG photo with an audio track. The repo contains a photo of the Lyme Town Offices which is used by default. To use the script:

  1. Open the audio .mp4 file with QuickTime Player, and use the Trim (Cmd-T) function to remove the dead air from the start and end of the recording, as necessary. Save as Meeting Name_ddMMMyyyy.mp4
  2. Move the resulting audio file to this folder and run this script, where hh:mm:ss is the actual start time of the recording:

sh AddTimestamp.sh "Meeting Name and Date" hh:mm:ss

The script looks for a .mp4 file (and the image of Town Offices) to produce an output file named Meeting Name and Date-timecoded.mov

3. Cleanup: Move the original audio file and the resulting …-timecoded.mov file to the CompletedFiles folder so they won’t interfere with subsequent runs. Discard after they have been uploaded

Add label and timecode to AVCHD files

A Panasonic HDC-TM80 video camera produces a AVCHD meta-file that contains the video from a recording session. The files in an AVCHD file are within the AVCHD/BDMV/STREAM directory with filenames 00000.MTS, 00001.MTS, etc.

Drag the AVCHD file into this folder and run this script:

sh ./TimecodeAVCHD.sh "Meeting Name and Date" hh:mm:ss

The script looks for a file named AVCHD and outputs file named MeetingName-timecoded.mov

Add label and timecode to Zoom video recordings

Sometimes, a meeting is recorded by an Owl Camera. This results in a good video with good audio, but it’s still helpful to display the meeting name and timecode at the bottom.

Drag the Zoom file (a .mp4 file) into this folder and run this script:

sh ./TimecodeZoom.sh "Meeting Name and Date" hh:mm:ss

The script looks for any file with a .mp4 extension and outputs file named MeetingName-timecoded.mov

Background Information

StackOverflow/SuperUser and similar sites are your friends.

So is ChatGPT. I gave it this initial prompt, “give me a ffmpeg command to read a .mts file and add a label and a timecode and output a .mov file. Be sure the audio of the .mts file is preserved.” and iterated to get the final commands.

Experiments with ffmpeg From: https://superuser.com/questions/1041816/combine-one-image-one-audio-file-to-make-one-video-using-ffmpeg

  1. Accepted answer: ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4

ffmpeg -loop 1 -i Lyme-Town-Hall-Offices-cropped-1024.jpeg -i SB-20231130.mp4 -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest 11Nov2023-first.mp4

Takes a while to encode

  1. PJBrunet and Kokizzu: ffmpeg -r 1 -loop 1 -y -i 1.jpg -i 1.m4a -c:a copy -r 1 -vcodec libx264 -shortest 1.avi

time ffmpeg -r 1 -loop 1 -y -i Lyme-Town-Hall-Offices-cropped-1024.jpeg -i SB-20231130.mp4 -c:a copy -r 1 -vcodec libx264 -shortest 11Nov2023-second.mp4

~5 seconds; result 18.6mbytes. Creates file that cannot be opened by QuickTime Player

  1. Same as #2 with image that has odd number of pixels

ffmpeg -r 1 -loop 1 -y -i Lyme-Town-Hall-Offices-cropped-1024-1.jpeg -i SB-20231130.mp4 -c:a copy -r 1 -vcodec libx264 -shortest 11Nov2023-three.mp4

Blows big chunks with “odd dimensions” error

  1. Same as #2 with odd number of pixels, using -pix_fmt yuv444p right before name of output file.

time ffmpeg -r 1 -loop 1 -y -i Lyme-Town-Hall-Offices-cropped-1024-1.jpeg -i SB-20231130.mp4 -c:a copy -r 1 -vcodec libx264 -shortest -pix_fmt yuv444p 11Nov2023-four.mp4

Fast (takes 5-10seconds). Creates file that cannot be opened by QuickTime Player

WPNTFIIWDKIB

We promise not to fix it if we don’t know it’s broke. My mentor at Dartmouth College, Stan Dunten, said this all the time.

That’s why I always send in short reports to webmaster@…. mentioning something that didn’t look right. Most of the time it’s something silly. And sometimes I get a heartfelt “Thanks!” because I pointed out a real problem.

Save money while keeping latency low

I often hear people saying they have bad responsiveness / high latency on their high-speed internet connection. Even though they have a contract for 500 mbps+ service from their ISP, a speedtest shows high ping times when the link is loaded.

The answer is well-known – install a router with SQM that knows how to control latency (“bufferbloat”). But… they counter, a router to handle my high-speed network is expensive! And that blows out my budget!

I posted a contrarian viewpoint in a post on the OpenWrt forum:

Save money and purchase a 250mbps to 350mbps connection and use good SQM (for example, the IQrouter v3, or any reasonable performance OpenWrt compatible router.)

Unless you’re unusual, and the transfer speeds of your bulk up/downloads are unacceptable, it’s likely that a lower speed to your ISP with a modestly-priced router that controls latency will make you just as happy.

Not only will you save money with a less-expensive router, you save every month with a lower ISP bill.

uBlock Origin and other blockers

Many people are surprised to hear that their web browsing doesn’t have to be crowded out by intrusive ads. There is an entire industry of “ad blockers” and “content blockers” that claim to fix this.

uBlock Origin is the one I use. Its author, “gorhill” states that it’s Free. Open-source. For users by users. No donations sought.

Accept no substitutes! The other products carry names that combine the words “ad”, “block”, “guard”, “plus” and a whole host of synonyms. And I wouldn’t trust any of them – they all come with with strings (or fees) that make them less than perfect.

For Chrome or Firefox:

  • To install uBlock Origin, Google “ublock origin” (use that exact phrase) and then click the link for “ublockorigin.com
  • Follow the instructions

For Safari:

  • uBlock Origin is no longer available for Safari
  • Use AdGuard for Safari. It’s also free, and seems to follow the same ethos as uBlock Origin. (Tested with current Safari on 12Feb2023).
  • For a state of uBlock Origin for Safari, and the recommendations that lead me to AdGuard for Safari, see https://github.com/el1t/uBlock-Safari/issues/158

For Other Browsers:

Format pretty reports in PRQL

I can no longer bring myself to write bare SQL – PRQL makes building queries so easy.

I have become enamored with PRQL – Pipelined Relational Query Language, pronounced “Prequel”. It’s a simple, powerful, pipelined SQL replacement.

From the PRQL Github page: Like SQL, it’s readable, explicit and declarative. Unlike SQL, it forms a logical pipeline of transformations, and supports abstractions such as variables and functions. It can be used with any database that uses SQL, since it compiles to SQL.

I wrote a blog post over on the prql-lang.org site that tells how to make SQL queries “look good” using PRQL. See more »