Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6.0.2
- uses: actions/checkout@v7.0.1
with:
submodules: true
- run: ./scripts/validate-stack.sh
Expand All @@ -28,7 +28,7 @@ jobs:
if: github.event_name != 'pull_request'
runs-on: [self-hosted, Linux, X64, arko, typetype]
steps:
- uses: actions/checkout@v6.0.2
- uses: actions/checkout@v7.0.1
with:
submodules: true
- run: ./scripts/validate-stack.sh
8 changes: 7 additions & 1 deletion .github/workflows/component-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,17 @@ jobs:

- name: Update beta
env:
COMPONENT: ${{ needs.validate.outputs.component }}
DEPLOY_HOST: ${{ secrets.TYPE_TYPE_DEPLOY_HOST }}
DEPLOY_PORT: ${{ secrets.TYPE_TYPE_DEPLOY_PORT }}
DEPLOY_USER: ${{ secrets.TYPE_TYPE_DEPLOY_USER }}
DIGEST: ${{ needs.validate.outputs.digest }}
IMAGE: ${{ needs.validate.outputs.image }}
run: |
ssh -i "$RUNNER_TEMP/typetype_deploy_key" -p "$DEPLOY_PORT" -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" "$DEPLOY_USER@$DEPLOY_HOST" /usr/local/sbin/typetype-beta-update
printf -v update_command \
'TYPETYPE_DEPLOY_COMPONENT=%q TYPETYPE_DEPLOY_IMAGE=%q TYPETYPE_DEPLOY_DIGEST=%q /usr/local/sbin/typetype-beta-update' \
"$COMPONENT" "$IMAGE" "$DIGEST"
ssh -i "$RUNNER_TEMP/typetype_deploy_key" -p "$DEPLOY_PORT" -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" "$DEPLOY_USER@$DEPLOY_HOST" "$update_command"
curl --fail --retry 12 --retry-delay 2 --retry-all-errors --silent --show-error https://beta.typetype.video/api/health
curl --fail --retry 12 --retry-delay 2 --retry-all-errors --silent --show-error https://beta.typetype.video/api/downloader/health

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ tmp/
.DS_Store
*.tsbuildinfo
.env
.runtime/
2 changes: 1 addition & 1 deletion Docs-TypeType
Submodule Docs-TypeType updated 40 files
+4 −1 .github/workflows/deploy.yml
+2 −2 .github/workflows/typos.yml
+4 −0 .typos.toml
+3 −0 CONTRIBUTING.md
+3 −1 README.md
+83 −77 bun.lock
+160 −15 docs/.vitepress/config.mts
+47 −0 docs/.vitepress/theme/MermaidDiagram.vue
+6 −1 docs/.vitepress/theme/index.ts
+14 −0 docs/.vitepress/theme/style.css
+29 −0 docs/es/index.md
+134 −0 docs/es/self-hosting/prerequisites.md
+29 −0 docs/fr/index.md
+137 −0 docs/fr/self-hosting/prerequisites.md
+6 −0 docs/guide/accounts.md
+12 −0 docs/guide/embedding.md
+5 −0 docs/guide/library.md
+10 −2 docs/guide/settings.md
+5 −2 docs/index.md
+56 −0 docs/project/community.md
+89 −0 docs/project/index.md
+149 −0 docs/project/playback.md
+95 −0 docs/project/releases.md
+184 −0 docs/project/repositories.md
+43 −13 docs/self-hosting/architecture.md
+82 −9 docs/self-hosting/authentication.md
+24 −6 docs/self-hosting/beta-and-main.md
+192 −52 docs/self-hosting/configuration.md
+67 −19 docs/self-hosting/docker-compose.md
+29 −2 docs/self-hosting/importing-data.md
+32 −22 docs/self-hosting/introduction.md
+87 −9 docs/self-hosting/maintenance.md
+95 −3 docs/self-hosting/prerequisites.md
+14 −6 docs/self-hosting/quick-start.md
+24 −12 docs/self-hosting/reporting-issues.md
+34 −5 docs/self-hosting/reverse-proxy.md
+11 −6 docs/self-hosting/rollback.md
+127 −0 docs/self-hosting/security.md
+118 −11 docs/self-hosting/troubleshooting.md
+5 −3 package.json
103 changes: 92 additions & 11 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,98 @@
# TypeType 1.2.4
# TypeType 1.3.0

