Configuration settings for playing audio on a specific channel of a USB audio device connected to Raspberry Pi

Is there any sort of configuration file with plexamp for Raspberry Pi that gives some control over where plexamp sends its audio? I am currently casting to the Pi from app.plex.tv, and sound is playing from a USB sound card connected to the Pi. This card has 8 channels, and the problem is that plexamp is playing on all 8 channels.

I would like to be able to specify which channels it is playing on since I have other things (DLNA, shairport, spotify, etc.) playing on the other channels. Is there any sort of config file that does this? I’ve already found ā€œ.config/Plexamp/server.jsonā€ and ā€œplexamp/plexamp.serviceā€ - neither of these have what I’m looking for.

For reference, I am running Plexamp for RPi version 2, installed according to this:

Thanks in advance for your support!

@elan Do you have any insight on this? I can’t seem to find any answers anywhere else. I would greatly appreciate the help!

Supposedly, there is a config option you can place in the server.json file that will allow you to select which audio device and/or /channels are used by Plexamp:

},
"audio: {
ā€œdeviceā€: ā€œdevice name hereā€
}

I am assuming there are channel options to be used here also. That said, I can’t get it to work. I’ve tried every combination of options I can think of to select my USB DAC. I am assuming that

Thanks for the response! I just tried that and also couldn’t get it working. If the audio/device option for server.json really works (and we’re just missing something small), that would be great!

i’m sorry, it’s been way too long since i’ve used that version, so i can’t recall what specifically is the format of the device name. it’s possible if you look in the logs you’ll see it iterate them.

Thanks anyway @elan . Been thru the logs front, back, left and right. The various sound device options are iterated there, but it’s in no way clear how to name them in the config file to match.

Looking forward to the new version of Plexamp for the Pi!

