diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..ad2f006 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,20 @@ +variables: + DOCKER_HOST: tcp://docker:2375 + +build: + image: docker:20 + stage: deploy + services: + - name: docker:20-dind + command: ["--experimental"] + before_script: + - mkdir -p ~/.docker/cli-plugins + - wget -O ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.8.1/buildx-v0.8.1.linux-amd64 + - chmod +x ~/.docker/cli-plugins/docker-buildx + - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker context create mybuilder + - docker buildx create --use --name mybuilder mybuilder + - docker pull $CI_REGISTRY_IMAGE:latest || true + - docker buildx build --cache-from $CI_REGISTRY_IMAGE:latest --platform linux/amd64,linux/arm64 --push -t $CI_REGISTRY_IMAGE:latest . \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 2d5ffc2..5fc5e52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,10 +8,9 @@ RUN cargo vendor RUN cargo build --release RUN ls target/release -FROM scratch as bin +FROM alpine:latest as bin WORKDIR /app -COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=build /src/target/release/stream-proxy . EXPOSE 3001 diff --git a/src/live.rs b/src/live.rs index 696a11f..aa7c24e 100644 --- a/src/live.rs +++ b/src/live.rs @@ -5,13 +5,11 @@ pub async fn forward_live( payload: web::Payload, path: web::Path, ) -> Result { - let cdn_url = "https://cdn.odysee.live/"; + let cdn_url = "https://cloud.odysee.live/"; let url = cdn_url.to_owned() + &path; let client = Client::default(); - println!("{}", url); - let forwarded_req = client .get(url) .insert_header(( diff --git a/src/main.rs b/src/main.rs index 4201224..a601a2e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod live; mod stream; +mod manifest; use std::env; use actix_web::{web, App, HttpServer}; @@ -17,6 +18,7 @@ async fn main() -> std::io::Result<()> { HttpServer::new(move || { App::new() + .route("/live/{path:.*}.m3u8", web::get().to(manifest::forward_manifest)) .route("/live/{path:.*}", web::get().to(live::forward_live)) .route("/stream/{path:.*}", web::get().to(stream::forward_stream)) }) diff --git a/src/manifest.rs b/src/manifest.rs new file mode 100644 index 0000000..840fb0d --- /dev/null +++ b/src/manifest.rs @@ -0,0 +1,41 @@ +use actix_web::{error, web, Error, HttpResponse}; +use lazy_static::lazy_static; +use regex::Regex; +use bytes::{Bytes}; + +fn replace_manifest_urls(text: &str) -> std::string::String { + lazy_static! { + static ref RE: Regex = Regex::new("(?m)^/[0-9]{3}").unwrap(); + } + let new_text = RE.replace_all(text, "/live$0"); + new_text.replace("https://cloud.odysee.live", "/live") +} + +pub async fn forward_manifest( + path: web::Path, +) -> Result { + let cdn_url = "https://cloud.odysee.live/"; + let url = cdn_url.to_owned() + &path + ".m3u8"; + + let client = awc::Client::default(); + let req = client + .get(url) + .insert_header(( + "User-Agent", + "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0", + )) + .insert_header(("Origin", "https://odysee.com")) + .insert_header(("Referer", "https://odysee.com/")); + + let mut res = req.send() + .await + .map_err(error::ErrorInternalServerError)?; + + let mut client_resp = HttpResponse::build(res.status()); + let body: Bytes = res.body().await?; + let body_vec = body.to_vec(); + let body_string = String::from_utf8(body_vec).unwrap(); + let new_body = replace_manifest_urls(&body_string); + + Ok(client_resp.body(new_body)) +} diff --git a/src/stream.rs b/src/stream.rs index db10944..bd6bd0e 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -7,8 +7,6 @@ pub async fn forward_stream(payload: web::Payload, path: web::Path) -> R let client = Client::default(); - println!("{}", url); - let forwarded_req = client .get(url) .insert_header((