home-assistant-libs / pychromecast

Library for Python 3 to communicate with the Google Chromecast.
MIT License
2.52k stars 378 forks source link

20-60s buffering for LIVE media streaming & huge delay #356

Open fornellas opened 4 years ago

fornellas commented 4 years ago

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:

We can then, see the delay:

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?

muammar commented 4 years ago

@fornellas thank you very much for your work here. I also look forward to knowing how to solve this issue.

emontnemery commented 4 years ago

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.

muammar commented 4 years ago

@emontnemery thanks for your reply. That is what I recently implemented and reduced the delay to ~6 seconds.

fornellas commented 4 years ago

@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?

pasikarkkainen commented 4 years ago

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..

emontnemery commented 4 years ago

@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.

clam-i-am commented 4 years ago

@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.

tjharman commented 4 years ago

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.

Eerovil commented 3 years ago

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.

emontnemery commented 3 years ago

@Eerovil This sounds great! Does the Bubble UPNP work better then the default media receiver with all streams?

Eerovil commented 3 years ago

@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)

ankostis commented 3 years ago

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?

emontnemery commented 3 years ago

@ankostis who is the question for? pychromecast is not doing anything fancier than sending an URL to the Chromecast.

Eerovil commented 3 years ago

@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.

ankostis commented 3 years ago

pychromecast is not doing anything fancier than sending an URL to the Chromecast.

Thank you, i didn't know that.

doiiido commented 5 months ago

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?