## Summary
TypeType 1.3.0 brings new backup and content controls, makes SABR the only
YouTube playback path on the web, and improves downloads and self-hosted
updates.

- fix intermittent SABR startup failures when resuming videos from a saved position
- restore reliable audio and video initialization on cold playback sessions
- prevent stalled preparation from retrying indefinitely
- improve recovery when a SABR session cannot produce media
- keep repeated long-distance seeks responsive while SABR recovery is pending
## Playback

Normal seeks and quality changes continue to preserve the current playback position.
- Use SABR/MSE for all YouTube web playback, including watch pages, embeds and
autoplay. The old Classic toggle and transition prompt have been removed.
NicoNico and BiliBili playback remain unchanged.
[#168](https://github.com/TypeType-Video/TypeType/issues/168)
- Recover SABR sessions when YouTube authorization expires and stop stalled
preparation attempts instead of retrying indefinitely.
- Apply automatic SponsorBlock skips in audio-only mode.
[#178](https://github.com/TypeType-Video/TypeType/issues/178)
- Add a default playback speed from `0.25x` to `4x`, applied to regular videos
and Shorts.

No configuration or database migration is required.
## Backups And Content Controls

Thx to everyone who reported playback and buffering issues.
- Export a complete TypeType backup or select individual categories, including
subscriptions, history, playlists, watch later, favorites, playback
progress, search history, saved playlists, settings and content filters.
- Restore versioned TypeType JSON backups with an immediate confirmation
showing how many items were restored.
- Add blocked title keywords to filter unwanted videos from recommendations.
- Support very large history exports without exceeding PostgreSQL query
limits.
- Preserve more original dates and metadata when importing YouTube Takeout
favorites, history and playlists.

If u want to support TypeType, please share it with others. If u want to support it financially, u can do so through [GitHub Sponsors](https://github.com/sponsors/Priveetee).
## Subscriptions

- Keep subscription feeds updating when one subscribed channel is deleted,
private or temporarily unavailable.
[#180](https://github.com/TypeType-Video/TypeType/issues/180)
- Keep live videos ordered by their actual promotion time instead of
permanently placing every active live stream first.

## Downloads And Performance

- Rework SABR downloads around bounded multipart streams and concurrent range
workers.
- Reserve the required disk space before starting large downloads to prevent
active jobs from exhausting storage.
- Detect stalled streams while allowing long downloads to continue as long as
data is still arriving.
- Reduce progress-update contention and reuse download buffers.
- Serve precompressed frontend assets through Nginx.

## Self-Hosting

- Bundle the default Nginx configuration directly in the Frontend image.
- Generate the default Garage configuration inside a managed Docker volume.
- Back up existing stack files and preserve custom Compose and Garage
configuration during updates.
- Validate the resolved Compose configuration, wait for service health and
provide a rollback directory when an update fails.
- Show the Frontend, Server, Token and Downloader versions, revisions and build
times directly in Settings.
- Expand the self-hosting documentation with resource requirements and new
French and Spanish prerequisites guides.
[#176](https://github.com/TypeType-Video/TypeType/issues/176)

Self-hosters should follow the official update procedure for this release
because the Compose stack and managed configuration have changed.

## Thx

A big thx to @BuggyPasta for the detailed testing and for the ideas behind
backups, blocked keywords and default playback speed.

Thx to @Toastienergy for reporting the missing SponsorBlock behavior in
audio-only mode, and to @tam1m for the precise subscription-feed report.

Thx to @jerkiz and @coral-hungus for testing playback and SponsorBlock on real
iPhones.

Thx to @arcoast for the Nginx, Garage and update-flow suggestions, to
@filippobaroni for helping expose problems caused by stale self-hosted stack
files, and to @EdgarsJudovics for helping keep the script-free installation
path documented.

Thx as well to everyone testing the beta, reporting playback and buffering
problems, or helping other self-hosters.

## Updating

Follow the
[update guide](https://typetype-video.github.io/Docs-TypeType/self-hosting/maintenance).

If necessary, follow the
[rollback guide](https://typetype-video.github.io/Docs-TypeType/self-hosting/rollback).

If u want to support TypeType, please share it with others. If u want to
support it financially, u can do so through
[GitHub Sponsors](https://github.com/sponsors/Priveetee).
2 changes: 1 addition & 1 deletion TypeType-Downloader
Submodule TypeType-Downloader updated 39 files
+3 −3 .github/workflows/ci.yml
+2 −2 .github/workflows/coverage.yml
+24 −3 .github/workflows/docker.yml
+6 −10 Dockerfile
+1 −1 Dockerfile.wolfi
+1 −1 cmd/server/main.go
+1 −1 docker-compose.yml
+3 −1 internal/api/version_test.go
+1 −1 internal/buildinfo/info.go
+79 −161 internal/downloader/range_downloader.go
+253 −0 internal/downloader/range_downloader_test.go
+110 −0 internal/downloader/range_request.go
+159 −0 internal/downloader/range_worker.go
+30 −0 internal/mux/real_remux_test.go
+85 −0 internal/pipeline/capacity.go
+68 −0 internal/pipeline/capacity_test.go
+18 −0 internal/pipeline/failure.go
+16 −0 internal/pipeline/failure_test.go
+4 −4 internal/pipeline/remote.go
+15 −10 internal/pipeline/runner.go
+2 −4 internal/pipeline/sabr.go
+23 −8 internal/pipeline/sabr_runner.go
+57 −0 internal/pipeline/sabr_runner_test.go
+81 −69 internal/sabr/download.go
+95 −0 internal/sabr/download_benchmark_test.go
+223 −74 internal/sabr/download_test.go
+70 −0 internal/sabr/idle_timeout.go
+63 −0 internal/sabr/idle_timeout_test.go
+0 −95 internal/sabr/manifest.go
+0 −42 internal/sabr/manifest_test.go
+83 −0 internal/sabr/multipart.go
+94 −0 internal/sabr/network_test.go
+111 −0 internal/sabr/part_files.go
+35 −14 internal/sabr/progress.go
+0 −150 internal/sabr/segments.go
+186 −0 internal/sabr/stream_protocol.go
+16 −10 internal/sabr/types.go
+56 −2 internal/storage/monitor.go
+35 −0 internal/storage/monitor_test.go
2 changes: 1 addition & 1 deletion TypeType-Frontend
Submodule TypeType-Frontend updated 70 files
+2 −2 .github/workflows/ci.yml
+1 −1 .github/workflows/coverage.yml
+9 −9 .github/workflows/docker.yml
+4 −1 Dockerfile
+1 −1 apps/web/package.json
+ apps/web/public/import-cooking-chef.gif
+ apps/web/public/import-dudu-cooking.gif
+ apps/web/public/member-only.gif
+1 −4 apps/web/src/components/embed-player-shell.tsx
+0 −26 apps/web/src/components/navbar-playback-mode.tsx
+0 −2 apps/web/src/components/navbar.tsx
+0 −165 apps/web/src/components/playback-transition-notice.tsx
+35 −0 apps/web/src/components/player-defaults.tsx
+1 −0 apps/web/src/components/shorts-player-shell.tsx
+3 −0 apps/web/src/components/shorts-player-stage.tsx
+3 −0 apps/web/src/components/shorts-video-player.tsx
+5 −1 apps/web/src/components/toast.tsx
+2 −1 apps/web/src/components/video-player-playback-tools.tsx
+2 −2 apps/web/src/components/video-preview.tsx
+17 −3 apps/web/src/components/watch-stage-player.tsx
+12 −3 apps/web/src/hooks/use-blocked-filter.ts
+32 −1 apps/web/src/hooks/use-blocked.ts
+0 −23 apps/web/src/hooks/use-playback-mode.ts
+15 −23 apps/web/src/hooks/use-player-error.ts
+1 −0 apps/web/src/hooks/use-settings.ts
+6 −24 apps/web/src/hooks/use-stream.ts
+12 −0 apps/web/src/hooks/use-version-info.ts
+4 −6 apps/web/src/hooks/use-watch-autoplay-preload.ts
+20 −0 apps/web/src/lib/api-collections.ts
+53 −0 apps/web/src/lib/api-restore.ts
+1 −3 apps/web/src/lib/api-stream.ts
+61 −0 apps/web/src/lib/api-version.ts
+3 −3 apps/web/src/lib/bilibili-manifest.ts
+11 −0 apps/web/src/lib/blocked-keyword-filter.ts
+3 −3 apps/web/src/lib/dash-manifest.ts
+0 −9 apps/web/src/lib/embed-playback.ts
+0 −62 apps/web/src/lib/playback-mode.ts
+12 −0 apps/web/src/lib/playback-speed.ts
+11 −3 apps/web/src/lib/sabr-playback-rate-preference.ts
+4 −2 apps/web/src/lib/settings-section.ts
+11 −0 apps/web/src/lib/sponsorblock-playback-tools.ts
+4 −4 apps/web/src/lib/stream-compatibility.ts
+9 −9 apps/web/src/lib/stream-delivery.ts
+8 −8 apps/web/src/lib/stream-direct-src.ts
+7 −16 apps/web/src/lib/stream-request.ts
+12 −13 apps/web/src/lib/stream-src.ts
+0 −3 apps/web/src/routes/__root.tsx
+3 −18 apps/web/src/routes/embed_.$videoId.tsx
+5 −23 apps/web/src/routes/settings.tsx
+1 −1 apps/web/src/routes/shorts.tsx
+3 −10 apps/web/src/routes/watch.tsx
+55 −0 apps/web/src/settings/settings-about.tsx
+145 −0 apps/web/src/settings/settings-backup.tsx
+64 −25 apps/web/src/settings/settings-blocked.tsx
+1 −1 apps/web/src/settings/settings-nav.tsx
+33 −9 apps/web/src/settings/settings-playback.tsx
+7 −0 apps/web/src/types/user.ts
+45 −0 apps/web/tests/api-version.test.ts
+19 −0 apps/web/tests/blocked-keyword-filter.test.ts
+1 −7 apps/web/tests/embed-playback.test.ts
+14 −0 apps/web/tests/playback-speed.test.ts
+25 −0 apps/web/tests/sabr-playback-rate-preference.test.ts
+39 −0 apps/web/tests/sponsorblock-playback-tools.test.ts
+7 −7 apps/web/tests/stream-hls-transport.test.ts
+6 −23 apps/web/tests/stream-playback-mode.test.ts
+1 −1 apps/web/tests/watch-player-key.test.ts
+1 −1 biome.json
+66 −69 bun.lock
+2 −0 nginx.conf
+5 −4 package.json
2 changes: 1 addition & 1 deletion TypeType-Player
2 changes: 1 addition & 1 deletion TypeType-Server
Submodule TypeType-Server updated 157 files
59 changes: 53 additions & 6 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ services:
image: ${TYPETYPE_WEB_BETA_IMAGE:-ghcr.io/typetype-video/typetype-beta:latest}
ports:
- "${HOST_PORT_WEB_BETA:-18082}:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
typetype-server:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1/api/version/web"]
interval: 5s
timeout: 3s
retries: 12
restart: unless-stopped

typetype-server:
Expand All @@ -21,7 +24,7 @@ services:
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-${POSTGRES_PASSWORD:-typetype}}
DRAGONFLY_URL: ${DRAGONFLY_URL:-redis://dragonfly:6379}
DOWNLOADER_SERVICE_URL: http://typetype-downloader:18093
YOUTUBE_OUTBOUND_PROXY_URL: ${YOUTUBE_OUTBOUND_PROXY_URL:-}
YOUTUBE_OUTBOUND_PROXY_URL: ${YOUTUBE_OUTBOUND_PROXY_URL:?YOUTUBE_OUTBOUND_PROXY_URL is required}
YOUTUBE_REMOTE_LOGIN_ENABLED: ${YOUTUBE_REMOTE_LOGIN_ENABLED:-false}
YOUTUBE_REMOTE_LOGIN_SERVICE_URL: http://typetype-token:8081
YOUTUBE_REMOTE_LOGIN_CALLBACK_BASE_URL: http://typetype-server:8080
Expand Down Expand Up @@ -90,7 +93,7 @@ services:
ipc: host
environment:
NODE_ENV: production
YOUTUBE_OUTBOUND_PROXY_URL: ${YOUTUBE_OUTBOUND_PROXY_URL:-}
YOUTUBE_OUTBOUND_PROXY_URL: ${YOUTUBE_OUTBOUND_PROXY_URL:?YOUTUBE_OUTBOUND_PROXY_URL is required}
YOUTUBE_REMOTE_LOGIN_ENABLED: ${YOUTUBE_REMOTE_LOGIN_ENABLED:-false}
YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN: ${YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN:-}
YOUTUBE_REMOTE_LOGIN_CALLBACK_ORIGIN: ${YOUTUBE_REMOTE_LOGIN_CALLBACK_ORIGIN:-http://typetype-server:8080}
Expand Down Expand Up @@ -136,26 +139,70 @@ services:
restart: "no"

dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
image: docker.dragonflydb.io/dragonflydb/dragonfly:v1.39.0
ulimits:
memlock: -1
healthcheck:
test: ["CMD", "redis-cli", "ping"]
restart: unless-stopped

garage-config:
image: busybox:1.37
command:
- /bin/sh
- -ec
- |
config=/etc/garage/garage.toml
if [ -s "$$config" ]; then
exit 0
fi
umask 077
if [ -s /migration/garage.toml ]; then
cp /migration/garage.toml "$$config"
exit 0
fi
cat > "$$config" <<'EOF'
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"

replication_factor = 1

rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"

[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
EOF
volumes:
- garage_config:/etc/garage
- ./.typetype-migration:/migration:ro
restart: "no"

garage:
image: dxflrs/garage:v2.2.0
ports:
- "${HOST_BIND_GARAGE_S3_BETA:-127.0.0.1}:${HOST_PORT_GARAGE_S3_BETA:-3900}:3900"
environment:
GARAGE_CONFIG_FILE: /etc/garage/garage.toml
GARAGE_RPC_SECRET: ${GARAGE_RPC_SECRET:-}
volumes:
- ./garage.toml:/etc/garage.toml:ro
- garage_config:/etc/garage
- garage_meta:/var/lib/garage/meta
- garage_data:/var/lib/garage/data
depends_on:
garage-config:
condition: service_completed_successfully
healthcheck:
test: ["CMD", "/garage", "status"]
interval: 5s
timeout: 3s
retries: 12
restart: unless-stopped

volumes:
postgres_data:
garage_config:
garage_meta:
garage_data:
57 changes: 52 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ services:
image: ${TYPETYPE_WEB_IMAGE:-ghcr.io/typetype-video/typetype:latest}
ports:
- "${HOST_PORT_WEB:-8082}:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
typetype-server:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1/api/version/web"]
interval: 5s
timeout: 3s
retries: 12
restart: unless-stopped
typetype-server:
image: ${TYPETYPE_SERVER_IMAGE:-ghcr.io/typetype-video/typetype-server:latest}
Expand Down Expand Up @@ -50,7 +53,7 @@ services:
restart: unless-stopped

typetype-secrets:
image: busybox:1.37
image: busybox:1.38
command:
- /bin/sh
- -ec
Expand Down Expand Up @@ -176,25 +179,69 @@ services:
restart: "no"

dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
image: docker.dragonflydb.io/dragonflydb/dragonfly:v1.39.0
ulimits:
memlock: -1
healthcheck:
test: ["CMD", "redis-cli", "ping"]
restart: unless-stopped
garage-config:
image: busybox:1.37
command:
- /bin/sh
- -ec
- |
config=/etc/garage/garage.toml
if [ -s "$$config" ]; then
exit 0
fi
umask 077
if [ -s /migration/garage.toml ]; then
cp /migration/garage.toml "$$config"
exit 0
fi
cat > "$$config" <<'EOF'
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"

replication_factor = 1

rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"

[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
EOF
volumes:
- garage_config:/etc/garage
- ./.typetype-migration:/migration:ro
restart: "no"

garage:
image: dxflrs/garage:v2.2.0
ports:
- "${HOST_BIND_GARAGE_S3:-127.0.0.1}:${HOST_PORT_GARAGE_S3:-3900}:3900"
environment:
GARAGE_CONFIG_FILE: /etc/garage/garage.toml
GARAGE_RPC_SECRET: ${GARAGE_RPC_SECRET:-}
volumes:
- ./garage.toml:/etc/garage.toml:ro
- garage_config:/etc/garage
- garage_meta:/var/lib/garage/meta
- garage_data:/var/lib/garage/data
depends_on:
garage-config:
condition: service_completed_successfully
healthcheck:
test: ["CMD", "/garage", "status"]
interval: 5s
timeout: 3s
retries: 12
restart: unless-stopped
volumes:
postgres_data:
typetype_secrets:
garage_config:
garage_meta:
garage_data:
12 changes: 0 additions & 12 deletions garage.toml

This file was deleted.

Loading