Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
54
We've all seen progress bars that move slowly for twenty minutes, then rapidly fill up in the last 30 seconds. Or the reverse, where a once speedy bar takes 50% of the time covering the last few pixels. And bars that occasionally jump backward in time are not the rarity you'd expect them to be. Even this past month, when I installed the macOS Sierra update, the process completed when the progress bar was only two-thirds full. DOOM 2016 has a circular progress meter for level loads, with the percent-complete in the center. It often sits for a while at 0%, gets stuck at 74% and 99%, and sometimes finishes in the 90s before reaching 100%. Clearly this is not a trivial problem, or these quirks would be behind us. Conceptually, a perfect progress bar is easy to build. All you need to know is exactly how long the total computation will take, then update the bar in its own thread so it animates smoothly. Simple! Why do developers have trouble with this? Again, all you need to know is ...exactly how long Oh. You could time it with a stopwatch and use that value, but that assumes your system is the standard, and that other people won't have faster or slower processors, drives, or internet connections. You could run a little benchmark and adjust the timing based on that, but there are too many factors. You could refine the estimate mid-flight, but this is exactly the road that leads to the bar making sudden jumps into the past. It's all dancing around that you can't know ahead of time exactly how long it should take for the progress bar to go from empty to full. There's a similar problem in process scheduling, where there are a number of programs to run sequentially in batch mode. One program at a time is selected to run to completion, then the next. If the goal is to have the lowest average time for programs being completed, then best criteria for choosing the next program to run is the one with the shortest execution time (see ). But this requires knowing how long each...
21st Dec 2016

Stay updated

Get a weekly newsletter with the top 5 articles worth reading every week.

More from Programming in the 21st Century

So Long, Prog21

I always intended "Programming in the 21st Century" to have a limited run. I knew since the entry from January 1, 2010, that I needed to end it. It just took a while.Recovering Programmer And now, an explanation. I started this blog to talk about issues tangentially related to programming, about soft topics like creativity and inspiration and how code is a medium for implementing creative visions. Instead I worked through more technical topics that I'd been kicking around over the years. That was fun! is something I would have loved to read in 1998. More than once I've googled around and ended up back at one of my essays.Purely Functional Retrogames As I started shifting gears and getting back toward what I originally wanted to do, there was one thing that kept bothering me: the word in the title.programming I don't think of myself as a programmer. I write code, and I often enjoy it when I do, but that term is both limiting and distracting. I don't want to program for its own sake, not being interested in the overall experience of what I'm creating. If I start thinking too much about programming as a distinct entity then I lose sight of that. Now that I've exhausted what I wanted to write about, I can clear those topics out of my head and focus more on using technology to make fun things.programmer Thanks for reading! It's hard to sum up 200+ articles, but here's a start. This is not even close to a full index. See the if you want everything. (There are some bits in there.)archivesodd Also see the for all of the functional programming articles.previous entry is something I wrote in 2004 which used to be linked from every prog21 entry.Programming as if Performance Mattered widely linked popular on creativity others that I like Erlang retro Things That Turbo Pascal is Smaller Than Do You Really Want to be Doing This When You're 50? Organizational Skills Beat Algorithmic Wizardry Retiring Python as a Teaching Language Computer Science Courses that Don't Exist, But Should Five Memorable Books About Programming A Spellchecker Used to Be a Major Feat of Software Engineering Want to Write a Compiler? Just Read These Two Papers. On Being Sufficiently Smart Optimizing for Fan Noise Free Your Technical Aesthetic from the 1970s Advice to Aimless, Excited Programmers Write Code Like You Just Learned How to Program Don't Distract New Programmers with OOP Recovering From a Computer Science Education Don't Fall in Love With Your Technology A Complete Understanding is No Longer Possible Solving the Wrong Problem This is Why You Spent All that Time Learning to Program We Who Value Simplicity Have Built Incomprehensible Machines Your Coding Philosophies are Irrelevant The Silent Majority of Experts Hopefully More Controversial Programming Opinions How much memory does malloc(0) allocate? The Pure Tech Side is the Dark Side Flickr as a Business Simulator How to Think Like a Pioneer What Do People Like? Accidental Innovation, Part 1 If You're Not Gonna Use It, Why Are You Building It? It's Like That Because It Has Always Been Like That Trapped by Exposure to Pre-Existing Ideas Get Good at Idea Generation You Can't Sit on the Sidelines and Become a Philosopher The Software Developer's Sketchbook Design is Expensive Why Doesn't Creativity Matter in Tech Recruiting? Deriving Forth Tales of a Former Disassembly Addict Living Inside Your Own Black Box Tricky When You Least Expect It The Most Important Decisions are Non-Technical Things to Optimize Besides Speed and Memory All that Stand Between You and a Successful Project are 500 Experiments The UNIX Philosophy and a Fear of Pixels Dangling by a Trivial Feature Documenting the Undocumentable You Don't Want to Think Like a Programmer You Don't Read Code, You Explore It If You Haven't Done It Before, All Bets Are Off What Can You Put in a Refrigerator? The Same User Interface Mistakes Over and Over Fun vs. Computer Science A Deeper Look at Tail Recursion in Erlang My Road to Erlang Garbage Collection in Erlang How to Crash Erlang Eleven Years of Erlang A Ramble Through Erlang IO Lists A Concurrent Language for Non-Concurrent Software A Peek Inside the Erlang Compiler Evolution of an Erlang Style A Personal History of Compilation Speed Slow Languages Battle Across Time How Much Processing Power Does it Take to be Fast? 8-Bit Scheme: A Revisionist History Stumbling Into the Cold Expanse of Real Programming Why Do Dedicated Game Consoles Exist? Lost Lessons from 8-Bit BASIC Programming Modern Systems Like It Was 1984

