beets icon indicating copy to clipboard operation
beets copied to clipboard

convert: Multiple allowed output formats

Open intelfx opened this issue 8 years ago • 14 comments

Usecase

I have a single "master" library, which is a bit heterogeneous: most of media is lossless, but a substantial part of it is in different lossy formats. Next, I have two mobile devices with different sets of supported media codecs and different available space.

Current workflow

The music upload workflow is hence following:

  • determine what needs to be uploaded
  • determine the source file format(s)
  • check if each of these is supported
  • issue multiple convert commands for the same source and destination with different source type filters and different output formats

Wanted workflow

I would like to be able to specify a set of conversion rules in some way and let beets apply them in order over the same source and destination in one run. For example, here's how the rules would look for an iPhone:

  1. lossless ⇒ aac_256
  2. lossy(mp3, aac) ⇒ copy
  3. lossy(bitrate > 128kbps) ⇒ aac_128 (this is unfortunate, but well, having poor-quality music is still better than not having it)
  4. others ⇒ fail (or aac_he_64)

Another way around, one could specify the supported file format list (e. g. aac, mp3) and a behavior mode ("prefer lossless" / "prefer lossy") and have beets convert figure out the codec and the bitrate for each file.

Multiple profiles

On top of this, it would be very nice to have a notion of a "conversion profile" (== rule set) to be able to say beets convert --profile iphone or beets convert --profile laptop or so on.

intelfx avatar Feb 03 '16 15:02 intelfx

Interesting situation!

Did you know you can get most of the way there already by using the max_bitrate config option? Using that, you'd get:

  • Lossless => your configured lossy format
  • Lossy under a given limit => copy
  • Lossy over the limit => transcode

Maybe there's a specific tweak we can make to this existing setup to match what you're hoping for?

sampsyo avatar Feb 03 '16 17:02 sampsyo

@sampsyo: It's not exactly about the bitrates. It's mostly about source codecs. The bitrates were just an example of additional (non-source format) filter. The primary feature request is the ability to make decisions based on source format, either in form of an explicit rule set or in form of an allowed codec list.

intelfx avatar Feb 03 '16 22:02 intelfx

Aha. So to be clear, you'd like more intricate policies than just "if lossless then X; if lossy then Y"? Are there particular circumstances where you need finer-grained decisions than that---for example, one for AAC and one for MP3?

sampsyo avatar Feb 03 '16 22:02 sampsyo

@sampsyo: Sure. An iPod/iPhone. In simplest case:

  1. lossless ⇒ AAC (or lossless ⇒ ALAC, depending on user's space/quality tradeoff preferences)
  2. lossy(AAC, MP3) ⇒ copy
  3. lossy(other) ⇒ warn and AAC

On top of this, it probably would be good if not just formats could be considered, but also e. g. bitrates (so one could have different fallback rules for high-bitrate lossy and low-bitrate lossy). But in my usecase this is not needed.

intelfx avatar Feb 03 '16 22:02 intelfx

Ah, that's cool. In that sense, it's actually pretty close to what you get by specifying just "MP3" or just "AAC" as the output format. That is, convert will transcode everything but MP3 to MP3, but just copy MP3s (or the same for AACs).

So, here's another abstraction: Currently, the convert config lets you specify the format you want to convert to. What if you instead specified a set of formats to convert to? Then, anything that matched those formats would be copied; anything else would be transcoded---say, with the first format in the list.

That would match the iPod use case without needing a fully general specification of what to do with any given file based on its attributes.

sampsyo avatar Feb 03 '16 22:02 sampsyo

I also suppose the never_convert_lossy_files option is also pretty similar. It gets you the behavior you listed above, except that "lossy(other)" just gets copied instead of "warn and AAC".

sampsyo avatar Feb 03 '16 22:02 sampsyo

Yes, that was exactly my second proposal. The "policy"/"behavior mode" I spoke about in the opening post is actually redundant.

except that "lossy(other)" just gets copied instead of "warn and AAC".

I don't want unreadable files on the device :)

intelfx avatar Feb 03 '16 22:02 intelfx

Got it! You did say "an allowed codec list"; sorry it took me a while to catch up.

Thanks for working through it. I can totally see the utility of a feature like this.

sampsyo avatar Feb 03 '16 22:02 sampsyo

Great. Thank you for considering this feature.

intelfx avatar Feb 03 '16 22:02 intelfx

I'm quite keen to see this feature, too - again, I have a media player (a VW car audio system) that likes some formats better than others, and I'd like to do the bare minimum of transcoding.

I might have a go at implementing it over the next few weeks, free time permitting. I'm totally new to Beets development (and Beets in general), so it might be a bit of a mess, but if there's interest, I'd gladly submit a PR.

rhalkyard avatar Jun 17 '16 02:06 rhalkyard

Awesome! Please do let us know if you need help navigating the code.

sampsyo avatar Jun 17 '16 07:06 sampsyo

There is a third-party plugin, beets-alternatives built on top of the convert plugin, that probably does (most of) this. Its latest version is incompatible with current beets as it suffers from the same issue as in #1467. This one should be an easy fix, I don't know whether there could be more incompatibilities in recent beets. As I'm moving my library to beets, I'll need this feature, too, but I'll not have much time to spend on it before july/august.

wisp3rwind avatar Jun 17 '16 08:06 wisp3rwind

And this beets-alternatives seems to (partially) solve this case as well... I'd still wish for more granular rules than just "supported formats", but ok.

intelfx avatar Oct 06 '16 12:10 intelfx

(Sorry for reviving this very old thread) I'm hoping that there could be a way for defining rules such as "for FLAC files above 16-bit or above 44.1khz, convert it to 16-44 with ffmpeg". ChatGPT suggested setting max_bitrate: 1411 which mostly work but is way too hacky.

hexacera avatar Dec 24 '23 16:12 hexacera