mirror of
https://github.com/iv-org/invidious.git
synced 2025-06-28 01:28:30 +00:00
Merge branch 'master' into theme-styles
This commit is contained in:
commit
82b943dc9b
@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
## vX.Y.0 (future)
|
## vX.Y.0 (future)
|
||||||
|
|
||||||
|
## v2.20250504.0
|
||||||
|
|
||||||
|
Small release with quick workaround fix for issue #4251 (Nil assertion failed).
|
||||||
|
|
||||||
|
PR: https://github.com/iv-org/invidious/issues/5263
|
||||||
|
|
||||||
## v2.20250314.0
|
## v2.20250314.0
|
||||||
|
|
||||||
### Wrap-up
|
### Wrap-up
|
||||||
|
14
README.md
14
README.md
@ -81,9 +81,9 @@
|
|||||||
- [Available in many languages](locales/), thanks to [our translators](#contribute)
|
- [Available in many languages](locales/), thanks to [our translators](#contribute)
|
||||||
|
|
||||||
**Data import/export**
|
**Data import/export**
|
||||||
- Import subscriptions from YouTube, NewPipe and Freetube
|
- Import subscriptions from YouTube, NewPipe and FreeTube
|
||||||
- Import watch history from YouTube and NewPipe
|
- Import watch history from YouTube and NewPipe
|
||||||
- Export subscriptions to NewPipe and Freetube
|
- Export subscriptions to NewPipe and FreeTube
|
||||||
- Import/Export Invidious user data
|
- Import/Export Invidious user data
|
||||||
|
|
||||||
**Technical features**
|
**Technical features**
|
||||||
@ -95,11 +95,11 @@
|
|||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
**Using invidious:**
|
**Using Invidious:**
|
||||||
|
|
||||||
- [Select a public instance from the list](https://instances.invidious.io) and start watching videos right now!
|
- [Select a public instance from the list](https://instances.invidious.io) and start watching videos right now!
|
||||||
|
|
||||||
**Hosting invidious:**
|
**Hosting Invidious:**
|
||||||
|
|
||||||
- [Follow the installation instructions](https://docs.invidious.io/installation/)
|
- [Follow the installation instructions](https://docs.invidious.io/installation/)
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ https://github.com/iv-org/documentation
|
|||||||
### Extensions
|
### Extensions
|
||||||
|
|
||||||
We highly recommend the use of [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect#get),
|
We highly recommend the use of [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect#get),
|
||||||
a browser extension that automatically redirects Youtube URLs to any Invidious instance and replaces
|
a browser extension that automatically redirects YouTube URLs to any Invidious instance and replaces
|
||||||
embedded youtube videos on other websites with invidious.
|
embedded YouTube videos on other websites with Invidious.
|
||||||
|
|
||||||
The documentation contains a list of browser extensions that we recommended to use along with Invidious.
|
The documentation contains a list of browser extensions that we recommended to use along with Invidious.
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ We use [Weblate](https://weblate.org) to manage Invidious translations.
|
|||||||
You can suggest new translations and/or correction here: https://hosted.weblate.org/engage/invidious/.
|
You can suggest new translations and/or correction here: https://hosted.weblate.org/engage/invidious/.
|
||||||
|
|
||||||
Creating an account is not required, but recommended, especially if you want to contribute regularly.
|
Creating an account is not required, but recommended, especially if you want to contribute regularly.
|
||||||
Weblate also allows you to log-in with major SSO providers like Github, Gitlab, BitBucket, Google, ...
|
Weblate also allows you to log-in with major SSO providers like GitHub, GitLab, BitBucket, Google, ...
|
||||||
|
|
||||||
|
|
||||||
## Projects using Invidious
|
## Projects using Invidious
|
||||||
|
@ -90,14 +90,14 @@ db:
|
|||||||
##
|
##
|
||||||
## API key for Invidious companion, used for securing the communication
|
## API key for Invidious companion, used for securing the communication
|
||||||
## between Invidious and Invidious companion.
|
## between Invidious and Invidious companion.
|
||||||
## The size of the key needs to be more or equal to 16.
|
## The key needs to be exactly 16 characters long.
|
||||||
##
|
##
|
||||||
## Note: This parameter is mandatory when Invidious companion is enabled
|
## Note: This parameter is mandatory when Invidious companion is enabled
|
||||||
## and should be a random string.
|
## and should be a random string.
|
||||||
## Such random string can be generated on linux with the following
|
## Such random string can be generated on linux with the following
|
||||||
## command: `pwgen 16 1`
|
## command: `pwgen 16 1`
|
||||||
##
|
##
|
||||||
## Accepted values: a string
|
## Accepted values: a string (of length 16)
|
||||||
## Default: <none>
|
## Default: <none>
|
||||||
##
|
##
|
||||||
#invidious_companion_key: "CHANGE_ME!!"
|
#invidious_companion_key: "CHANGE_ME!!"
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
# If you want to use Invidious in production, see the docker-compose.yml file provided
|
# If you want to use Invidious in production, see the docker-compose.yml file provided
|
||||||
# in the installation documentation: https://docs.invidious.io/installation/
|
# in the installation documentation: https://docs.invidious.io/installation/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
|
|
||||||
@ -11,9 +13,10 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
|
image: rockerboo/invidious
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3000:3000"
|
- "127.0.0.1:9999:3000"
|
||||||
environment:
|
environment:
|
||||||
# Please read the following file for a comprehensive list of all available
|
# Please read the following file for a comprehensive list of all available
|
||||||
# configuration options and their associated syntax:
|
# configuration options and their associated syntax:
|
||||||
|
@ -23,10 +23,16 @@ module Invidious::Frontend::WatchPage
|
|||||||
return "<p id=\"download\">#{translate(locale, "Download is disabled")}</p>"
|
return "<p id=\"download\">#{translate(locale, "Download is disabled")}</p>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
url = "/download"
|
||||||
|
if (CONFIG.invidious_companion.present?)
|
||||||
|
invidious_companion = CONFIG.invidious_companion.sample
|
||||||
|
url = "#{invidious_companion.public_url}/download?check=#{invidious_companion_encrypt(video.id)}"
|
||||||
|
end
|
||||||
|
|
||||||
return String.build(4000) do |str|
|
return String.build(4000) do |str|
|
||||||
str << "<form"
|
str << "<form"
|
||||||
str << " class=\"watch-action-group\""
|
str << " class=\"watch-action-group\""
|
||||||
str << " action='/download'"
|
str << " action='#{url}'"
|
||||||
str << " method='post'"
|
str << " method='post'"
|
||||||
str << " rel='noopener'"
|
str << " rel='noopener'"
|
||||||
str << " target='_blank'>"
|
str << " target='_blank'>"
|
||||||
|
@ -21,7 +21,7 @@ module Invidious::Routes::VideoPlayback
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Sanity check, to avoid being used as an open proxy
|
# Sanity check, to avoid being used as an open proxy
|
||||||
if !host.matches?(/[\w-]+.googlevideo.com/)
|
if !host.matches?(/[\w-]+\.(?:googlevideo|c\.youtube)\.com/)
|
||||||
return error_template(400, "Invalid \"host\" parameter.")
|
return error_template(400, "Invalid \"host\" parameter.")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -37,7 +37,8 @@ module Invidious::Routes::VideoPlayback
|
|||||||
|
|
||||||
# See: https://github.com/iv-org/invidious/issues/3302
|
# See: https://github.com/iv-org/invidious/issues/3302
|
||||||
range_header = env.request.headers["Range"]?
|
range_header = env.request.headers["Range"]?
|
||||||
if range_header.nil?
|
sq = query_params["sq"]?
|
||||||
|
if range_header.nil? && sq.nil?
|
||||||
range_for_head = query_params["range"]? || "0-640"
|
range_for_head = query_params["range"]? || "0-640"
|
||||||
headers["Range"] = "bytes=#{range_for_head}"
|
headers["Range"] = "bytes=#{range_for_head}"
|
||||||
end
|
end
|
||||||
|
@ -293,6 +293,9 @@ module Invidious::Routes::Watch
|
|||||||
if CONFIG.disabled?("downloads")
|
if CONFIG.disabled?("downloads")
|
||||||
return error_template(403, "Administrator has disabled this endpoint.")
|
return error_template(403, "Administrator has disabled this endpoint.")
|
||||||
end
|
end
|
||||||
|
if CONFIG.invidious_companion.present?
|
||||||
|
return error_template(403, "Downloads should be routed through Companion when present")
|
||||||
|
end
|
||||||
|
|
||||||
title = env.params.body["title"]? || ""
|
title = env.params.body["title"]? || ""
|
||||||
video_id = env.params.body["id"]? || ""
|
video_id = env.params.body["id"]? || ""
|
||||||
@ -328,13 +331,7 @@ module Invidious::Routes::Watch
|
|||||||
env.params.query["title"] = filename
|
env.params.query["title"] = filename
|
||||||
env.params.query["local"] = "true"
|
env.params.query["local"] = "true"
|
||||||
|
|
||||||
if (CONFIG.invidious_companion.present?)
|
return Invidious::Routes::VideoPlayback.latest_version(env)
|
||||||
video = get_video(video_id)
|
|
||||||
invidious_companion = CONFIG.invidious_companion.sample
|
|
||||||
return env.redirect "#{invidious_companion.public_url}/latest_version?#{env.params.query}"
|
|
||||||
else
|
|
||||||
return Invidious::Routes::VideoPlayback.latest_version(env)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
return error_template(400, "Invalid label or itag")
|
return error_template(400, "Invalid label or itag")
|
||||||
end
|
end
|
||||||
|
@ -109,27 +109,20 @@ def extract_video_info(video_id : String)
|
|||||||
params["reason"] = JSON::Any.new(reason) if reason
|
params["reason"] = JSON::Any.new(reason) if reason
|
||||||
|
|
||||||
if !CONFIG.invidious_companion.present?
|
if !CONFIG.invidious_companion.present?
|
||||||
new_player_response = nil
|
if player_response["streamingData"]? && player_response.dig?("streamingData", "adaptiveFormats", 0, "url").nil?
|
||||||
|
LOGGER.warn("Missing URLs for adaptive formats, falling back to other YT clients.")
|
||||||
# Don't use Android test suite client if po_token is passed because po_token doesn't
|
players_fallback = [YoutubeAPI::ClientType::WebMobile, YoutubeAPI::ClientType::TvHtml5]
|
||||||
# work for Android test suite client.
|
players_fallback.each do |player_fallback|
|
||||||
if reason.nil? && CONFIG.po_token.nil?
|
client_config.client_type = player_fallback
|
||||||
# Fetch the video streams using an Android client in order to get the
|
player_fallback_response = try_fetch_streaming_data(video_id, client_config)
|
||||||
# decrypted URLs and maybe fix throttling issues (#2194). See the
|
if player_fallback_response && player_fallback_response["streamingData"]? &&
|
||||||
# following issue for an explanation about decrypted URLs:
|
player_fallback_response.dig?("streamingData", "adaptiveFormats", 0, "url")
|
||||||
# https://github.com/TeamNewPipe/NewPipeExtractor/issues/562
|
streaming_data = player_response["streamingData"].as_h
|
||||||
client_config.client_type = YoutubeAPI::ClientType::AndroidTestSuite
|
streaming_data["adaptiveFormats"] = player_fallback_response["streamingData"]["adaptiveFormats"]
|
||||||
new_player_response = try_fetch_streaming_data(video_id, client_config)
|
player_response["streamingData"] = JSON::Any.new(streaming_data)
|
||||||
end
|
break
|
||||||
|
end
|
||||||
# Replace player response and reset reason
|
end
|
||||||
if !new_player_response.nil?
|
|
||||||
# Preserve captions & storyboard data before replacement
|
|
||||||
new_player_response["storyboards"] = player_response["storyboards"] if player_response["storyboards"]?
|
|
||||||
new_player_response["captions"] = player_response["captions"] if player_response["captions"]?
|
|
||||||
|
|
||||||
player_response = new_player_response
|
|
||||||
params.delete("reason")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user