Unable to stream some videos - "Upstream returned 403" #133
|
Hello! So my problem is this. Sometimes (maybe about half the times?), when I open a video, it streams perfectly fine, and I can watch it until the end forgetting I'm not on YouTube. Some other times, when I open a video, it starts streaming, then after ~10 seconds the video reloads, it buffers for a couple of seconds and then resumes streaming, only for the cycle to resume after 10 more seconds. This repeats for 3 or 4 times, until TypeType finally gives up and the stream enters a permanent buffering state (wheel spinning and nothing else showing). Being the diligent self-hoster that I am, I have been gathering all information and logs that may be relevant.
Now for the config. Here is my docker-compose. services:
typetype:
container_name: typetype
image: ghcr.io/priveetee/typetype:latest
security_opt:
- no-new-privileges
ports:
- "127.0.0.1:30973:80"
volumes:
- ./frontend/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- typetype-server
restart: unless-stopped
typetype-server:
container_name: typetype-server
image: ghcr.io/priveetee/typetype-server:latest
user: "1000:1000"
security_opt:
- no-new-privileges
cap_drop:
- ALL
environment:
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS}
DATABASE_URL: jdbc:postgresql://postgres:5432/typetype
DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
DRAGONFLY_URL: ${DRAGONFLY_URL}
DOWNLOADER_SERVICE_URL: http://typetype-downloader:18093
YOUTUBE_REMOTE_LOGIN_ENABLED: true
YOUTUBE_REMOTE_LOGIN_SERVICE_URL: http://typetype-token:8081
YOUTUBE_REMOTE_LOGIN_CALLBACK_BASE_URL: http://typetype-server:8080
YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN: ${YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN}
YOUTUBE_SESSION_ENCRYPTION_KEY: ${YOUTUBE_SESSION_ENCRYPTION_KEY}
YOUTUBE_REMOTE_LOGIN_TTL_MS: 480000
YOUTUBE_REMOTE_LOGIN_MAX_SESSIONS: 2
YOUTUBE_REMOTE_LOGIN_MAX_FRAME_BYTES: 524288
OIDC_ISSUER: "https://pocket-id.mydomain.com"
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID}
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
OIDC_PROVIDER_NAME: "Pocket ID"
depends_on:
postgres-init:
condition: service_completed_successfully
dragonfly:
condition: service_started
typetype-token:
condition: service_started
typetype-downloader:
condition: service_started
restart: unless-stopped
typetype-downloader:
container_name: typetype-downloader
image: ghcr.io/priveetee/typetype-downloader:latest
security_opt:
- no-new-privileges
environment:
HTTP_PORT: "18093"
PUBLIC_BASE_URL: /api/downloader
TYPETYPE_API_BASE: http://typetype-server:8080
DB_URL: jdbc:postgresql://postgres:5432/typetype_downloader
DB_USER: typetype
DB_PASSWORD: ${DATABASE_PASSWORD}
REDIS_HOST: dragonfly
REDIS_PORT: "6379"
REDIS_QUEUE_KEY: downloader:queue
MAX_CONCURRENT_WORKERS: "2"
MAX_QUEUE_SIZE: "100"
JOB_TTL_SECONDS: "600"
DOWNLOAD_WORKERS: "8"
DOWNLOAD_CHUNK_SIZE: "10485760"
DOWNLOAD_RANGE_MODE: query
MUXER: avformat
STORAGE_BACKEND: s3
S3_ENDPOINT: http://garage:3900
S3_PUBLIC_ENDPOINT: ${DOWNLOADER_S3_PUBLIC_ENDPOINT}
S3_REGION: garage
S3_BUCKET: typetype-downloads
S3_ACCESS_KEY: ${DOWNLOADER_S3_ACCESS_KEY}
S3_SECRET_KEY: ${DOWNLOADER_S3_SECRET_KEY}
S3_ARTIFACT_TTL_SECONDS: "7200"
depends_on:
postgres-init:
condition: service_completed_successfully
dragonfly:
condition: service_started
garage:
condition: service_started
typetype-token:
condition: service_started
restart: unless-stopped
typetype-token:
container_name: typetype-token
image: ghcr.io/priveetee/typetype-token:latest
user: "1000:1000"
security_opt:
- no-new-privileges
cap_drop:
- ALL
init: true
ipc: host
environment:
NODE_ENV: production
YOUTUBE_REMOTE_LOGIN_ENABLED: true
YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN: ${YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN}
YOUTUBE_REMOTE_LOGIN_CALLBACK_ORIGIN: http://typetype-server:8080
YOUTUBE_REMOTE_LOGIN_MAX_SESSIONS: 2
YOUTUBE_REMOTE_LOGIN_FRAME_FPS: 10
YOUTUBE_REMOTE_LOGIN_MAX_FRAME_BYTES: 524288
restart: unless-stopped
postgres:
container_name: typetype-postgres
image: postgres:17
security_opt:
- no-new-privileges
environment:
POSTGRES_DB: typetype
POSTGRES_USER: typetype
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
postgres-init:
container_name: typetype-postgres-init
image: postgres:17
security_opt:
- no-new-privileges
depends_on:
postgres:
condition: service_started
environment:
PGPASSWORD: ${DATABASE_PASSWORD}
command:
- /bin/sh
- -ec
- |
until pg_isready -h postgres -U typetype -d typetype; do sleep 1; done
EXISTS=$$(psql -h postgres -U typetype -d typetype -tAc "SELECT 1 FROM pg_database WHERE datname='typetype_downloader'")
if [ "$$EXISTS" != "1" ]; then
psql -h postgres -U typetype -d typetype -c "CREATE DATABASE typetype_downloader"
fi
restart: "no"
dragonfly:
container_name: typetype-dragonfly
image: ghcr.io/dragonflydb/dragonfly:latest
security_opt:
- no-new-privileges
ulimits:
memlock: -1
restart: unless-stopped
garage:
container_name: typetype-garage
image: dxflrs/garage:v2.2.0
security_opt:
- no-new-privileges
volumes:
- ./garage/garage.toml:/etc/garage.toml:ro
- garage_meta:/var/lib/garage/meta
- garage_data:/var/lib/garage/data
restart: unless-stopped
ports:
- 127.0.0.1:39001:3900
volumes:
postgres_data:
garage_meta:
garage_data:And relevant logs. When the video is streaming, I see requests to Then I start getting some 422's (showing the url in case anything is different?): The response to this is This is all from browser devtools. On the containers side, The I am really at my wits' end, I don't know if Google has flagged my IP and I'm doomed, or if there's something wrong with my configuration. For what it's worth, my YouTube remote connection doesn't seem to get used at all: in the Remote Login page, it shows "Status: connected" and "Last used: never". |
Replies: 1 comment
|
Hey, sorry I completely missed this one. This was not a mistake in ur setup, and the logs do not look like Google flagged ur home IP. At that time TypeType was still sending signed The
Since this report I rebuilt YouTube playback around a stateful SABR session on Server and my own MSE player in the frontend. Current playback no longer depends on those signed Could u update to TypeType 1.1.1 if u have not updated yet, and retry the same videos? If any still fail, send me the YouTube watch URLs or video IDs. The signed URLs in the report are not enough to identify the original videos, so I do not want to claim it is fixed without testing them again. And thx for taking the time to provide all these logs, they made the old failure pretty clear. |
Hey, sorry I completely missed this one.
This was not a mistake in ur setup, and the logs do not look like Google flagged ur home IP. At that time TypeType was still sending signed
googlevideoURLs through/api/proxy. The first range requests returned206, then YouTube rejected the following requests with403, so the player kept rebuilding the source until it eventually gave up.The
ChannelWriteExceptionwas mostly a consequence of this reload loop: the browser had already closed the previous proxy response while Server was still writing it.Last used: neverwas confusing but expected with that old implementation. The connected YouTube session was only used as a fallback when public extra…