A Rust serverless function to retrieve and relay a playlist for Twitch livestreams/VODs.

Overview

City17

A Rust serverless function to retrieve and relay a playlist for Twitch livestreams/VODs.

By running this in specific countries and using a browser extension to redirect certain network requests to this function, Twitch will not display any ads.

I don't provide any pre-built version of this, you have to set it up yourself.

My rough estimate is that a few hundred to a few thousand users can be supported while staying inside the free tier's limits, but I wouldn't recommend publicizing your function unless you actually understand how the pricing works. If you're the only user you won't need to pay anything. (Supposedly there's no free tier on outbound bandwidth, but my bill in May was 0.000000 USD.)

You can probably run this as an actual server, but I haven't tested that because that costs money.

(I don't remember why I named this City17.)

Requirements

The function needs to be run in a country where Twitch doesn't serve ads. Countries currently known: Russia, China.

I don't know of any serverless provider that operates in Russia, and supports Rust, and allows use by people outside Russia. China has at least two providers that should work fine, one of which I've personally tested. (Some amount of GFW evasion takes place, since Twitch is blocked in China, but at least we can be pretty sure that Twitch won't start running ads there...?)

I've only successfully run this on Aliyun (Alibaba Cloud) from Chinese regions, and the code will require modifications to run on a different provider. (Except Azure if I managed to avoid breaking it after my initial tests there; there's a feature flag.)

Tencent Cloud should also work with some minor modifications, but I've been unable to complete signup to test it.

Azure might work if any of its locations are non-ad countries. Twitch considers the UAE to be located inside the USA, so their Dubai location (UAE North) doesn't work. Azure doesn't allow use of their Chinese regions unless you're a business with a presence in China.

Building

Run build.sh. Cannot be truly built in Windows due to ring, but cargo check and cargo build work for checking the code. Ubuntu 20.04 via WSL works fine and is what I use.

Once city17.zip is built, see setup instructions below.

Requires:

  • Rust installed via rustup
  • The x86_64-unknown-linux-musl target for Rust (rustup target add x86_64-unknown-linux-musl)
  • 7za (p7zip-full on Debian and Ubuntu, can modify script to use normal zip command)
  • musl-gcc (musl-tools)
  • Probably build-essential

Aliyun setup instructions

  1. Sign up, enable function compute, etc. (I'm not creating a new account just to write down all the steps)
  2. Set the region to China (Shanghai). As far as I know this is the region closest to Tokyo, which is where one of Twitch's servers is.
  3. In the Function Compute menu, enter Services and Functions and create a service named a. (Or whatever you want, but you'll need to modify the code.)
  4. Create a function:
    • HTTP
    • Named prx
    • Custom Runtime
    • Select the ZIP file city17.zip
    • Give it 128MB of RAM and a 15-second timeout.

For future updates of the function, use the Code tab's "Upload Zip File". (Or get fcli, set it up, and run update.sh after build.sh)

Under the Code tab, use the URL listed there to set up the browser extension.

It looks like https://################.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/a/prx/; you will need to add invoke to the end.

Issues

  • If the shell scripts fail due to having Windows line endings, run
dos2unix build.sh
dos2unix update.sh

in your Linux shell. (This shouldn't happen.)

Extra reading

The streamlink Twitch plugin has all the info needed in order to learn how to connect to Twitch and get the M3U8 playlist. Some of it doesn't quite match what Twitch is doing now, so watch a Twitch stream normally and look at the network requests your browser makes.

License

GNU GPLv3.

Comments
  • Bump openssl-src from 111.15.0+1.1.1k to 111.20.0+1.1.1o

    Bump openssl-src from 111.15.0+1.1.1k to 111.20.0+1.1.1o

    Bumps openssl-src from 111.15.0+1.1.1k to 111.20.0+1.1.1o.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Switch to reqwest and accept any hostname for certificates

    Switch to reqwest and accept any hostname for certificates

    Fixes #1.

    Makes it trivially easy to MITM the function, but it was specifically designed not to need any of your Twitch account's data so the worst thing that can happen is watching a different stream.

    opened by AlyoshaVasilieva 0
  • Bump openssl-src from 111.15.0+1.1.1k to 111.22.0+1.1.1q

    Bump openssl-src from 111.15.0+1.1.1k to 111.22.0+1.1.1q

    Bumps openssl-src from 111.15.0+1.1.1k to 111.22.0+1.1.1q.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump hyper from 0.14.11 to 0.14.19

    Bump hyper from 0.14.11 to 0.14.19

    Bumps hyper from 0.14.11 to 0.14.19.

    Release notes

    Sourced from hyper's releases.

    v0.14.19

    Bug Fixes

    • http1: fix preserving header case without enabling ffi (#2820) (6a35c175)
    • server: don't add implicit content-length to HEAD responses (#2836) (67b73138)

    Features

    Breaking Changes

    • ffi (unstable):
      • hyper_clientconn_options_new no longer sets the http1_preserve_header_case connection option by default. Users should now call hyper_clientconn_options_set_preserve_header_case if they desire that functionality. (78de8914)

    New Contributors ❤️

    v0.14.18

    Bug Fixes

    • ffi: don't build C libraries by default (1c663706)

    Features

    • client: add HttpInfo::local_addr() method (055b4e7e, closes #2767)

    New Contributors

    v0.14.17

    Bug Fixes

    ... (truncated)

    Changelog

    Sourced from hyper's changelog.

    v0.14.19 (2022-05-27)

    Bug Fixes

    • http1: fix preserving header case without enabling ffi (#2820) (6a35c175)
    • server: don't add implicit content-length to HEAD responses (#2836) (67b73138)

    Features

    Breaking Changes

    • ffi (unstable):
      • hyper_clientconn_options_new no longer sets the http1_preserve_header_case connection option by default. Users should now call hyper_clientconn_options_set_preserve_header_case if they desire that functionality. (78de8914)

    v0.14.18 (2022-03-22)

    Bug Fixes

    • ffi: don't build C libraries by default (1c663706)

    Features

    • client: add HttpInfo::local_addr() method (055b4e7e, closes #2767)

    v0.14.17 (2022-02-10)

    Bug Fixes

    Features

    ... (truncated)

    Commits
    • f8e2a83 v0.14.19
    • a929df8 docs(various): fix typos in VISION and ROADMAP (#2875)
    • 3a755a6 chore(lib): update tokio-util to 0.7 (#2762)
    • 4678be9 docs(contrib): add guide for Triaging Issues
    • 775fac1 docs(lib): propose 1.0 roadmap (#2806)
    • a32658c feat(server): add Connection::http2_max_header_list_size option (#2828)
    • 67b7313 fix(server): don't add implicit content-length to HEAD responses (#2836)
    • faf24c6 refactor(http1): assorted code readability improvements in h1/conn.rs (#2817)
    • 6a35c17 fix(http1): fix preserving header case without enabling ffi (#2820)
    • 89598df docs(lib): fix some typos (#2818)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump tokio from 1.9.0 to 1.16.1

    Bump tokio from 1.9.0 to 1.16.1

    Bumps tokio from 1.9.0 to 1.16.1.

    Release notes

    Sourced from tokio's releases.

    Tokio v1.16.1

    1.16.1 (January 28, 2022)

    This release fixes a bug in #4428 with the change #4437.

    #4428: tokio-rs/tokio#4428 #4437: tokio-rs/tokio#4437

    Tokio v1.16.0

    Fixes a soundness bug in io::Take (#4428). The unsoundness is exposed when leaking memory in the given AsyncRead implementation and then overwriting the supplied buffer:

    impl AsyncRead for Buggy {
        fn poll_read(
            self: Pin<&mut Self>,
            cx: &mut Context<'_>,
            buf: &mut ReadBuf<'_>
        ) -> Poll<Result<()>> {
          let new_buf = vec![0; 5].leak();
          *buf = ReadBuf::new(new_buf);
          buf.put_slice(b"hello");
          Poll::Ready(Ok(()))
        }
    }
    

    Also, this release includes improvements to the multi-threaded scheduler that can increase throughput by up to 20% in some cases (#4383).

    Fixed

    • io: soundness don't expose uninitialized memory when using io::Take in edge case (#4428)
    • fs: ensure File::write results in a write syscall when the runtime shuts down (#4316)
    • process: drop pipe after child exits in wait_with_output (#4315)
    • rt: improve error message when spawning a thread fails (#4398)
    • rt: reduce false-positive thread wakups in the multi-threaded scheduler (#4383)
    • sync: don't inherit Send from parking_lot::*Guard (#4359)

    Added

    • net: TcpSocket::linger() and set_linger() (#4324)
    • net: impl UnwindSafe for socket types (#4384)
    • rt: impl UnwindSafe for JoinHandle (#4418)
    • sync: watch::Receiver::has_changed() (#4342)
    • sync: oneshot::Receiver::blocking_recv() (#4334)
    • sync: RwLock blocking operations (#4425)

    Unstable

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Unreliable GFW evasion

    Unreliable GFW evasion

    The current version of the code uses a now-broken workaround to access the GQL API from inside China. Fixing that shows that Twitch appears to be blocking access to the GQL API, at least the way I use it from China. (Or the Great Firewall is blocking it.)

    Working on a resolution.

    opened by AlyoshaVasilieva 2
Owner
Malloc Voidstar
They/them
Malloc Voidstar
Distributed compute platform implemented in Rust, and powered by Apache Arrow.

Ballista: Distributed Compute Platform Overview Ballista is a distributed compute platform primarily implemented in Rust, powered by Apache Arrow. It

Ballista 2.3k Jan 3, 2023
A secure JavaScript and TypeScript runtime

Deno Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. Features Secure by default. No file,

Deno Land 87.1k Jan 5, 2023
Provides a single TUI-based registry for drm-free, wine and steam games on linux, accessed through a rofi launch menu.

eidolon A conversion of steam_suite to rust with additional features. Provides a single TUI-based registry for drm-free, wine and steam games on linux

Nico Hickman 113 Dec 27, 2022
👾 Modern and minimalist pixel editor

██ ████ ██ ██ ███ ██ ███ ██ ██ ██ ██ ██ ██ `rx` is a modern and minimalist pixel editor. Designed with g

Alexis Sellier 2.6k Jan 1, 2023
A genetic algorithm for bechmark problems, written to learn Rust.

Genetic Algorithm A genetic algorithm in Rust for the following benchmark problems: Ackley Griewangk Rastrigin Rosenbrock Schwefel Sphere Usage: Insta

Andrew Schwartzmeyer 73 Dec 25, 2022
interative assembly shell written in rust

Overview this project is inspired by https://github.com/poppycompass/asmshell Preview Build from source git clone https://github.com/keystone-engine/k

Xargin 236 Dec 23, 2022
Userspace WireGuard® Implementation in Rust

BoringTun BoringTun is an implementation of the WireGuard® protocol designed for portability and speed. BoringTun is successfully deployed on millions

Cloudflare 4.8k Jan 8, 2023
Drill is a HTTP load testing application written in Rust inspired by Ansible syntax

Drill Drill is a HTTP load testing application written in Rust. The main goal for this project is to build a really lightweight tool as alternative to

Ferran Basora 1.5k Dec 28, 2022
An experimental HTTP load testing application written in Rust.

Herd Herd was a small side project in building a HTTP load testing application in Rust with a main focus on being easy to use and low on OS level depe

Jacob Clark 100 Dec 27, 2022
A fast data collector in Rust

Flowgger is a fast, simple and lightweight data collector written in Rust. It reads log entries over a given protocol, extracts them, decodes them usi

Amazon Web Services - Labs 739 Jan 7, 2023
kytan: High Performance Peer-to-Peer VPN in Rust

kytan: High Performance Peer-to-Peer VPN kytan is a high performance peer to peer VPN written in Rust. The goal is to to minimize the hassle of config

Chang Lan 368 Dec 31, 2022
A purpose-built proxy for the Linkerd service mesh. Written in Rust.

This repo contains the transparent proxy component of Linkerd2. While the Linkerd2 proxy is heavily influenced by the Linkerd 1.X proxy, it comprises

Linkerd 1.7k Jan 7, 2023
Full fake REST API generator written with Rust

Weld Full fake REST API generator. This project is heavily inspired by json-server, written with rust. Synopsis Our first aim is to generate a fake ap

Seray Uzgur 243 Dec 31, 2022
pastebin written in pure rust. A rewrite of ptpb/pb.

rspb rust fork of ptpb/pb TL;DR Create a new paste from the output of cmd: cmd | curl -F c=@- https://pb.mgt.moe/ Usage Creating pastes > echo hi | c

mgt 39 Jan 4, 2023
The LibreTranslate API for Rust.

libretranslate-rs A LibreTranslate API for Rust. libretranslate = "0.2.4" libretranslate allows you to use open source machine translation in your pr

Grant Handy 51 Jan 5, 2023
Yet another pager in Rust

rust-pager Yet another pager in Rust Features Vim like keybindings Search substring Mouse wheel support Install cargo install rust-pager Usage <comman

null 19 Dec 7, 2022
Fork of async-raft, the Tokio-based Rust implementation of the Raft protocol.

Agreed Fork of async-raft, the Tokio-based Rust implementation of the Raft distributed consensus protocol. Agreed is an implementation of the Raft con

NLV8 Technologies 8 Jul 5, 2022
Rust runtime for Vercel Functions.

Rust Rust runtime for Vercel Functions. Community-maintained package to support using Rust inside Vercel Functions as a Runtime. Usage First, you'll n

Vercel Community 378 Dec 30, 2022
Source to relay.fedi.buzz: the customizable ActivityPub relay

buzzrelay A follow-only ActivityPub relay that connects to Mastodon's Streaming API. You don't need to run this yourself, just use the instance at rel

Astro 7 Jan 23, 2023
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022