ffmpeg can produce pseudo-corrupt audio when ‘copy’ing to an MP4 container

I’ve been using ffmpeg to trim clips from a trail camera, as most of the time there’s only a few seconds of anything interesting in frame out of the 30+ seconds of video it records each time, but I don’t want to re-encode them and lose video quality as a result (or balloon file sizes tremendously with a lossless video coding).  Keeping the whole 30 seconds is not just unnecessary and makes viewing the videos much more tedious, but wasteful of storage space as the encoding quality from the trail camera is very inefficient (file sizes are many times larger than they should be for the quality – clearly the H.264 encoder used in the trail camera is very cheap and very bad at its job).

I was originally doing something like:

ffmpeg -ss 00:07 -t 00:03 -i "IMG_0164.MP4" -async 1 -c copy "IMG_0164_TRIMMED.MP4"

The resulting trimmed MP4s play just fine in Quicktime, the Finder – anywhere that uses Apple’s decoding libraries (though I didn’t test iOS).

However, in VLC, or Lightroom, the audio is completely corrupt – just incoherent noise.  In Lightroom the video doesn’t even play correctly, because of Lightroom’s stupid habit of re-encoding the video & audio into internal caches – apparently their video decoder is somehow thrown off by the audio channel issues, too.

After much trial and error and many dead-ends (thank you completely bogus & wrong Stack Overflow threads… sigh) I eventually realised that the problem is apparently simply that Lightroom, VLC, etc get offended when you include pcm_s16le audio in an MP4.  ffmpeg itself says that’s not a valid audio codec for the MP4 container, iff you explicitly tell it to use that as the codec.  If you’re just copying from an existing audio / video file, however, it makes no mention at all of the concern.  Sigh.

So the apparent solution is simply to switch to the MOV container format instead.

ffmpeg -ss 00:07 -t 00:03 -i "IMG_0164.MP4" -async 1 -c copy "IMG_0164_TRIMMED.MOV"

The encoded bits remain identical, but the MOV container apparently accepts PCM audio where MP4 does not.  VLC, Lightroom, etc are now happy (and Quicktime et al remain happy).

(another possibility is that the ‘incompatibility’ is related to MP4 levels or some other such junk… I didn’t try deciphering or exploring that)

It’s frustrating that VLC & Lightroom can’t handle this when clearly it’s technically possible (witness Quicktime), and worse they don’t even properly recognise that they’re not handling it properly – they just play completely corrupt audio that’s literally painful on the ears.

It’s also very curious that the trail camera uses PCM audio if that’s not valid in an MP4 container.  It’s downright bizarre that VLC & Lightroom can play the unmodified MP4s straight from the trail camera, even though they use the same purportedly invalid audio codec… somehow something ffmpeg is doing during its transmutation is making them angry.  I was unable to determine what that might be, though, through trial-and-error with ffmpeg command line options & rudimentary examination of the input & output files.

P.S.  An alternative is to bitwise-copy only the video stream (i.e. change -c copy to -c:v copy), and let VLC transcode the audio into its default AAC for the MP4 container.  That probably wouldn’t be a problem for me in my case – the audio from trail cameras is pretty crappy to begin with – but at the same time the audio tracks in these files are insignificant in size, so re-encoding them (and lossy as AAC) is pointless to saving disk space.

Better is the enemy of best

You might have heard the aphorism “Perfect is the enemy of good“.  If you’re in a technical field, you’ve probably used it, or had it used against you, to shut down a conversation.  It’s an effective way to do so because it insinuates that the target is thinking impractically, not focused on the problem at hand, rat-holing or bike-shedding or yak-shaving or otherwise getting distracted from “getting shit done”.  All clearly faults, right?

Its original wording, “better is the enemy of good”, more clearly reflects its defeatist mentality that presumes things can’t be much, if any, better than they are now – always implied as the aforementioned ‘good’.  It’s often taken to its extreme – unintentionally ironically – as part of perfect solution fallacies – that it must be impossible to achieve perfection, so why even try?

It can be very difficult to rebut because in practice it’s somewhat subjective & contextual, and thus judged in the context of the dominant culture – which in tech, currently, is pervasively biased towards doing things.  Not necessarily the right things – just things.  Move fast and break things.

