bootsie123 / F1-Web-Viewer

A simple grid-based web viewer for Formula 1
https://f1webviewer.netlify.app
ISC License
168 stars 24 forks source link

F1TV backend changes breaks video playback #35

Open NadimAsad opened 3 years ago

NadimAsad commented 3 years ago

Detailed in https://github.com/robvdpol/RaceControl/issues/210. Same issue also affects F1-Web-Viewer.

bootsie123 commented 3 years ago

Thanks for bringing this to my attention! I'll get on it!

destroyar commented 3 years ago

Thank you for posting this - today was the day I decided to spin this up locally, and thought I had missed something!

NadimAsad commented 3 years ago

F1TV looks to have reverted back the changes for RaceControl based user-agents. Information regarding this can be found at https://github.com/robvdpol/RaceControl/issues/210#issuecomment-907024985.

bootsie123 commented 2 years ago

With the recent change to requiring the playToken cookie on video playback, there is some good news and some bad news. The good news is that this can be implemented very easily for self hosted users or users using the electron application. However, the bad news is that the CORS proxy I'm using strips all cookies from requests.

Unfortunately, this means that the live website will no longer work. I'll try to see if there is some way I can revive it, but I'm afraid the only solution may be to host a CORS proxy myself. Which, unfortunately, I'm not able to do at this time.

If you guys have any ideas on this, feel free to let me know!

bootsie123 commented 2 years ago

QUICK UPDATE

I just pushed a small update to the master (development) branch which adds support for playToken cookie authentication. This should fix the issues reported in issue #55. However, this will only work for those of you self hosting the project or those running the Electron app. Unfortunately, these changes will not effect the live website.

Tomorrow, I'll do some thorough testing just to double check everything and then I'll deploy it to the production branch and release the update for Docker and the Electron app.

As far as the live website goes, I have no ETA on when that will be fixed. As I said earlier, the future is unfortunately undetermined as of right now

EDIT: I did a little bit of real world testing and it seems there are a few issues with my current implementation that I didn't see in my test environment. I'll be addressing those tomorrow

bootsie123 commented 2 years ago

Just released a fix for everything except for the live website. You should be seeing the updated version show up on Docker Hub and on the GitHub releases tab shortly

EDIT: Desktop application is now released for Windows, MacOS, and Linux. It can be downloaded here

EDIT EDIT: Had a few issues with the CI. I'll manually make a build and release it today. Sorry for the wait!

sbkg0002 commented 2 years ago

Latest build as docker image here: sbkg0002/f1-web-viewer:1.17.13

bootsie123 commented 2 years ago

Thanks for posting this in the meantime! CircleCI recently added a build limit which, unfortunately, is shorter than the multiarch build time. I thought I would be able to fix it fairly quickly, however, it's taking longer than expected.

Long story short, I'll do a manual build and release later today

bootsie123 commented 2 years ago

Update! I had some issues building the arm64 and armv7 images manually so I only pushed the regular amd64 image for now. I'll update this comment when I get it fixed and push it out

EDIT: I was able to push armv7 successfully. Just need to do arm64 now EDIT EDIT: and all images have been successfully pushed

iebb commented 2 years ago

Made a public version (which is basically a reverse proxy which changes the playToken cookie), and configured cloudflare to cache all ts/aac files, which might be able to reduce bandwidth usage. Unsure if the cache thing works with live though, might need some more page rules being added Test Link: https://live.sox.pm/

bootsie123 commented 2 years ago

Nice! Great idea to make use of CloudFlare for caching. I'd be curious to know how you're handling everything in the backend and how you're going about hosting it. I'd love to work with you on merging your changes and coming up with a sustainable solution for this

iebb commented 2 years ago

the reverse proxy is just a tiny go script in about 40 lines, and it's not designed to handle huge amount of traffic. a tiny bit of lagging can be observed, so it's only a test at its current form, and if it works well i may carry out some improvements :D

iebb commented 2 years ago
package main

import(
        "log"
        "strings"
        "net/url"
        "net/http"
        "net/http/httputil"
        "github.com/gorilla/mux"
)

