Repository navigation
Convert tracks with ffmpeg on the way to a USB - #17
Merged
Merged
Conversation
A sync and its review can name a format. The USB job (schema 4) carries it, and es-usb hands the SDK an ffmpeg converter: tracks not already in that format are encoded straight onto the stick, their cues, beat grid and detail waveforms moved by the encoder delay. The library and its files are left as they are. The stick records each conversion, so syncing again with the same format re-encodes and re-copies nothing, and the review says so. Converting gets its own progress phase. The SDK submodule moves to the branch with the converter hook.
There was a problem hiding this comment.
🟡 Changes recommended
AAC bitrate metadata can be inaccurate, and the outdated device-import fixture is rejected by the new job schema.
2 open issues
What changed in this PR
Adds backend support for converting audio during USB export without changing library files. The conversion preset flows through the app and native layers into the USB exporter; UI controls remain deferred.
Changes:
- Pass optional conversion presets through review and sync using job schema 4.
- Add an ffmpeg converter with output metadata, analysis shifting, size estimates, and a distinct conversion phase.
- Extend sync-plan types and tests for converted exports and unchanged repeat syncs.
| File | Description |
|---|---|
| native/crates/es-usb/src/main.rs | Accepts schema 4 jobs and connects the converter to review and export. |
| native/crates/es-usb/src/convert.rs | Implements ffmpeg conversion and associated metadata handling. |
| native/crates/es-usb/Cargo.toml | Adds conversion, tag-reading, and analysis dependencies. |
| native/crates/es-node/src/usb.rs | Validates and forwards conversion presets. |
| native/crates/es-node/src/library.rs | Exposes optional presets through native bindings. |
| native/crates/es-engine/tests/sync.rs | Covers converted exports, library preservation, and repeat syncs. |
| native/crates/es-engine/src/sync.rs | Serializes conversion presets into schema 4 jobs. |
| native/crates/es-engine/src/library.rs | Threads presets through library service methods. |
| native/Cargo.lock | Records the USB exporter's added dependencies. |
| app/src/preload/engine.ts | Defines conversion parameters and expanded sync-plan fields. |
| app/src/main/library.ts | Forwards conversion parameters to native methods. |
| app/src/main/audio/native.ts | Updates native interface signatures for optional conversion. |
Review effort: Balanced
…test uses job schema 4 Only MP3 is encoded at a constant bitrate, so other conversions record the bitrate measured from the output (the requested one when none is read). The device import fixture sends job schema 4 like the exporter now expects. The SDK moves to the reviewed converter branch.
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.

Part 5 of the "convert audio on USB export" series. Stacked on #16; the SDK submodule points at claw1200/es-rekordbox-sdk#3 (which includes #2) — re-point after those merge.
Backend for "convert tracks to a chosen format when exporting to USB". Nothing in the library changes: conversion happens inside the USB export, straight onto the stick.
Flow
usb.syncReview/usb.syncaccept an optionalconvertpreset (same shape as track conversion) → main → es-node (clean_preset) → es-engineinspect_volume/sync_volume(…, convert)→ USB job schema 4 gainsconversion→es-usbbuilds anFfmpegconverter and passes it torb_usb::Options.converterfor both the review and the export (so the review token covers the chosen format).es-usb
Ffmpegconverter (AudioConverterfrom SDK #3)wants:es_convert::matches_formatis false → only tracks not already in the format are converted (format only, quality ignored).convert:es_convert::encodeinto the stick's staging, then reads bitrate/sample rate/bit depth (es_tags, as library conversion does) and the delay offset (delay_offset_ms).shift_analysis:rb_anlz::write::shift_timeline(SDK improve db latency #2) — grid and detail waveforms move like library conversion (Move rekordbox's detail waveforms with the grid when converting a track #15).profile:es-ffmpeg-v1:<format>-<quality>; bumpENCODER_VERSIONif output changes and sticks should be re-converted.EXPORTSTUDIO_FFMPEGfrom the app).convertingstage now reports as its ownconvertphase instead ofcopy.Behaviour verified end-to-end (
es-engine/tests/sync.rs, real es-usb + ffmpeg)One.mp3at 128 kbps; the library row still points atOne.wav; nothing is written beside the library file.copy 0, convert 0, keep 1; a second sync has no copy/convert phase.copy 1(the original goes back).The UI (format picker, plan counts, phase label) follows in the next PR; until then nothing sends
convert, so behaviour is unchanged.Note:
es-enginesync tests use thees-usbfound byexporter(); a staletarget/release/es-usb(schema 3) will fail them — setEXPORTSTUDIO_USB_EXPORTto the debug build or rebuild release.