Repository navigation
feat(convert): per-track log, and our own art placeholder - #9
Merged
Merged
Conversation
A cover the webview cannot decode is not a missing cover as far as the <img> is concerned: WebKit swaps in its own broken-image icon, which on macOS is the system question mark tile — foreign to this UI and readable as neither "no cover" nor "bug". The thumb now reports the failure to the artwork cache, so the key falls back to the music-note placeholder for every later mount rather than only the one that happened to paint it. The mark is an ordinary cache entry, so invalidateArtwork drops it and a replaced cover is fetched again.
Half the cores left the UI responsive but not the audio: with eight decode+resample chains running, CoreAudio's render thread loses the race often enough that music playing on the machine stutters for as long as a batch lasts. Two workers still halve the wall clock against a plain queue, which is where most of the win was.
A successful job used to leave a log holding a header, a footer and
whatever ffmpeg happened to complain about — no record of the tracks
themselves. Each one now writes a start line and a result line, and the
result carries what the file turned out to be:
✓ FKJ - Blessed.flac: converted in 0.7s · ALAC 16-bit 44.1 kHz stereo
· 28.5 MB · 856 kbps
Those facts are read back off the finished file rather than derived from
the request: a passthrough that skipped the encode, or a VBR pass that
landed nowhere near its nominal rate, would otherwise be reported as
whatever was asked for. The extra ffprobe is gated on the observer
wanting it, so the drag-and-drop import path does not pay for it.
Three things the per-track lines exposed:
- ffmpeg's own lines carried the destination name while ours carried the
source, so one track appeared in the log under two names.
- swscale's "deprecated pixel format" fires once per track of an album
with art, from cover normalization this app asks for itself.
- the failure line repeated ffmpeg's whole stderr tail, which had already
been logged line by line just above it.
Colour follows who is speaking rather than one hue per level: the app
narrating its own progress stays muted, ffmpeg keeps amber, and the only
two saturated colours are the states a reader scans for — landed and
failed. Both are the queue's existing tones, so a track that went green
in the list is green in the log too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three unrelated fixes that came out of one session with a real iPod: a
cover the webview cannot decode no longer paints macOS's question mark,
the convert log now has a line per track instead of one per run, and the
batch runs two workers rather than half the machine's cores.
Changes
broken-image icon on macOS is the system question-mark tile, which
reads as neither "no cover" nor "bug".
ArtworkThumband the importdialog now catch the decode failure and paint the music-note tile;
the artwork cache records it, so every later mount of that key agrees
and
invalidateArtworkstill clears it when the cover is replaced.cores/2. Eight decode+resamplechains starve CoreAudio's render thread — music playing on the machine
stutters for as long as a batch lasts. Two still halve the wall clock
against a plain queue.
and result lines per item, the result carrying codec, depth, rate,
channels, size and average bitrate — read back off the finished file
with ffprobe rather than derived from the request, so a passthrough or
a VBR pass cannot be reported as whatever was asked for. The probe is
gated on
ConvertObserver::wants_stats, so the drag-and-drop importpath does not pay for it.
carried the destination name while ours carried the source, so one
track appeared twice under two names; swscale's "deprecated pixel
format" warning fires once per track from cover normalization this app
asks for itself; and the failure line repeated ffmpeg's whole stderr
tail that had already been logged line by line above it.
narrating its own progress stays muted, ffmpeg keeps amber, and the
two saturated colours go to the states a reader scans for. Both are
the queue's existing tones, so a track that went green in the list is
green in the log.
Test plan
cargo test— 47 unit + 12 round-trip, green. New tests cover theoutput-summary formatting (units, lossy output claiming no bit depth,
an unknown bitrate omitted rather than printed as zero) and the
swscale line being filtered.
npm test— 128 green, including four new cases for the undecodablemark: it holds, it does not refetch the same bytes, it does not leak
to another size or track, and it clears when the cover is replaced.
npm run typecheck,cargo clippy --all-targets— clean.prepare_batchwith the same observer the job uses: 4 FLAC to ALAC and to MP3, plus a
deliberately corrupt file for the failure path.
npm run bundleand launched.