pychromecast
pychromecast copied to clipboard
20-60s buffering for LIVE media streaming & huge delay
I've been debugging https://github.com/muammar/mkchromecast/issues/292, and traced the issue down to pychromecast / my Chromecast Audio.
Using examples/media_example.py, I was able to repro the issue. Here's the setup:
- Start this Flask server (
FLASK_APP=pacast.py flask run --host=0.0.0.0).- It will spin
parec&ffmpegto stream captured audio.
- It will spin
- Use
examples/media_example.pyto connect the Chromecast to Flask.- Change play parameters to:
cast.media_controller.play_media(args.url, "audio/aac", stream_type="LIVE").
- Change play parameters to:
We can then, see the delay:
- If Pulseaudio is quiet.
- It gets stuck in BUFFERING for ~60s (~32k streamed), plays for ~1s, and back to BUFFERING.
- If Pulseaudio has output.
- It gets stuck in BUFFERING for ~20s (~512k streamed), then switches to PLAYING.
- Things play fine from this point on, but audio is 20s delayed.
Google documentation says that LIVE should work, but the described above behavior is the same with stream_type="BUFFERED".
If we try serving an MP3 from a URL for example, it starts playing within ~1s, as the Chromecast can fill its buffer pretty quick. I haven't tried, but I bet if we serve the MP3 file at 1kB/s, it'll buffer for the same 20s.
From all tests I did, data is being streamed from Flask to Chromecast in a reasonable amount of time, but Chromecast insists in buffer things (either 20s or 512k it seems) thus having a massive delay as a result.
Is there some Chromecast option we're missing to send for live streaming?
@fornellas thank you very much for your work here. I also look forward to knowing how to solve this issue.
Unfortunately, it seems LIVE is not working as expected for Chromecasts, as you have experienced the Chromecast device still buffers.
A workaround is to send a "play" command after a few seconds of buffering, as discussed here:
https://github.com/home-assistant/core/issues/16319#issuecomment-476351385
This works for some streams, but not all.
@emontnemery thanks for your reply. That is what I recently implemented and reduced the delay to ~6 seconds.
@emontnemery I'll give the "play" hack a try when I find some time, tkz for the tip.
Do you happen to know if this issue happens with devices other than Chromecast Audio?
I just did a few tests using Chrome and casting a tab which has some web audio player in it.. test result: hitting play/pause on the web audio player results in less than 1 second delay with the Chrome browser internal tab casting.
I tested with both Chromecast Ultra and Chromecast Audio devices. Similar less than 1 second delay/lag with both devices.
So yeah, definitely something wrong with the pychromecast LIVE mode..
@pasikarkkainen Right, but that is using the app "Chrome Audio Mirroring", not the builtin app "Default Media Receiver". The problem here is that "Default Media Receiver" buffers some live streams.
@fornellas I opened this issue up on the catt issues board before I saw this. (catt appears to leverage pychromecast.) A few comments that may or may not be helpful...
In that issue I noticed a low bitrate live stream would undergo this "buffering" treatment for about 5 minutes before playing, while decent bitrate ones (e.g. 128kbps) would start up within 5-10 seconds. While my issue link above only shows output at a point in time, I can say that I too have seen the BUFFERING->PLAYING->immediately back to BUFFERING (if I re-run the info command in catt quickly enough).
Regarding your question "does this happen with other devices besides the Audio?" - I've see it on the Mini, Chromecast, and a Nest Hub, too. Same behavior across all.
Lastly, quickly triggering "play" for the buffering live stream has mixed results - doesn't appear to work with any consistency on this end.
I agree, I have tried to work around this by triggering a "play" but it doesn't help. I can't figure out why some of my stations play straight away, and some take ages.
I've had success circumventing this problem by using another media controller app (BubbleUPNP).
The question remains, should we keep something like that as a completely separate app (callable in homeassistant via quick play), or perhaps add a global setting to pychromecast, where you could choose whatever "Media player app" you wish to use? I'll make a pull request with the quick_play feature for now.
EDIT: For some results: The stream I've tested with takes 20-25 seconds to start with the default player, but only 6 seconds with BubbleUPNP.
@Eerovil This sounds great! Does the Bubble UPNP work better then the default media receiver with all streams?
@emontnemery I couldn't say, since finding theses low-bitrate streams is pretty difficult. The stream used previously in the catt issue https://github.com/skorokithakis/catt/issues/264#issue-627857166 doesn't work anymore.
EDIT: It does work but there is rarely any audio. I'll try to see if I can get a measurement...
EDIT: Yup, something like 10 seconds for playback it seems. Not 100% sure though (I just restarted the stream when audio started coming)
Thank you for yor efforts.
Just to mention that ~6sec with BubbleUPNP while still improving things, it does not seem like dealing with the problem.
Have you considered switching to an actual MPEG-DASH implementation, as muammar/mkchromecast#292 seems to suggest?
@ankostis who is the question for? pychromecast is not doing anything fancier than sending an URL to the Chromecast.
@ankostis If there is a Chromecast app with a better implementation (and also implements the media controller namespace) then surely using that is a better idea. You can use any app.
pychromecast is not doing anything fancier than sending an URL to the Chromecast.
Thank you, i didn't know that.
Hi everyone! Everyone is pointing out at the default receiver app on chromecast, but I've created an (very basic available on the codelab https://www.gstatic.com/eureka/cast_codelabs/src/live_codelab_src.zip) Chromecast receiver app and the delay is still about the same. Do you guys have any notes or wish for me to test specific flags?