owntone-server icon indicating copy to clipboard operation
owntone-server copied to clipboard

Change speaker volume via cli

Open snizzleorg opened this issue 7 years ago • 20 comments

Im using mpd support of forked-daapd to control. Forked-daapd from Home-assistant. I would like to change the volume of a specific speaker but it seems that mpd does not support that. Anybody has figured out a way to change the volume of a specific output via the commanding or via curl or something similar?

snizzleorg avatar Aug 23 '16 07:08 snizzleorg

MPD in general does not support the notion of having different volumes for different speakers, therefore forked-daapd would not be able to either. If your use-case is that one device is louder than another you can change the volume "mapping" in the settings via the max_volume.

Lakritzator avatar Aug 23 '16 09:08 Lakritzator

@Lakritzator yeah that is what I found out as well. So the mpd interface doesn't help me here. What I need is a way to directly talk to forked-daapd to set the volumes of the outputs... Obviously mpd would be easy but thats a no-go. So I'm looking for a curl command line or something alike to directly tell forked-daapd to set a specific output level

snizzleorg avatar Aug 23 '16 20:08 snizzleorg

curl "http://HOSTNAME:3689/ctrl-int/1/setproperty?dmcp.volume=VOLUME&include-speaker-id=ID&session-id=SESSION"

where: VOLUME is 0-100 ID is the long speaker id (one way to find it: "sqlite3 songs3.db" and "select id,name from speakers;" - another way is to look in the log in debug mode after adjusting volume with Remote) SESSION look here and do as it says (also the login/logout part)

Note you can either use "include-speaker-id" or "speaker-id". The former should set an absolute volume, and the latter should set the volume relative to the master volume (I think...).

ejurgensen avatar Aug 23 '16 21:08 ejurgensen

cool thanks!

its a bit strange: if I use include-speaker-id how this behaves But I suppose I get the idea with trying around a little ... Any way to get the volume - read out the set volume I mean?

snizzleorg avatar Aug 24 '16 20:08 snizzleorg

Try "/ctrl-int/1/getspeakers?session-id=SESSION"

To parse the result you would need one of these (I think the first one, dmapprint, is probably the best): https://github.com/mattstevens/dmap-parser http://pydaap.readthedocs.io/en/latest/ http://dacp.jsharkey.org/decode.txt

ejurgensen avatar Aug 25 '16 18:08 ejurgensen

Thanks for the help. I will see if I can get this coded somehow...

All relatively complicated. Somehow compared to daap rest/api seem very nice and easy ;-)

snizzleorg avatar Aug 25 '16 18:08 snizzleorg

Someone started adding per output volume to mpd some time ago: http://mailman.blarg.de/pipermail/mpd-devel/2015-October/000445.html

If i understand the patch correctly, it adds a new command "outputvolume" to the mpd protocol to set the volume of an output. The per output volume is read from the client with the existing "outputs" command, which returns an additional line "outputvolume: xxx".

I can look into adding this to forked-daapd. As it is not part of mpd, the chances that clients will implement it are probably non existent. But maybe it would make it easier to write scripts controlling forked-daapd.

chme avatar Aug 27 '16 04:08 chme

interesting. I would only need a command line client and I suppose this is the only really important client since there is very nice iOS and android clients that talk directly to forked-daapd. So I suppose the mpd interface is mostly interesting for people doing some kind of home-automation with it.

snizzleorg avatar Aug 29 '16 13:08 snizzleorg

@snizzleorg i achieved changing volume of an individual speaker by adding support to the python-mpd2 library: https://github.com/chme/python-mpd2/tree/outputvolume

My python script "outputvolume.py" looks like this (it takes to parameters, first the speaker id and second the new volume 0 - 100):

import sys
from mpd import MPDClient

client = MPDClient()
client.connect('localhost', 6600)
client.outputvolume(int(sys.argv[1]), int(sys.argv[2]))
client.disconnect()

Getting the volume from each speaker is possible with the following script:

from mpd import MPDClient

client = MPDClient()
client.connect('localhost', 6600)