Further challenging the defence is that it’s often considered ‘above my pay grade’ to think about the bigger picture.  Especially down where the rubber meets the road and people have deadlines and quotas and (believe they) are judged solely by the volume of work they complete.  In that environment, targeting someone with that aphorism is labelling them as being disruptive, slowing things down, and not having their priorities in order.  A would-be tall poppy.  A Troublemaker™.

In short, it puts the target on the defensive for an indefensible position – and makes it personal, no less.  It is, in a way, a nuclear option – the conversation abruptly ends with no actual conclusion, and no problems actually addressed.

It is in fact a clever ruse, and while usually used well-meaningly rather than viciously & tactically, either way it’s usually used unfairly, inappropriately, and worst of all, incorrectly.

Amongst its many flaws, in practice if not in logic, I believe its worst is that it conflates the path of least resistance with the right path.

Building a better horse.

It is a pervasive practice within business to look at where you are now and where you can go from there.  This is called incremental planning.  An instrument & exemplar of this mentality is SWOT analysis.  In a nutshell:  what have I got going for me, what’s going against me, and how can I work with that against my immediate environment?

It is supposed to be applied tactically.  When misused as a strategy, it does so predicated on the belief that by incrementally improving along the path of least resistance – i.e. opportunistically – one will inevitably triumph above all others.

That is the kind of thinking which leads to building a better horse, rather than realising you can build a car instead.

It is applying the process of finding your local maximum, in ignorance to finding bigger maxima.  It is short-sighted and tunnel-visioned and preys on our lizard brain’s desire for constant gratification and reassurance that we’re making forward progress.

In a competitive environment it is guaranteed fatal, because sooner or later one of your competitors will find a bigger maximum.  Or worse, someone from outside your market entirely, not so constrained in their thinking, will come in and set up shop on the slopes of a much bigger maximum to begin with.  Ever heard of an ‘iPhone’?

Of course, not all tech environments actually have competition.  If you’re working on a company-internal product, yours is usually the only one within your company.  You have a captive market with zero competition.  So unfortunately, you’re free to produce bad products indefinitely, at least insofar as they’re not so bad that they bring down the whole company.  And for as long as you can convince your bosses that you’re working really hard and it’s a really hard problem and look at how big these closed bug numbers are.

Thankfully, there are other motivations – than market dominance or conservation – for building better things.  Some people have an innate desire to do so.

Where are you going?

The incremental planning approach leaves it to a higher power to determine if you’re even heading in the right direction.  It is by definition short-sighted, putting emphasis on speed and not direction.  It is dangerously optimistic.

If you don’t know where you’re going, you might not get there.

Yogi Berra

Incremental development is not the problem.  It is not at odds with vision & leadership.  It is just all too often confused with, and entangled with, incremental planning.

You cannot know where you should be going if you don’t know what the possibilities are, and specifically what the best possibilities are.  Once you’ve identified them, only then can you investigate how to get to them – and thus in what direction you need to move.

Thus why the first step in any kind of development – technical, business, or otherwise – must be to identify where you want to be, irrespective of where you are currently.  That in itself is a complicated task – full of whats and whys – but given that, then you figure out how you might get there.  With that map and route in hand, then you act on that, and only then do you turn your focus to speed – to execution.

And this is where “Perfect is the enemy of good” actually comes in, in its correct usage.  What you identify as the highest place to be might be very difficult to reach from where you are now.  Perhaps there is a different place that’s nearly as high, but much easier to get to.  That might offer the best return on investment, and thus be the best solution.  Especially if it gets you closer to the highest place as well – what you cannot do today, you might be able to do tomorrow.

You must, in effect, put the car before the horse.  If you do not currently possess the means to build a car, find a way of building better horses that gets you closer to building a car, so you at least have a chance of building cars in the future.

[Mechanical Horse patent image used under CC BY 2.0 license from Patents Wall Art on Flickr – available as real wall art through their Etsy store.]

Apple Mail crashes on launch if connection logging is enabled

This was a fun one.  Mail started crashing on launch for absolutely no apparent reason – nothing had changed to its config or similar in a long time.  The crash logs were all fingering an identical culprit – -[IMAPTaskManager secondaryIdleMailboxName] called on the wrong GCD queue:

