By Casey Liss

The wonderful organization, App Camp for Girls, has been interviewing various people in the field as part of their “Fireside Chat” series. My interview was just posted, and I’m happy with how it turned out.

There’s a ton of great interviews; be prepared to lose a couple hours to all of them.

Also worth noting, App Camp for Girls is currently raising money to expand to three more cities by 2020. App Camp’s mission is to promote gender equality in technology, which is something everyone should be able to throw their weight (and money) behind.

If you have even a dollar to spare, please support AC4G. I have.


 

Though I haven’t talked about it here on the blog, I was lucky enough to get a week of seat time in a really nice car. That seat time was arranged by Sam Abuelsamid of Wheel Bearings.

When we set out to do Neutral, what we hoped to be creating was what Wheel Bearings actually is. Informed hosts, with diverse opinions, talking about all things automotive. Between Sam and Dan Roth, there is not only tremendous knowledge (which we lacked) and access to press cars (which we lacked).

On this episode of Wheel Bearings, we discuss the Alfa that I borrowed, and I pick a fight about Volvo’s Sensus infotainment system. When Dan and Sam could get a word in edgewise, they discussed the cars they’ve been driving recently, as well as Sam’s experience in an automated vehicle.

Wheel Bearings is a great show you should always listen to, and I like to think this is a great introductory episode.


Volvo's Key Tag

I’m a day late for my Thankful Thursday “thing I like” post, but yesterday was Erin’s birthday, so, I’m giving myself a bye. Keeping in the spirit of Erin, I’d like to talk about something I really love about her new car.

When we took delivery of Erin’s Volvo XC90, we were presented with this box:

Keys in fancypants box

I’ve never seen nor heard of keys coming in a fancy box like this, so immediately I was impressed. Everyone likes to feel special, and I felt like we were getting the white glove treatment. By comparison, though I bought my BMW used, I’d never heard of BMW keys coming in a fancy box like that.

However, the box isn’t what I want to talk about. I want to talk about that little piece of plastic that’s hiding in the right-hand side of the box. I took out the other full-size key so you could see it. The thing I like this week is the Volvo "Key Tag".

Erin’s XC90 has a proximity key, which it refers to as a “Passive Entry” and "Passive Start" system. In BMW nomenclature, it’s a part of “Comfort Access”. Regardless of the marketing name, the… well… key here is that you don’t need to ever touch the car key to enter and start the car. For someone who keeps his keys in his pocket, this is a fantastic feature that now I’m not sure I can live without. I can only imagine how convenient this is for someone like Erin who keps her keys in her purse.

In order to open either of our cars, we simply need to grab the door handles, as long as the key is on our person. Once we get in, we can turn the car on without touching the key. When we exit, we keep the key on us, and touch a special part of the door handle to lock the car. This largely obviates the traditional remote lock/unlock features of our car keys. I almost never use my car key to lock or unlock my car remotely; I only do so by grabbing the door handle.[1]

When it came time to claim one of Erin’s keys as my own, I immediately knew which one I wanted: the Key Tag.

Erin’s Volvo came with two traditional—and large—keys that have all the buttons you’re used to: lock, unlock, trunk release, and a panic button. But the Key Tag is the thing I like for this week.

The Key Tag also works as a proximity key, but doesn’t have any buttons on it. By not having any buttons on it, that means the Key Tag can be much much smaller than the full-size keys with remote lock/unlock. For someone who carries his keys in his pocket, that makes a world of difference. Further, the Key Tag is totally sealed, which means it’s also waterproof.

Since Erin wanted to carry a full-size key in her purse, I got my choice of either the other full-size key, or the Key Tag. Without hesitation, I chose the Key Tag. Even if this were primarily my car, I’d almost certainly[2] still choose to carry the Key Tag over one of the traditional keys. Having that much less in my pocket is fantastic, and I wish there were an equivalent for my car.

There’s a lot to like about Erin’s car, some of which I may talk about in the future, but the seemingly simple Key Tag may be my favorite.


  1. Before I get a bunch of "Well, actually"s, the one exception to this rule is that I do occasionally roll down all my windows from afar using my car key. This is not possible by physical contact with the car; only by holding the unlock button on the remote.

  2. The only problem with the Key Tag is that it doesn’t have a traditional "key blade" inside it, should the car’s electronics have a fault. Thus, if I were by myself with Erin’s car, and the battery died, I wouldn’t be able to get in the car to open the hood. That may cause me to carry the large key if it were my primary car, but as an at most occasional driver, I’m not too worried about it.