for output in client.outputs():
    for key, val in output.items():
        print key + ': ' + val

client.disconnect()

The script prints to stdout:

outputid: 0
outputname: Computer
outputvolume: 50
outputenabled: 0

chme avatar Oct 31 '16 18:10 chme

I tried forked-daapd for the first time today, trying to stream to two RPis with shairport-sync installed... everything seemed to work except no sound was coming through either speaker attached to RPis.

I checked the logs of shairport-sync and discovered that forked-daapd was setting the volume to minimum/zero (-144db) on both.

I then used mpc volume 100 on the RaspberryPi that runs both: forked-daapd and shairport-sync and achieved the desired output (I mean any output) on the speaker connected to this RPi (still using AirPlay). It's strange that volume went to normal only on one of the AirPlay targets, I think forked-daapd isn't treating this one output specially although it's local on this device.

I see that I cannot use any mpd clients to set volume to 100% for all current and future outputs in forked-daapd. So how to go about that at all?

And second question of course is why was the default volume at 0% and nothing mentioned about this in obvious places in documentation... If I had't trusted that this is a good project and it has to work somehow, I'd given up because of a small technical glitch... I had no idea the problem was the volume, I just saw there is no sound although my Remote app on the iPhone appeared to be playing to one or both AirPlay targets...

davidhq avatar Feb 23 '17 15:02 davidhq

Out of the box, the default master volume is actually 50%. When the master volume is changed it should apply to all devices, also future ones. However, volume handling gets complicated by the fact that forked-daapd also supports per-speaker relative volumes. This is supported by Remote, but not by mpc.

What you are seeing is some kind of bug, but at first attempt I was not able to reproduce it. If you have a sure-fire recipe, please let me know. Otherwise I will make a few more tests to see if I can reproduce.

ejurgensen avatar Feb 23 '17 21:02 ejurgensen

Is the Master volume set by mpc volume [num]? Because this for sure wasn't at 50 after I set everything up... and also still on one speaker it's set to absolute zero and I can't get it up with Remote or otherwise.

Not sure how to help you reproduce, I just compiled it myself with default flags from the manual plus --enable-itunes.

Please let me know if I should provide you with more info for debugging and clarify above.

On 23 Feb 2017, at 22:23, ejurgensen [email protected] wrote:

Out of the box, the default master volume is actually 50%. When the master volume is changed it should apply to all devices, also future ones. However, volume handling gets complicated by the fact that forked-daapd also supports per-speaker relative volumes. This is supported by Remote, but not by mpc.

What you are seeing is some kind of bug, but at first attempt I was not able to reproduce it. If you have a sure-fire recipe, please let me know. Otherwise I will make a few more tests to see if I can reproduce.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

davidhq avatar Feb 24 '17 05:02 davidhq

Is the Master volume set by `mpc volume [num]

Yes

also still on one speaker it's set to absolute zero and I can't get it up with Remote or otherwise

In Remote > Speakers > Multiple you should have a volume slider for each speaker. If changing it there doesn't increase volume then there is an entirely different problem. The reason you cannot do it with mpc is that you probably have speaker A at volume X, and B at 0. When you increase the master volume to 100, then these are scaled relatively, so A goes from X -> 100 and B remains at 0.

It sounds like you got into a situation where both A and B were 0, then you started playback and A got autoselected, and then you increased the volume, which would then set A to X, while B remained at 0. I've tested some more, and I still cannot reproduce the initial state of A and B being 0. Did you upgrade from an older version of forked-daapd or something like that? That might explain it.

If you want to help debugging, then do the following:

  1. Stop forked-daapd
  2. Run "sqlite3 /var/cache/forked-daapd/songs3.db"
  3. Run "delete from speakers;" and then ".quit" (this resets the speaker states)
  4. Start forked-daapd
  5. Can you now reproduce the problem? If so, what are your exact actions?

ejurgensen avatar Feb 24 '17 16:02 ejurgensen

Thank you again for this!

I solved the current problem when second speaker had volume at zero, indeed under Remote / Speakers / Multiple the slider was at far left.

I somehow missed that and in my opinion it now seems quite possible that my initial problem when nothing was playing on either AirPlay target was because of similar issues, although it seems strange but also the most plausible since I cannot reproduce now. I thought maybe both AirPlay volumes were at zero and I was moving the main volume but if I do this now, both speakers volumes move with the main one in the Remote app UI.

Anyway, I purged the speakers table as you suggested just to see what is the default volume through mpc volume and it’s the same as when I tried first, namely volume: n/a. When I upped the volume through Remote, this changed to some percentage, so I’m happy to find out it is not neccessary to use mpc volume [n] to make it work when setting everything up.

I don’t have time now to try another fresh setup on another RPi but I will next week. I will let you know if all this confusion was purely at my side.

Thank you for help again and sorry for wasted time. For me it was nice to check the logs and also find out about songs3.db, so it was worth it.

I do have another short question though: is it possible not to announce the local alsa target on the network? I now have three things in Remote app: both AirPlay targets and local one which is the same as one of the AirPlay ones. Thank you !

On Fri, Feb 24, 2017 at 5:11 PM, ejurgensen [email protected] wrote:

Is the Master volume set by `mpc volume [num]

