toomuchio / plex-nginx-reverseproxy

Configuration to serve Plex Media Center https://plex.tv using Nginx https://nginx.com
658 stars 95 forks source link

Google Chrome - Pause bug #21

Closed toomuchio closed 7 years ago

toomuchio commented 7 years ago

NET::ERR_INCOMPLETE_CHUNKED_ENCODING

What at first was related to issue https://bugs.chromium.org/p/chromium/issues/detail?id=622313 Appears to be a continuing issue, not present in Opera (Which is based on Chrome's engine :/) or Firefox...

Tried setting Accept-Ranges and Connection keep-alive and increasing keep-alive but to no avail.

savahu commented 7 years ago

When I add this to the nginx config:

#add accept-ranges header to support pausing/resuming
add_header Accept-Ranges bytes;

The response of the request to '/video/:/transcode/universal/start?' looks like this: schermafbeelding 2017-05-31 om 10 10 44

Does Cloudflare add accept-ranges:none ??

Update: Apparently Plex does. I just tried watching directly on 127.0.0.1:32400 on the server and it still sends accept-ranges:none.

toomuchio commented 7 years ago

But directly it doesn't have the pause issue? Do you see any missing headers or anything different. I didn't even think to try playing directly to see what the differences in the headers could be.

This could be the answer to fixing this issue!

savahu commented 7 years ago

When I play directly from 127.0.0.1:32400 it doesn't have the pause issue. What is interesting is after resuming no new request to '/video/:/transcode/universal/start?' is made.

The original request to '/video/:/transcode/universal/start?' stays active. schermafbeelding 2017-05-31 om 10 36 12

The headers are:

Request (direct) GET /video/:/transcode/universal/start?hasMDE=1&path=%2Flibrary%2Fmetadata%2F214818&mediaIndex=0&partIndex=0&protocol=http&fastSeek=1&directPlay=0&directStream=1&subtitleSize=100&audioBoost=100&location=lan&session=41tta30vol95975eavn6guzk&offset=391.15&subtitles=burn&copyts=1&Accept-Language=en&X-Plex-Session-Identifier=qvqafzkrtymg7vr86twjnwa1&X-Plex-Chunked=1&X-Plex-Product=Plex%20Web&X-Plex-Version=3.7.0&X-Plex-Client-Identifier=w98pmp0nhvbbcptwinowmfjj&X-Plex-Platform=Chrome&X-Plex-Platform-Version=61.0&X-Plex-Device=OSX&X-Plex-Device-Name=Plex%20Web%20%28Chrome%29&X-Plex-Device-Screen-Resolution=546x723%2C1440x900&X-Plex-Token=XXXXXXX HTTP/1.1 Host: 127.0.0.1:32400 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Accept-Encoding: identity;q=1, ;q=0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3115.0 Safari/537.36 Accept: /* Referer: http://127.0.0.1:32400/web/index.html Accept-Language: en-US,en;q=0.8,nl;q=0.6,de;q=0.4 Range: bytes=0-

Response (direct): HTTP/1.1 200 OK Transfer-Encoding: chunked Content-Type: video/x-matroska Accept-Ranges: none Connection: close X-Plex-Protocol: 1.0 Cache-Control: no-cache Date: Wed, 31 May 2017 08:18:09 GMT

I don't see meaningful differences except 'Connection: close'

toomuchio commented 7 years ago

Interesting, connection close header means that the server cannot support a keepalive. So perhaps if we turn off all our keepalives off and even push that header through, it may work.

Can probably do it on a per user-agent basis as well just for Chrome, since every other browser seems to be fine with it. I'll give it a shot later.

toomuchio commented 7 years ago

Ok that didn't fix it however...

If you turn on buffering with proxy_buffering on; The issue goes away, I figured it was due to chucked transfer encoding not working with buffering on so I tried just chunked_transfer_encoding off; And while the error isn't thrown in console any more, the playback still stops, so unfortunately... buffering must be enabled.

If you don't mind taking the performance hit turning buffering on seems to fix it, I'll a few days to confirm and update the config... Perhaps there's a smart way to detect chrome and only enable buffering on Chrome.

The trouble is so many browsers have Chrome in the user agent string, applying a generic if regex wont cut it...

toomuchio commented 7 years ago

Follow up you need chunked_transfer_encoding off; as well, so far no stops. I don't use Chrome so just depending on what people are telling me. With the default buffer sizes it doesn't seem so bad, performance wise either.

toomuchio commented 7 years ago

Just to follow up, none of the above 'fixes' worked, it may have made the time longer in which you can pause however which lead me to believe I had fixed it.

I've left a comment on the Chrome bug track, it still seems to be an issue with Chrome and not this configuration.

zmike808 commented 7 years ago

Setting send_timeout 100m; seems to have fixed this issue for me. Some google-fu led me to this post about nginx video streaming & chrome https://www.digitalocean.com/community/questions/setup-nginx-to-video-streaming

toomuchio commented 7 years ago

@zmike808 Nice! I'll apply it and confirm and push a fix thanks for this. Are you doing send_timeout 100m; in the server block or globally? Presumably should work in the server block, documentation seems to indicate so.

zmike808 commented 7 years ago

@toomuchio I put it in my server block, however I must admit I am not an nginx guru. I just happened to stumble upon that post on DO's forum after some googling for solutions regarding chrome, nginx, and video streaming.

toomuchio commented 7 years ago

Confirmed it works! Thank you so much for finding this closing this issue off finally!

gdob commented 5 years ago

I noticed the fix send_timeout 100m now works with Cloudflare, too. Tested from two different servers on Roku, Chrome and Chromecast. The stream continues as it should.