Mirror Mirror in the Code

For the last year and a half, I’ve been working full time as a Swift developer. I love Swift, and I’ve also been really enjoying diving into Functional Reactive Programming using RxSwift. Nevertheless, I find myself longing for something that I don’t have anymore: a robust introspection API.

When I was writing C#, I could write a simple class like this:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Now let’s say I want to send or receive a Person from a RESTful API. Perhaps the transmission will be JSON, and it will look something like this:

{
    "fn": "Casey",
    "ln": "Liss"
}

If we wanted to map a C# Person from a JSON dictionary, it’s reasonably straightforward, except that there’s an important discrepancy: we need to tie fn to FirstName and ln to LastName.

There’s a ton of ways one can create a link between those different names. My favorite, in C#, was to use introspection. In C#, this is called Reflection, and that’s how I still refer to it to this day.

Reflection is neat because it allows my code to learn about itself. That means I can add some metadata to my code—I can annotate it—in order to provide some supplementary information. How does that work in practice? Let’s augment the Person class, adding and leveraging a new Attribute.

public class JsonKeyAttribute: Attribute
{
    public string Key { get; set; }

    public JsonKeyAttribute(string key)
    {
        this.Key = key;
    }
}

public class Person
{
    [JsonKey("fn")]
    public string FirstName { get; set; }

    [JsonKey("ln")]
    public string LastName { get; set; }
}

Now we are annotating our properties with new metadata: we’re storing the keys needed to translate to/from JSON right there inline. How do we leverage it? Let’s write a static factory method:

public class Person
{
    [JsonKey("fn")]
    public string FirstName { get; set; }

    [JsonKey("ln")]
    public string LastName { get; set; }

    public static Person FromJson(string jsonString)
    {
        var retVal = new Person();
        var properties = typeof(Person).GetProperties();
        foreach (var property in properties)
        {
            var attribs = property.GetCustomAttributes(typeof(JsonKeyAttribute), true);
            var attrib = attribs.FirstOrDefault() as JsonKeyAttribute;
            if (attrib != null) 
            {
                var key = attrib.Key;
                var value = // Get value from JSON object 
                            // using the key we just discovered.
                // Set the property's value
                property.SetValue(retVal, value);
            }
        }

        return retVal;
    }
}

Admittedly I’ve fluffed over the conversion from JSON string to something meaningful, as well as glossing over extracting "Casey" and "Liss" from the JSON. However, the rest of the code is the point. We can leverage Reflection to look at the Person class and see what the key is for each of its properties.

Having the ability to annotate our code with information about itself is super powerful. Using an Attribute, we were able to leave information about how to convert between different representations of the same data right in the class that needs to know about it. Some purists say that’s a poor separation of concerns; to me, that’s improving local reasoning.


Furthermore, using annotations can accomplish interesting things in arguably far cleaner ways.

As an example, if you want to specify a “pretty printer” for the purposes of debugging a Swift class, you can use CustomDebugStringConvertible. However, to do so, you must implement the protocol. For example:

struct Person {
    var firstName: String
    var lastName: String
}

extension Person: CustomDebugStringConvertible {
    var debugDescription: String {
        return "\(firstName) \(lastName)"
    }
}

The approximate equivalent in C# is arguably cleaner, because it doesn’t require implementing a new interface. Instead, you simply leverage the DebuggerDisplayAttribute:

[DebuggerDisplay("{FirstName,nq} {LastName,nq}")]
public class Person
{
    [JsonKey("fn")]
    public string FirstName { get; set; }

    [JsonKey("ln")]
    public string LastName { get; set; }
}

I can think of a ton of other places where reflection is useful as well. I’m particularly interested in how cool it could be to really open up the already crazy-powerful Swift enums by adding the ability to annotate them, or reflect over them. Oh, the crazy things I could do… 🤔


Reflection isn’t for everyone. In fact, I got the following email from an ATP listener:

If you need reflection to reason about and execute code runtime, your API is poorly designed. Can you please explain why you feel the the need for a reflection API?

That’s a pretty severe take-down.

I understand the sentiment, and this particular listener isn’t necessarily wrong. But what I love about reflection is that it opens up the possibility for a whole new way of solving problems. A way that I’ve found to be quite convenient from time to time.