func main() {
        handler := func(w http.ResponseWriter, r *http.Request) {
                vars := mux.Vars(r)
                remote, _ := url.Parse(vars["url"])
                r.URL.Scheme = remote.Scheme
                r.URL.Path = remote.Path
                r.Host = remote.Host
                remote.Path = ""
                proxy := httputil.NewSingleHostReverseProxy(remote)
                proxy.ModifyResponse = func(resp *http.Response) error {
                        if setCookie := resp.Header.Get("Set-Cookie"); setCookie != "" {
                                setCookie = strings.ReplaceAll(setCookie, "Path=/", "Path=/proxy/" + remote.String() + "/")
                                resp.Header.Set("Set-Cookie", setCookie)
                        }
                        return nil
                }
                proxy.ServeHTTP(w, r)
        }

        staticRemote, _ := url.Parse("https://f1vp.netlify.app/")
        staticProxy := httputil.NewSingleHostReverseProxy(staticRemote)
        staticHandler := func(w http.ResponseWriter, r *http.Request) {
                r.Host = staticRemote.Host
                staticProxy.ServeHTTP(w, r)
        }

        r := mux.NewRouter()
        r.HandleFunc("/proxy/{url:https?://.*}", handler)
        r.PathPrefix("/").HandlerFunc(staticHandler)
        r.SkipClean(true)

        http.Handle("/", r)
        http.ListenAndServe(":80", r)
}

Here's the code, not well-tested but it just works for me

bootsie123 commented 2 years ago

the reverse proxy is just a tiny go script in about 40 lines, and it's not designed to handle huge amount of traffic. a tiny bit of lagging can be observed, so it's only a test at its current form, and if it works well i may carry out some improvements :D

Ah, gotcha. I've been debating self hosting a public proxy for this since I have the infrastructure to do so, but I've been worried about bandwidth. Using Cloudflare as a CDN though should go a long way.

Thanks for posting your code by the way! I was curious to see how you went about it compared my solution. I'll probably end up creating a spin off microservice for this and then just host that. We'll see

iebb commented 2 years ago

the reverse proxy is just a tiny go script in about 40 lines, and it's not designed to handle huge amount of traffic. a tiny bit of lagging can be observed, so it's only a test at its current form, and if it works well i may carry out some improvements :D

Ah, gotcha. I've been debating self hosting a public proxy for this since I have the infrastructure to do so, but I've been worried about bandwidth. Using Cloudflare as a CDN though should go a long way.

Thanks for posting your code by the way! I was curious to see how you went about it compared my solution. I'll probably end up creating a spin off microservice for this and then just host that. We'll see

I also built a Python + Flask backend at deta.sh to do the reverse-proxy stuffs at https://tv.ieb.systems , which might be (more?) reliable than the previous one

EDIT seems deta.sh has a 5.5 MB payload size limit (aws lambda) which might be a problem for 1080p streams, I have hijacked the response to not include 1080p stream here

iebb commented 2 years ago

the flask reverse proxy: https://gist.github.com/iebb/c6fd779f206773e8b089790b4cf075a6

xAndrettix commented 2 years ago

Mine hasn't worked at all this season thus far, but up to now I haven't had any time to do anything about it. I've read most of the stuff above, but it is pretty much literally over my head as far as how to implement the fix. Whereas when I first tried to use this during preseason and it would allow me to log in (but when choosing cameras to use, i would see an 'X' (and it would say something below that at this point escapes me), as of today I can't even log in when trying to use it.

Is there any sort of 'how to' I can follow to fix mine? I know my subscription is working since I can log into F1TV and watch that way, but despite the improvements there, you all are still way ahead of the curve they set so I'd like to stay watching the races as I have the last year or so since I read and applied the app. So any help or suggestions would be appreciated.

Thanks in advance (for help/suggestions as well as making this available for the rest of us to use and enjoy).

ManCaveMedia commented 2 years ago

@xAndrettix For now the easiest way to get something working is by using iebb's Self Hosted version. Just download a release and run it. https://github.com/iebb/F1WebViewer-SelfHosted/releases