Yes

also still on one speaker it's set to absolute zero and I can't get it up with Remote or otherwise

In Remote > Speakers > Multiple you should have a volume slider for each speaker. If changing it there doesn't increase volume then there is an entirely different problem. The reason you cannot do it with mpc is that you probably have speaker A at volume X, and B at 0. When you increase the master volume to 100, then these are scaled relatively, so A goes from X -> 100 and B remains at 0.

It sounds like you got into a situation where both A and B were 0, then you started playback and A got autoselected, and then you increased the volume, which would then set A to X, while B remained at 0. I've tested some more, and I still cannot reproduce the initial state of A and B being 0. Did you upgrade from an older version of forked-daapd or something like that? That might explain it.

If you want to help debugging, then do the following:

  1. Stop forked-daapd
  2. Run "sqlite3 /var/cache/forked-daapd/songs3.db"
  3. Run "delete from speakers;" and then ".quit" (this resets the speaker states)
  4. Start forked-daapd
  5. Can you now reproduce the problem? If so, what are your exact actions?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ejurgensen/forked-daapd/issues/283#issuecomment-282331157, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAPO-zKcTqM1v4-TbrutQf08E6ZR2HUks5rfwE8gaJpZM4Jqo4b .

davidhq avatar Feb 24 '17 19:02 davidhq

I don’t have time now to try another fresh setup on another RPi

You don't need to do this for my sake. The "delete from speakers" will truly reset all forked-daapd's speaker settings, so for debugging purposes there is nothing gained by an entirely fresh install.

is it possible not to announce the local alsa target on the network?

Yes, if you build using the "--without-alsa" configure option then it shouldn't be there.

ejurgensen avatar Feb 24 '17 23:02 ejurgensen

@chme your mpd2 lib scripts work nicely - any idea if the changes you made to the library will get into the pip version?

snizzleorg avatar Apr 16 '17 13:04 snizzleorg

@snizzleorg I have created a pull request for the changes https://github.com/Mic92/python-mpd2/pull/87

The change in python-mpd2 is only necessary to change the volume, reading the volume is possible with the stock python-mpd2 version.

chme avatar Apr 22 '17 05:04 chme

@chme Cool! lets hope that it gets incorporated. Anyways I'm very happy with the whole situation now as it allows me to change the volume of the individual airplay speakers nicely from home-assistant.

snizzleorg avatar Apr 22 '17 07:04 snizzleorg

@chme - thanks for this support. Things are working well for me except one thing. Once an output is disabled it seems to ignore further request to adjust the volume. Am I missing some command that would enable the output first? Thanks.

outputenabled: 0

EDIT - Turns out all I needed to do is call client.enableoutput(id) Thanks all for this implementation!

kkfh avatar Jan 27 '18 19:01 kkfh

I wanted to set the volume from the command line and thanks to the comments here managed to knit together:

Torxgewinde avatar May 25 '18 15:05 Torxgewinde