In fact, all of you Objective-C developers out there may enjoy doing things like this on occasion:

id person = [[NSClassFromString("Person") alloc] init];

To me, that’s reflection.

A while back there was a big kerfuffle amongst some Objective-C developers who were, erm, objecting to the lack of Begin scare quote dynamic End scare quote features in Swift. To me, the canonical, level-headed post about this was this wonderful post by my pal Brent Simmons. It’s an extremely short but accurate summary of what all of the Objective-C folks seemed to think Swift was lacking.

To me, I can summarize his post in one word: reflection.


 

In the midst of the announcements over the last couple days, I didn’t get a chance to call out that I was on this week’s episode of the always-fun, always-brief Clockwise podcast.

This week, I joined Dan Moren, Mikah Sargent, and Kathy Campbell. We discussed messaging apps, LTE Apple Watches, how we get our news, and guilty [app] pleasures.

I always enjoy both recording and listening to Clockwise; you probably will too.


Sometimes, It's the Same as It Ever Was

In so many ways, I’m still riding the wave.

After four years of trying, when we finally had Declan, it felt like a tremendous weight was off of our chest. As I said to Erin repeatedly over the first several days, we did it. We had finally come to the end of this arduous, seemingly endless road that we had been on. Of course, we didn’t have much time to look in our rearview mirror; infants wait for no one.

Over time, we settled into our new normal. In many ways it likely was—and remains—harder for Erin than it is for me. I disappear for 8-10 hours a day almost every day. Erin, however, has no Off position. I try to take Declan as much as I can on the weekends, but for her, she’s never really not Mommy.


Despite this, after a couple years, the struggle to bring Declan here fades, even if only slightly. It’s a memory how hard raising an infant is. We remember that visiting the fertility doctor is inconvenient, frustrating, and often fairly demoralizing; but it was so long ago. We fall out of the habit of living our lives around Erin’s cycle; remembering now it is often times disrupting.

It’s the same as it ever was.

Naturally, our ever-optimistic families have a different party line, mostly regarding Erin: “You never know! Maybe now that your body has done it once, it knows exactly what to do!”

😑

It was quickly apparent that we were not that lucky.


As we restart our journey, Erin and I don’t realize that it’s disrupting to more than just us now. It’s exceptionally selfish to bring a child to a fertility clinic, so that means we need to ask family or our friends to watch Declan as we go. We have to schedule appointments around not only our own schedules, but that of another person entirely: Declan.

Perhaps it’s not that much like last time after all.

What’s most striking, though, is how different our attitudes are. When we were walking this path trying to conceive Declan, every single moment was monumental. Every time seemed like our last shot, even when it really wasn’t. Every time we were worried, scared, nervous, and most of all, hopeful.

As Erin and I start following the same procedures, and have the same kind of help as we did last time, we realize how this is our new normal. Even moreso than with Declan. While it definitely sucks, going through all these motions doesn’t carry the same weight it did. Even if we can’t conceive this time, we’ve still succeeded already; we’re still parents.


We got lucky… again.

Sprig Ultrasound

We’re so happy to share that Erin is pregnant again!

As I write this, Erin is 19 weeks along. So far, everything seems well. Erin had the pleasure of dealing with a fair bit of nausea for the first trimester, but for the last several weeks, that has subsided. To my eyes, she’s showing more—and sooner—than last time. I find that adorable; Erin is still… adjusting. 😉

Someone else, however, has been particularly interested in the goings on.

Sprig and Sprout

As with last time, we needed to pick a designated emoji. “Sprout”—🌱—is a high bar. After much deliberation, Erin and I landed on “Sprig”—🌿.

We don’t know 🌿’s gender yet, but there’s a sealed envelope in our house that does. This may be our last opportunity to get the surprise of the gender at the time of birth, so we’re attempting to hold out. That said, a smart gambler would bet on us caving and opening that envelope sooner rather than later.

Declan refers to Sprig as a “he”, but he talks about his “baby sister”. 🤔 As one would expect, Declan has also informed us that he, too, is growing a baby in his belly. In fact, he’s even asked for us to take a picture of his growing belly before we take weekly shots of 🌿. 😂


We’re petrified, but excited. We’re thrilled, but worried. So much of this feels so much different than last time. We’re more relaxed, and yet, in so many ways, it’s the same as it ever was.