We de-obfuscated the server.prod.js - here’s the start of AudioControllerLocal:

           const s = n(4),
                i = n(12),
                a = n(2),
                u = n(1),
                l = n("./server/settings.js"),
                c = n(26),
                d = n("./common/Device.js"),
                p = new c.AudioPlayer;
            t.default = class {
                constructor(e) {
                    this.currentTrackID = -1, this.app = e, this.lastSavedStateTime = new Date, this.lastStateReported = this.state = {
                        state: "stopped",
                        output: null,
                        id: ""
                    }, this.statusUpdatesEnabled = !0, this.lastStateChangeAt = new Date, this.state = {}, this.newState = {}
                }
                initialize() {
                    var e = this;
                    return o(function*() {
                        console.info("Audio: Ready.");
                        let t = process.env.PLUGIN_PATH;
                        t || (t = a.join(r, "..", "node_modules", "treble", "build", "Release"), s.existsSync(t) || (t = a.join(process.execPath, "..", "..", "..", "..", "..", "Resources", "app.asar.unpacked", "node_modules", "treble", "build", "Release"))), p.setPluginPath(t), "linux" === i.platform() && "arm" === i.arch() || p.setUdpPacketTarget("127.0.0.1", 36601), p.setLoggerCallback(function(e) {
                            const t = `[TREBLE] ${e.message}`;
                            0 === e.level ? console.error(t) : 1 === e.level ? console.warn(t) : console.debug(t)
                        }), yield p.setPlayerInfo({
                            username: (yield e.app.settings.get("user:name")) || "???",
                            clientIdentifier: (yield e.app.settings.get("user:identifier")) || "???",
                            platform: e.app.player.platform,
                            platformVersion: e.app.player.platformVersion,
                            product: e.app.player.product,
                            version: e.app.player.version,
                            device: e.app.player.device,
                            deviceName: (yield e.app.settings.get("player:name")) || e.app.player.deviceName
                        }), console.info("Audio: Set player info.");
                        const n = yield l.get("state");
                        n && e.setVolume(n.volume || 100)
                    })()
                }

It appears to use a plugin called ā€œTrebleā€ that is binary only. From what we can tell, inititalize() doesn’t pass any audio device information to Treble from the settings file loaded at ā€˜l = n("./server/settings.js")’ For reference, here is the de-obfuscated file: https://gist.github.com/micronova-jb/c7bc03ae046ce6ce988d3062555ed6e3

We also found the default settings configuration (server.json). Here’s what it looks like:

r.defaults({
            user: {
                token: null,
                id: null
            },
            audio: {
                controller: "127.0.0.1",
                normalize: !0,
                crossfade: !0
            },
            player: {
                name: "",
                identifier: null
            },
            logging: {
                level: "debug",
                colors: !0
            }
        })

No hints here on how to specify an audio output device.

Does Treble just guess which audio output it should use? Is there something that we’re missing?

1 Like

Is there a newer version for Pi?

Not yet. @elan has said that they are working on it, but it will ā€œbe ready when its readyā€ essentially. I don’t want to put words in his mouth, but I think that’s the gist

1 Like

Nice RE work :sweat_smile: The Pi version with TREBLE was an alpha, so it’s possible that I never got around to hooking up audio output selection and this only worked with the older non-TREBLE versions.

Essentially, yeah; we’re taking steps e.g. towards adding back controllability, which is a big need for a headless version.

2 Likes

Keeping the thread alive with some findings! It seems that choosing an audio device works with some modification of an older version of Plexamp for RPi! (we’re using version 1.0.5)
I’ll go through some of the steps we took below:

First, install version 1.0.5 the same way you would install the current version. Follow the same steps to get a server.json file as well.

Second, modify server.prod.js (found in /plexamp/server). This is the part that can be a little tricky. We figured this out by installing ā€œjs-beautifyā€ and running
$ js-beautify server.prod.js > test_server.prod.js
This gives you a de-obfuscated javascript file that is a little more readable compared to the original. It will likely take some time as it’s a large file. When you look at this file in an editor (we used Notepad++), the block to be modified is from line 25200 to 25205. It should look like this:

const d = s.join(o, c),
    m = l.get("audio:mpd_path"),
    p = {
        FFMPEG_EXTERNAL_LIBS: this.app.codecManager.getCodecPath(),
        DEVICE_NAME: l.get("audio:device") || ""
    };

MPD path and device will be specified later. From here, you can re-obfuscate the file, or just edit server.prod.js directly. If you want to save yourself some steps, open up server.prod.js, search for const d=s.join(o,c),m=l.get and modify the surrounding code until the line looks like this:
const d=s.join(o,c),m=l.get("audio:mpd_path"),p={FFMPEG_EXTERNAL_LIBS:this.app.codecManager.getCodecPath(),DEVICE_NAME:l.get("audio:device")||""};
You can see the similarities with ā€œaudio:mpd_pathā€ and ā€œaudio:deviceā€

If you don’t feel like doing this extra work, you can just take my version of server.prod.js from here: GitHub Gist of server.prod.js :slight_smile:

Finally, modify server.json and mpd.conf to suit your needs! On top of the typical information in server.json, my ā€œaudioā€ block looks like this:

  "audio": {
    "normalize": false,
    "crossfade": false,
    "mpd_path": "/home/pi/.config/Plexamp/mpd.conf"
  }

Where ā€œmpd_pathā€ is the path to your mpd.conf file. I just put it in the same directory as server.json. My mpd.conf file looks something like this:

audio_output {
  type "alsa"
  name "ch1"
  mixer_type "software"
  device "ch1"
}

samplerate_converter    "1"
bind_to_address         "127.0.0.1"
port                    "36600"
buffer_before_play      "15%"
audio_buffer_size       "16384"
log_file                "/home/pi/.config/Plexamp/mpd.log"

Where ā€œdeviceā€ is the audio device you want. In our case, it switches from ch0 through ch3. If you change these files, you’ll likely have to restart the Plexamp service to see them reflected. Alternatively, you could disable the service completely and just run the command in your terminal: $ /usr/bin/node /home/pi/plexamp/server/server.prod.js This is what we do for our application.
Hopefully this helps!

champion! I will try this out over the weekend!

1 Like

Thanks :slight_smile:

Let me know if it works out for you, or if you run into any bumps on the road!

Problem is that newer versions of Plexamp don’t use mpd anymore.

1 Like

Yeah, that’s why I’m using the 1.0.5. The hope is that a new ā€œversion 3ā€ will have something with audio device selection - I had a very specific use case, so it wasn’t surprising that it took a very specific answer!

Oh! That sounds wonderful!

I started ripping 1000s of classical music CDs (not found on streaming platforms) and they look so nice in plexamp, but I can’t listen to them on my stereo, the amp has USB-DAC but no optical in for a chromecast audio…

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.