Process: Mail [19884]
Path: /Applications/Mail.app/Contents/MacOS/Mail
Identifier: com.apple.mail
Version: 11.3 (3445.6.18)
Build Info: Mail-3445006018000000~4
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Mail [19884]
User ID: …

Date/Time: 2018-04-19 16:44:45.717 -0700
OS Version: Mac OS X 10.13.4 (17E199)
Report Version: 12
Anonymous UUID: …

Sleep/Wake UUID: …

Time Awake Since Boot: 94000 seconds
Time Since Wake: 530 seconds

System Integrity Protection: enabled

Crashed Thread: 13 Dispatch queue: Task Manager Serialization Queue (QOS: UNSPECIFIED)

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This method should only be called on the serialization queue'
terminating with uncaught exception of type NSException
abort() called

Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff55da96bb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff7d4c1942 objc_exception_throw + 48
2 CoreFoundation 0x00007fff55daf2a2 +[NSException raise:format:arguments:] + 98
3 Foundation 0x00007fff57ee7340 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 IMAP 0x00007fff6fe88959 -[IMAPTaskManager secondaryIdleMailboxName] + 216
5 IMAP 0x00007fff6fe880cb -[IMAPTask mailboxIsUserVisibleUsingDataSource:] + 180
6 IMAP 0x00007fff6fe6ab68 -[IMAPMailboxSyncTask _nextNetworkPriorityAndOperation:reservedNetworkPriority:] + 164
7 IMAP 0x00007fff6fe6c4ba -[IMAPMailboxSyncTask recalculatePriorities] + 398
8 IMAP 0x00007fff6fe67dd9 -[IMAPMailboxSyncTask initWithDataSource:taskManager:imapMailbox:fromStatus:forceFullSync:] + 766
9 IMAP 0x00007fff6fe931f7 -[IMAPTaskManager _syncMailboxWithDataSource:withIMAPMailbox:fromStatus:forceFullSync:userInitiated:] + 370
10 IMAP 0x00007fff6fe92e68 -[IMAPTaskManager syncMailboxWithDataSource:withIMAPMailbox:fromStatus:forceFullSync:userInitiated:] + 240
11 IMAP 0x00007fff6fe9631a -[IMAPTaskManager didAddMessagesWithUnknownUID:toDataSource:] + 872
12 Foundation 0x00007fff57e4a5df __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
13 Foundation 0x00007fff57e4a441 -[NSBlockOperation main] + 68
14 Foundation 0x00007fff57e488ee -[__NSOperationInternal _start:] + 778
15 Foundation 0x00007fff57e44917 __NSOQSchedule_f + 369
16 libdispatch.dylib 0x00007fff7e09ee08 _dispatch_client_callout + 8
17 libdispatch.dylib 0x00007fff7e0b1ed1 _dispatch_continuation_pop + 472
18 libdispatch.dylib 0x00007fff7e0a9783 _dispatch_async_redirect_invoke + 703
19 libdispatch.dylib 0x00007fff7e0a09f9 _dispatch_root_queue_drain + 515
20 libdispatch.dylib 0x00007fff7e0a07a5 _dispatch_worker_thread3 + 101
21 libsystem_pthread.dylib 0x00007fff7e3f0169 _pthread_wqthread + 1387
22 libsystem_pthread.dylib 0x00007fff7e3efbe9 start_wqthread + 13

Long story short, the issue turns out to be having connection logging enabled.  That’d been turned on many months before in order to debug a different stupid Mail bug, and had been simply left on (deliberately IIRC, since Mail tends to bug-out quite often, so why not have logs already available when it comes time to debug it yet again?).

Connection logging is enabled or disabled by opening the “Connection Doctor” (Window menu > Connection Doctor) and using the checkbox titled “Log Connection Activity”.

So how do you get to that checkbox when Mail crashes on launch?  Well, in this specific instance I was able to disable all mail accounts via System Preference’s Accounts pane, launch Mail, disable logging, quit Mail, re-enable all mail accounts via System Preferences, and then relaunch Mail to have it finally actually work.

From even just brief web searching, it’s clear that this issue has been present and well-known in Mail for a really long time.  Sigh.  Apple’s protestations that they care about software quality, or the Mac, are relentlessly undermined by their actual actions.