Either way, if all goes to plan, we’ll meet you in the first week of January, Sprig. Well, unless you come early, like Declan did…

I know I speak for your momma, and your older brother, in saying:

We can’t wait to meet you.

Footprints in the sand
 

Last Thursday, I discussed youtube-dl, a tool that allows you to easily download various kinds of media from the web. What happens once you have that media? Or what happens if you want to do something with media you already have?

ffmpeg is almost always the answer. It can take nearly any form of audio or video media and convert it to almost any other form. It can extract clips, transcode media, rotate it, crop it, downsample, upsample, etc. ffmpeg is truly omnivorous.

In fact, many media players and/or transcoders that you may know and love are actually just graphical front-ends for ffmpeg. Handbrake and Plex are two examples that spring to mind.

I’ve spoken about ffmpeg many times in the past, and I’ve often been asked to write a primer on how to use it. To cover every nook and cranny of ffmpeg would take forever, so instead I’ll just cover a handful of examples I find myself using often.

Installation

The easiest way to install ffmpeg is to use Homebrew:

brew install ffmpeg

There are some nuances to installation if you want support for certain sub-sets of functionality, but the above will at least get you started.

Basic Usage

Let’s say you downloaded a file using youtube-dl and it ended up in a format you didn’t expect:

youtube-dl "https://www.youtube.com/watch?v=s64RnXSwn-A"

The resulting file is of type .mkv; let’s say the full filename is input.mkv just to make things easier. MKV files are not a format that Apple OSes tends to like. Let’s suppose you want to convert that into something more Apple-friendly, like a .mp4. That’s simple to do:

ffmpeg -i input.mkv output.mp4

We’re using the -i parameter to specify the input file to ffmpeg, and then we’re simply specifying the output file. By virtue of the .mp4 extension, ffmpeg is smart enough to divine what to do.

Similarly, if we wanted to extract the audio from this video after we’ve already downloaded it, we could do so as such:

ffmpeg -i input.mkv output.mp3

Again, the presence of .mp3 will tell ffmpeg all it needs to know.

Trimming

If you actually watch the video, there’s an intro section and an outro section that we really don’t need. The intro ends at 46 seconds. We can instruct ffmpeg to start the output at that point:

ffmpeg -i input.mkv -ss 00:00:46 output.mp3

Here, we’re using the oddly-named -ss parameter to set the hours:minutes:seconds into the input we wish to seek before we start “recording”, so to speak.

However, we haven’t gotten rid of our outro yet, which lasts for the last six seconds of the video. We can handle that using the -to option, which sets when to stop processing the input file, in the time system of the input file. Since output.mp3 is 4:34 seconds, then we need to subtract 6 from that, to land on 00:04:28:

ffmpeg -i output.mp3 -to 00:04:28 trimmed.mp3

What if we wanted to do both at once? We can use the -to parameter to set the end point (again, in terms of the input), in addition to the -ss to set the start time. Note, though, we’re using the original file as the input again. Thus, we have to change the end point for the -to since we’re starting from the full file, not the one with the intro clipped. Finally, we land on this "compound" command:

ffmpeg -i input.mkv -ss 00:00:46 -to 00:05:13 trimed.mp3

In one shot, we’ve:

  • Stripped the audio
  • Transcoded the audio
  • Trimmed the beginning
  • Trimmed the end

Pretty cool stuff, and pretty easy, once you learn to speak ffmpeg.

Cropping

What if you download a different file, but it has bars on the top/bottom or left/right?

youtube-dl "https://www.youtube.com/watch?v=tTiiDQ03eSQ"

In this case, we’d like to remove the small black bars on the left and right sides of the video. We know we need to take off about 10 pixels total; 5 on both the left and right sides. We can do so by using a video filter:

ffmpeg -i input.mp4 -vf "crop=in_w-10:in_h" cropped.mp4

The crop parameter to the -vf (video filter) parameter indicates what the resolution of the width and then height of the output video should be. We use the in_w and in_h macros to indicate the source width and height; then we subtract 10 from the width.

Codecs

Continuing with the above example, we can make this ever-so-slightly faster. We know that we want the final file to be in the same format—.mp4—as the source was. Since we’re not doing any sort of modifications to the audio, we can tell ffmpeg to copy the audio codec:

ffmpeg -i input.mp4 -vf "crop=in_w-10" -acodec copy cropped.mp4

