gonic icon indicating copy to clipboard operation
gonic copied to clipboard

Allow custom transcoding commands and pipelines

Open jpsutton opened this issue 3 years ago • 15 comments

I'd love to use an application like gonic to replace Airsonic. But the big thing holding me back is the lack of support for arbitrary formats. In the case of airsonic, it allows the user to define arbitrary commands in 2 stages to support any format. So the step 1 command might decode a given file to raw PCM or WAV, and then the step 2 command might re-encode that to a commonly-supported format like MP3, Vorbis, or Opus.

I've got a fairly wide range of files from (for example) video game rips; formats include gsf, smf, spc, vgm, gbs, and plain old midi. I wouldn't expect any application to build in support for each of these formats, but providing the user the ability to extend support in the same way that Airsonic does makes sense.

jpsutton avatar Oct 04 '22 19:10 jpsutton

yep this would be cool. we have talked about it before and shouldn't be too hard since we already store the commands as simple strings

https://github.com/sentriz/gonic/blob/master/transcode/transcode.go#L49

it would just be a matter of creating a UI

sentriz avatar Oct 08 '22 14:10 sentriz

Does gonic always transcode? There's transcoding device profiles in settings but it's not clear to me if it's always applied or it can be disabled. I'd like to have original playback only.

remus-selea avatar Apr 08 '23 20:04 remus-selea

@remus-selea if you haven't added any rules to the transcode section of the UI then it will never transcode 👍

sentriz avatar Apr 08 '23 20:04 sentriz

As a workaround in the meantime, you should be able to run it with a custom $PATH that points to an ffmpeg which is actually a shell script wrapper, which can then inspect the filetype and make decisions about what transcoder to invoke.

This also lets you implement behaviours like "don't transcode mp3s at all, use openmpt for tracker files and use ffmpeg for everything else" -- I believe the current behaviour is, if a transcode rule for a client is enabled, all traffic to that client will be transcoded even if this results in (e.g.) an mp3-to-mp3 transcode.

ToxicFrog avatar Sep 23 '23 21:09 ToxicFrog

That idea is just crazy enough to work!

jpsutton avatar Sep 23 '23 21:09 jpsutton

I've been busy with other stuff lately, but once I actually find the time to test this out I'll report back on how well it worked (and post code).

ToxicFrog avatar Sep 23 '23 21:09 ToxicFrog

I've got a few minutes, so I'm going to try prototyping it out with one of my more obscure VGM formats.

jpsutton avatar Sep 23 '23 21:09 jpsutton

That won't work without additional changes to Gonic itself, since at the moment it won't even index those files; based on discussion on IRC, it only indexes files that pass both of these checks:

so that basically rules out all VGM and tracker formats, along with MIDI, a bunch of more obscure PCM-type formats like MusePack, and anything it actually supports but which has a nonstandard extension on disk.

I am actually in the process of writing an issue about this right now, I meant to a while ago and got distracted. I think a good approach to move towards would be use taglib for the "fast path" of common audio formats, but shell out to ffprobe for things that doesn't recognize.

So to test this, you'll need to use the above filetypes.

ToxicFrog avatar Sep 23 '23 22:09 ToxicFrog

I believe the current behaviour is, if a transcode rule for a client is enabled, all traffic to that client will be transcoded even if this results in (e.g.) an mp3-to-mp3 transcode

I think hopefully that shouldn't happen. gonic will skip a transcoded if

  • the source bitrate is less than the requested bitrate
  • the client requests a maxBitrate higher than the source nitrate
  • the client requests to not transcode

sentriz avatar Sep 24 '23 00:09 sentriz

I am actually in the process of writing an issue about this right now, I meant to a while ago and got distracted. I think a good approach to move towards would be use taglib for the "fast path" of common audio formats, but shell out to ffprobe for things that doesn't recognize.

I did some thinking tonight about the best way to work through this for formats that don't have support in taglib. Shelling out to ffprobe probably won't get you much, imo (at least not for the more obscure formats I'm dealing with). I'm wondering if having a user-provided fallback might be useful. Other "stream my library" software support things like this (e.g., Plex and Jellyfin, for instance, support NFO files for user-provided metadata). @sentriz if I implemented this kind of support, could this be an alternative to specific support for metadata in taglib?

Edit: Sorry, didn't mean to close the issue.

jpsutton avatar Sep 25 '23 23:09 jpsutton

I did some thinking tonight about the best way to work through this for formats that don't have support in taglib. Shelling out to ffprobe probably won't get you much, imo (at least not for the more obscure formats I'm dealing with).

For me what I'm mostly missing is support for tracker formats (xm, it, umx, etc) and VGM/VGZ, which ffmpeg supports via libopenmpt and libgme respectively. Given the ease of use there I don't think that sidecar metadata is a good replacement for ffprobe, but I could see it being useful as an additional metadata source. And that, I think, gives us a metadata priority that looks something like:

  1. User-provided metadata via some NFO format
  2. whatever taglib returns, if it supports the file format
  3. whatever an external prober like ffprobe returns

ToxicFrog avatar Sep 26 '23 19:09 ToxicFrog

In preparation for potentially parsing NFO data, I added album and artist support in this project:

https://github.com/bernmic/nforeader

jpsutton avatar Sep 27 '23 13:09 jpsutton

Possibly also relevant to that idea:

  • #371 lyrics in sidecar files
  • #324 m-TAGS metadata sidecar format, not sure if this is preferable to whatever jellyfin/kodi use but I do think it would be better than defining an ad hoc format

ToxicFrog avatar Sep 27 '23 14:09 ToxicFrog

Extending gonic so that it could stream tracker music is an awesome idea!

duckfromdiscord avatar Sep 28 '23 23:09 duckfromdiscord

hey, while i don't think this is the relevant issue to discuss this futher on, i just refactored the tag situation to make it easier to add more "tag backends" later. for example to support ffprobe, nfo, whatever - someone would just need to add a new package to scanner/tags/, implement a type that implements the tag Reader interface, add that type to the ChainReader in main.go

sentriz avatar Oct 02 '23 19:10 sentriz