Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ability to stream output of a linux desktop to Sonos #60

Closed
lsmith77 opened this issue Nov 11, 2018 · 21 comments
Closed

ability to stream output of a linux desktop to Sonos #60

lsmith77 opened this issue Nov 11, 2018 · 21 comments

Comments

@lsmith77
Copy link

I would like to stream the audio on my linux laptop to Sonos when I am watching a movie in place of the laptops speakers. is this within the scope of this app?

@janbar
Copy link
Owner

janbar commented Nov 11, 2018

The scope of this app is to control your Sonos devices. It cannot stream or share local resource to any devices. With it you could control the Sonos device to play an audio signal connected to an audio input (analog/coax/fiber).

@lsmith77
Copy link
Author

ok. I guess what would be within the scope is being able to set a stream URL?

at any rate, I managed to achieve more or less what I wanted using mkchromecast + soco .. however the delay was ~8.6s while watching a video in VLC which makes this somewhat unpractical, at least for that purpose.

@janbar
Copy link
Owner

janbar commented Nov 12, 2018

Yes you can set a stream to play, but sure it won't be sync with an other renderer.
In my opinion the only way is to connect the audio input.

@sandsmark
Copy link
Contributor

I thought about opening a PR adding a simple pulseaudio sink that is streamed to the sonos, but as you already noticed the lag is quite considerable, and the only way (that I can think of) to really get around it is to use the mic to determine the latency. Which sounds fun, but a bit out of scope of noson, I guess.

@janbar
Copy link
Owner

janbar commented Jan 19, 2019

Yep for instance it is out of the scope for the app because I haven't make code to stream to the Sonos. It could be fun to try that. Let me know if you have any idea to do it and some time to make a try. I guess Sonos uses the standard api to read stream from an upnp media server. And maybe it will need to use wireshark to know how Sonos works for that. The official desktop app (on OSX) doesn't provide this feature, but as I remember the android app do it. So running it in an android VM could help.

@janbar
Copy link
Owner

janbar commented Jan 20, 2019

I've done some checking and the only way to stream local audio files is by using a streamer as icecast. Seems Sonos allows only mp3 or aac streams. I fails to play any stream ogg or flac. So the feature should require to embed a "mini" streamer and a mp3 encoder to support audio formats like ogg, flac or wav. That isn't impossible... libmp3lame is gpl and coding a simple http streamer isn't so complex.

@sandsmark
Copy link
Contributor

Found this: https://github.com/masmu/pulseaudio-dlna

Very hackish, though, launching ffmpeg by itself, and the pulseaudio integration is way too complex.

And yeah, a very simple HTTP-ish server implementation to just hand out transcoded (if necessary) audio to any clients that connect, and point the Sonos at the local IP and right port. To stream any audio (i. e. from pulseaudio) and not just local files it's basically 10 lines of code if we use the pa_simple API.

It's probably simpler to just use ffmpeg, though, instead of using libmp3lame and libflac/libvorbis/etc. But then again; the ffmpeg API is anything but stable and there aren't that many sound formats people use for music (and the APIs for libmp3lame, libvorbis, libflac, etc. are easier to handle than ffmpeg ime).

@sandsmark
Copy link
Contributor

oh, and doing this is what I meant was out of scope: https://github.com/alopatindev/sync-audio-tracks

needs to take into account the delay of the transcoding as well, though.

@janbar
Copy link
Owner

janbar commented Feb 3, 2019

I pushed few commits (in branch streaming) to enable the request broker for others request than the upnp notifies. So now we can handle any GET/HEAD request from remote, do some work and reply to send a chunked stream. Also now I able to stream a flac file to my sonos. I tested it with noson-cli, where I transfer a flac stream to any remote requesting at http://host:1400/music/track.flac. So no need any more to use a losswith encoder. I had already designed a FLAC encoder wrapped within a QIODevice. Finally reading your previous comments I searched an easy way to read the stream from pulse and I found that: https://www.freedesktop.org/software/pulseaudio/doxygen/parec-simple_8c-example.html . Really simple and it should do the job.

@janbar
Copy link
Owner

janbar commented Feb 3, 2019