Since the audio is far easier to process than the video, this isn’t the best example, as the time savings are marginal. However, in some cases, you may be able to get away with copying the video codec using -vcodec copy. In those cases, that is a big time savings.

It’s beyond the scope of this article, but a nice way to figure out if you can leverage -vcodec copy is to run a command with no output:

ffmpeg -i input.mp4

That will tell you what the video and audio streams are:

Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 819 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc (default)
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)

In our case, we know that the video is h264, which means that we can use -vcodec copy is possible if we’re converting to .mp4.

Variable Bit Rates

Related to codecs, when left to its own devices, ffmpeg will encode mp3s at a constant 128kbps. That’s sufficient, but I prefer to use a variable bit rate. To do so, we use a less intuitive incantation:

ffmpeg -i input.mkv -codec:a libmp3lame -qscale:a 2 output.mp3

This is… completely bonkers. Ridiculous incantations like these—if not the ones that preceded it—are why ffmpeg gets a bad name. However, the sheer versatility of ffmpeg makes it an indispensible tool that I can’t imagine living without.

I’ve set up a folder in the Apple Notes app with a series of “recipes” for ffmpeg. As I find a new task I want to accomplish, I determine what the recipe is, and then write it down as a new note in that folder. You may find the same tactic is useful for you. Regardless, most of that “recipe book” has been recreated above.

I know the command line is scary, but ffmpeg is worth getting over it. Everything you do in ffmpeg is non-destructive, so the only harm in playing around is wasting time and listening to your computer’s fans scream. At first I never did anything more than transcoding using ffmpeg, but over time, I’ve gotten to be pretty confident with it.


 

I recently wrote about BMW’s The Hire series, starting a hopefully-weekly series about things that I like. That was… two weeks ago. Can’t win 'em all.

Nevertheless, today I’m back at it, and I have something else I like that I’d like to highlight: youtube-dl.

Have you ever wanted to download something that was available on YouTube? Perhaps you wanted to grab only the audio, but didn’t need the video? Perhaps, of a song you enjoy or of a concert you recently stumbled on. Maybe you want to grab something that isn’t on YouTube at all?

youtube-dl can do all of these things. And much, much more.

youtube-dl is a command line utility that allows you to download video (or, if you prefer, only the audio) from a staggering list of websites. I know that as soon as I say “command line”, many will go running. Seriously though, it’s really simple:

youtube-dl "https://www.youtube.com/watch?v=pngDPqubloo"

Wait a little while, and you’ll have a download sitting on your local disk.

What if you just want audio? Easy-peasy.

youtube-dl -x "https://www.youtube.com/watch?v=iCXItGrjqrw"

What if you wanted to download something that, as far as you can tell, is only available via streaming via the web? In many instances, you can use the developer tools in your browser of choice to find the m3u8 playlist that is being streamed, and feed that to youtube-dl. It will download the stream and save the result locally. This has… come in useful… from time to time.

youtube-dl is a staggeringly useful tool that I use easily every single week. If you’re one who likes to build up a large library of oft-watched videos, it’s indispensible. Or, perhaps if you are just wanting to watch a video on a long flight, you can download it onto your laptop in advance. Either way, there are other tools similar to youtube-dl, but I’ve not found one I like more.


A Silly Theory

We’ve heard some interesting things over the past few weeks:

Could the next iPhone—particularly a special edition halo like the "iPhone Pro"—have no ports at all?

Most obviously, the headphone jack is already gone. Furthermore, we’ve been programmed that Bluetooth audio is the future. If we add wireless charging, do we really need a lightning port anymore? Especially in a halo phone? We’ve made this sort of thing work with the Apple Watch already[1].

Given that I’m sitting at the beach, I can imagine quite a few ways where one could easy market a phone that has no ports, and as such, is considerably more water resistant.

This surely isn’t an original idea, but the more I think about it, the more I think it makes sense. Especially in the context of a specialty Begin scare quote Pro End scare quote iPhone.


  1. I concede that things like DFU restores will need to be resolved, but here again, we’ve mostly made this work for the Watch.


 

This week I was a guest on Collin Donnell’s The Run Loop. I’ve recently started listening to The Run Loop; it’s a great interview show with various developers in our community—and not just the ones most of us already know.

On my episode, Collin and I talked about QBasic, the live episode of ATP, a surprising amount about software methodologies, and, of course, RxSwift. It’s nice to stretch my legs and get really nerdy from time to time; this was one of those times.