4th Jan 2017 50 votes

More in programming

Abusing ID3 chapters to turn videos into glanceable podcasts

I listen to a lot of podcasts, and I like how they fit around other tasks. I press play, lock my phone, and put it down. I’m free to wash the dishes, fold the laundry, or shop for groceries. Unfortunately, more and more information is only published as a video. Technical talks, conference sessions, video essays – they don’t work in an audio-only podcast app. I could convert these videos to MP3 files, but that breaks down the moment a video isn’t pure spoken word. If a speaker says, “Look at this slide” or holds up a diagram, an audio-only file leaves me stranded. I don’t want to give up the podcast player I like, nor stare at a screen for an hour – but I do want the information in these videos. To solve this, I’m abusing my podcast player’s chapter support. This gives me the best of both worlds: I can listen to a video as audio-first, and glance at my lock screen if I need a moment of visual context. The idea: Chapters every few seconds MP3 files can have ID3 metadata, and ID3 metadata can include chapters. A chapter covers a particular time range, and it can have an associated title, description, and cover art. My podcast app of choice is Overcast, which can’t play videos, but it does have robust chapter support. I can jump between chapters, navigate a table of contents, and see per-chapter cover art. To get videos into Overcast, I’m creating MP3 files with a new chapter every few seconds, and the per-chapter cover art is a corresponding frame from the video. As I play the file, I get a slow, stop-motion-like rendition of the original video. If my phone is locked, I can glance at my lock screen and see the current frame in the Now Playing screen. Overcast is developed by Marco Arment, and I got this idea from Forecast, his app for adding chapters to podcasts. In particular, I was struck by its ability to create chapters that don’t display in the chapter list – ideal if I don’t want a table of contents with hundreds of entries. As I was developing my script, I compared my output to the output from Forecast to ensure I was creating the chapters correctly. The code: FFmpeg and Mutagen There are three steps in this process: Convert a video file to an MP3 Extract images from the video at a fixed interval Insert the images as hidden chapters in the MP3 file Let’s go through each in turn. 1. Convert a video file to an MP3 Converting a video file to an MP3 is a single FFmpeg command: ffmpeg -i video.mp4 audio.mp3 This is consistently the slowest step of the process, and I do wonder if I could use different settings or an alternative encoder to make it go faster – but it’s not slow enough to be worth further investigation. 2. Extract images from the video at a fixed interval Extracting images from a video needs a more complicated FFmpeg command: ffmpeg -i video.mp4 \ -vf 'fps=1/5,scale=iw*sar:ih,scale=min(iw\,945):min(ih\,945):force_original_aspect_ratio=decrease' \ thumbnail_%04d.jpg This extracts an image every 5 seconds, downscales any image larger than 945 pixels square (while preserving the original aspect ratio), and saves the results as sequentially numbered JPEG images (thumbnail_0001.png, thumbnail_0002.png, and so on). The key is the -vf flag, which defines two FFmpeg filters: The fps filter selects one frame every 5 seconds (fps=1/5). The first scale filter scales the width based on the sample aspect ratio (scale=iw*sar:ih). Without this filter, frames can be stretched and distorted. The second scale filter scales the input video, preserving the original aspect ratio (force_original_aspect_ratio=decrease), and ensuring the output images fit within 945×945px or the size of the input video, whichever is smaller. My limit is 945 pixels because that’s the largest size that cover art is shown on my iPhone. This filter still isn’t completely correct – it sometimes creates images from portrait videos that are smaller than I’m expecting – but it’s good enough. These are only thumbnails for glancing at, and if I want to change it later, I can always do the image resizing outside FFmpeg. 3. Insert the images as hidden chapters in the MP3 file Inserting the chapters into the MP3 file is more complicated. Although FFmpeg has basic support for ID3 metadata, as far as I know, it can’t insert chapters with per-chapter artwork. Instead, I’m going to reach for Python and the Mutagen library. Here’s the code to add a chapter to an MP3 file: from mutagen.id3 import APIC, CHAP, ID3, PictureType audio = ID3("audio.mp3") with open("thumbnail_0001.jpg", "rb") as f: img_data = f.read() image_frame = APIC(mime="image/jpeg", type=PictureType.OTHER, data=img_data) chapter_frame = CHAP( element_id="chp1", start_time=0, end_time=5 * 1000, sub_frames=[image_frame] ) audio.add(chapter_frame) audio.save() This creates a single chapter that lasts the first 5 seconds (0 to 5000 milliseconds), and the per-chapter cover art is thumbnail_0001.jpg. If we ran this in a loop, we could add images for every 5 second slice of the original video. This code is inserting two frames into the ID3 metadata: The CHAP (chapter) frame contains the timing information, and it can have subframes for metadata like title, chapter art, or associated URL. The APIC (attached picture) subframe contains information about a picture, which can either be a blob of image data or a URL to an image on the web. Normally, you’d also insert a CTOC frame which defines a table of contents, but I don’t want a TOC with hundreds of 5-second chapters, so I’m deliberately not doing this here. This is allowed by the ID3 spec – you’re not required to insert a CTOC frame if you’re using chapters, and you can have chapters that aren’t listed in your table of contents. To work out which frames I needed, I used Forecast to create some chapters by hand, and I inspected their frames. In particular, loading an MP3 and calling Mutagen’s pprint() method shows a human-readable list of frames, and then I could drill into the individual fields: from mutagen.id3 import ID3 audio = ID3("audio.mp3") print(audio.pprint()) I wrapped all this code in a project called glancecast, which allows you to convert a video file with a single command, with optional flags to set the frame length and chapter art size: $ python3 glancecast.py interesting_talk.mp4 interesting_talk.mp3 The process takes a minute or so to complete, most of which is spent transcoding the video file to MP3. The resulting MP3s are usually 40 to 50 MB in size, which is very reasonable. The outcome: How it looks in practice Here’s what one of these “glanceable” podcasts looks like in Overcast and on my lock screen: Maggie Appleton presented this talk over two years ago and it’s been on my “talks to watch” list ever since. Once I put it in Overcast? I listened to it in less than a day. It’s not a lot of extra information, but enough that I can quickly glance down and get the gist of what a speaker is saying. Both views update with a new frame every few seconds, or I can put my phone in my pocket and ignore the screen. I’ve used this approach for half a dozen videos so far, and I’m happy with the results. I expect to keep using it, because I have a long queue of videos I’ve been meaning to watch. If you’d like to try this, check out glancecast for the full code and instructions. [If the formatting of this post looks odd in your feed reader, visit the original article]

yesterday 1 votes
AI Isn’t Replacing Open Source

Andrew Baker, the current Group CIO at Capitec Bank wrote an interesting piece on AI and open source, and how these tools that generate code according to one’s specification may replace the general reliance on open source implementations done by contributors around the world. I’d really recommend reading it. I have great admiration and respectContinue reading "AI Isn’t Replacing Open Source"

yesterday 1 votes
6-7 loops we use everyday to make PostHog self-driving

I've mostly given up keeping up with agent trends. Every few months, I ignore all of it and ask what I'm actually getting use out of. Three things…

yesterday 1 votes
Confessions of an Unrepentant Slop Snob

A framework for thinking about when AI involvement is additive or a violation

2 days ago 1 votes
Planning with Agents: Divided Worlds, Boundary Objects, and Thicker Interfaces

Why we need richer, thicker interfaces and better boundary objects for collaborative planning with agents

2 days ago 1 votes
📚 BoredReading

You seem to be enjoying this.

Join free to unlock everything.

Create free account

Already have an account? Sign in