yep, reading the pulse stream we cannot read ahead the audio. So imo to resolve any sync issue the user should setup the delay for the video instead.

@janbar
Copy link
Owner

janbar commented Feb 7, 2019

Some news,
Trying to stream the monitor source from the pulse server works pretty well here. I read the LPCM bytes flow to push it into a FLAC encoder and finally send chunked data in the http response . But the latency is near 4 ~ 5 sec !!!

@sandsmark
Copy link
Contributor

awesome stuff!

but yeah, the latency is bad. in theory it is possible to automatically calculate the latency and tell whatever is playing about it, but I couldn't find that in the pulseaudio api (only how to ask for the latency).

but for just playing music from e. g. youtube in the background this approach works fine.

@janbar
Copy link
Owner

janbar commented Feb 11, 2019

@sandsmark, also the sonos device takes some time for buffering. Often around 1 second. But yes this works great to play youtube or any other music app. Playing youtube it could stop after the end of a show if the blank period is longer than 5 seconds. The sonos seems to trigger the stop when frame data are "zero" for some time. It is tricky to resolve that, the only way imo is to update pcm data with inaudible sound during the blank period.
For a first feature release it could be okay. For instance the feature will be available for Linux or BSD desktop with a pulseserver. Later when I will have more free time I will try to make it working on osx and android using the qt audiirecorder.
The branch streaming should work if you want to test it with the cli as below:

  • install flac++-dev, flac-dev, pulse-simple-dev, pulse-dev.
  • compile the software from branch streaming.
  • launch a youtube playback or play music with an app.
  • start the cli: build/cli/noson-cli
  • type: connect YourZoneName
  • type: playpulse

@janbar
Copy link
Owner

janbar commented Feb 13, 2019

This feature will be merged within the next release (3.8.0). Not too much work to finalze the required stuff. I will add an other request broker to share images and finally providing the pulseaudio logo and the favicon. About osx and android the feature has been killed. For those platforms we cannot monitor the sound output because firstly a "copyright" issue, and secondly for security issue. Only the streaming of stored files could be available.

@janbar
Copy link
Owner

janbar commented Feb 14, 2019

The feature is merged into master

@janbar janbar closed this as completed Feb 14, 2019
@janbar
Copy link
Owner

janbar commented Feb 15, 2019

It is ready to use with the release 3.10.4. I fixed the blank issue by designing a blank killer that injects an inaudible sound: one wave 20khz with a level of 0.0007 for each blanked millisecond. Under the hood Noson create a dedicated PA sink with the name 'noson'. Then it read the stream data from the associated PA source monitor 'noson.monitor'. Once you stop to stream or you close the app, the sink is removed. In the app to pulse your stream you have to open the sound parameters and then clic "PulseAudio". Enjoy with youtube...

@lsmith77
Copy link
Author

thank you!

@k-s-dean
Copy link

@janbar
I just wanna say thank you. Seriously one of my pet hates about sonos was the inability to stream things to this piece of s***, especially from youtube. made my day :) 👍

@expl0ratory
Copy link

Just found this after railing against youtube music forever. Thank you!

@javorekm
Copy link

Maybe I did not understand this super cool feature well. I just did

./noson-latest-ubuntu-bionic-x86_64.AppImage --cli --deviceurl=http://192.168.1.158:1400
Noson CLI using libnoson 2.10.0, Copyright (C) 2018 Jean-Luc Barriere
Connecting to http://192.168.1.158:1400... Succeeded
Found player 'Living Room' with UUID 'RINCON_XXXXXXXXXXXXX'
Found zone 'Living Room' with coordinator 'Living Room'
>>> connect Living Room
Connected to zone Living Room
Living Room >>> playpulse
Succeeded
Living Room >>> 

and then I expected I will see a new pulseaudio sink in my desktop linux system which I can use to play through. But I cannot see any new sink (noson or something like this) in pavucontrol or anywhere else. I was looking for some more info for command "playpulse" but I did not find any.

Noson app: 5.4.0 (appimage)

Thanks a lot for some info how to use it.

@javorekm
Copy link

Mea culpa!
I opened the android app and there was a stream to my computer - unable to play as firewall was active. When I changed firewall settings and play stream in app, noson sink appeared and I can play through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants