When switching between Listen and Watching the timestamp in the url of
the listen of watch button is now updated automatically.
This means if you switch between listening and viewing you keep in sync
with time.
* Remove sort by rating and date in video search filters
Closes https://github.com/iv-org/invidious/issues/5626
* Remove check of protobug generation of rating and date sort filters in Invidious spec
thin_mode only took in account the query param because
env.get("preferences").as(Preferences).thin_mode returned a boolean and
not a string to be able to compare it with the string `"true"`
* doc: Update HTTP proxy configuration comments
Added information about proxy configuration for YouTube streams.
* Document supported proxy types in config.example.yml
Added note about supported proxy types in configuration.
Image responses contained the following unwanted headers that should not
be passed to the clients:
```
"Cross-Origin-Resource-Policy"
["cross-origin"]
"Cross-Origin-Opener-Policy-Report-Only"
["same-origin; report-to=\"youtube\""]
"Report-To"
["{\"group\":\"youtube\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube\"}]}"]
"Timing-Allow-Origin"
["*"]
```
* Allow downloading via companion
* post request where not proxied for the download companion which made
it impossible to download with the companion enabled
* Re-apply Channel to Channels rename which was pulled in
* Update src/invidious/routes/companion.cr
* doc: better comments for each route
---------
Co-authored-by: Fijxu <fijxu@nadeko.net>
Co-authored-by: Émilien (perso) <4016501+unixfox@users.noreply.github.com>
* Replace deprecated `blocking` property of `Socket`
This replaces the deprecated argument `blocking` and uses
`Socket.set_blocking(fd, value)` instead.
Fixes a warning in the compiler
https://github.com/crystal-lang/crystal/pull/16033
* Upgrade to upstream
* chore: only Socket.set_blocking for > 1.18
---------
Co-authored-by: Emilien <4016501+unixfox@users.noreply.github.com>
Summing the sizes of each cached file every time is very inefficient.
Instead we can simply store the cache size in an constant and increase
it everytime a file is added into the cache.
Running `crystal spec` without a file argument essentially produces one
big program that combines every single spec file, their imports, and
the files that those imports themselves depend on. Most of the types
within this combined program will get ignored by the compiler due to a
lack of any calls to them from the spec files.
But for some types, partially the HTTP module ones, using them within
the spec files will suddenly make the compiler enable a bunch of
previously ignored code. And those code will suddenly require the
presence of additional types, constants, etc. This not only make it
annoying for getting the specs working but also makes it difficult to
isolate behaviors for testing.
The `static_assets_handler_spec.cr` causes this issue and so will be
marked as an isolated spec for now. In the future all of the tests
should be organized into independent groupings similar to how the
Crystal compiler splits their tests into std, compiler, primitives and
interpreter.
Overriding `#call` or patching out `serve_file_compressed` provides
only minimal benefits over the ease of maintenance granted by only
overriding what we need to for the caching behavior.
Kemal's subclass of the stdlib `HTTP::StaticFileHandler` is not as
maintained as its parent, and so misses out on many enhancements and bug
fixes from upstream, which unfortunately also includes the patches for
security vulnerabilities...
Though this isn't necessarily Kemal's fault since the bulk of the stdlib
handler's logic was done in a single big method, making any changes hard
to maintain. This was fixed in Crystal 1.17.0 where the handler
was refactored into many private methods, making it easier for an
inheriting type to implement custom behaviors while still leveraging
much of the pre-existing code.
Since we don't actually use any of the Kemal specific features added by
`Kemal::StaticFileHandler`, there really isn't a reason to not just
create a new handler based upon the stdlib implementation instead which
will address the problems mentioned above.
This PR implements a new handler which inherits from the stdlib variant
and overrides the helper methods added in Crystal 1.17.0 to add the
caching behavior with minimal code changes. Since this new handler
depends on the code in Crystal 1.17.0, it will only be applied on
versions greater than or equal to 1.17.0. On older versions we'll
fallback to the current monkey patched `Kemal::StaticFileHandler`
* dockerfile: compile openssl instead of using the one bundled on the crystal alpine image.
* fix formatting
* CI: add --no-cache to openssl-builder
* CI: add Dockerfile.arm64 version
* add comment why we compile openssl ourselves
* fix wrong position of comment
* oopsie
* verify openssl checksums
* set nproc for openssl make
* use ARG for openssl sha256 checksum
* feat: Add configurable max_request_line_size to handle long URLs
This commit adds a new configuration option `max_request_line_size` that allows
users to increase the HTTP request line size limit. This is particularly useful
for handling very long continuation tokens that can cause 414 (URI Too Long) errors.
Changes:
- Add `max_request_line_size` property to Config class
- Configure Kemal server to use the custom limit if specified
- Document the option in config.example.yml with recommendations
- Add examples in docker-compose.yml for both YAML and env var configuration
The default behavior remains unchanged (8KB limit) unless explicitly configured.
This provides a solution for users experiencing 414 errors without affecting
existing installations.
* Hardcode max_request_line_size to 16384
---------
Co-authored-by: Sunghyun Kim <hello@sunghyun.me>
* fix: restore dmca_content functionality
This restores (or adds) the functionality of the `dmca_content` config
option that at this date, has been unused and makes no effect.
* only disable download widget for dmca video ids
* Remove signature helper completely from Invidious
The official way to reproduce video with Invidious now is by using
Invidious Companion which uses Youtube.JS with a Javascript Interpreter
that can successfully decrypt youtube video URLs.
Sig helper has not been used for a long time, is beyond broken and no
one has plans to fix it and maintain it.
* Remove DECRYPT_FUNCTION and shrink player function
* remove `sp = cfr[sp]`
* Improve message
Posts with a video that has been removed returned
`ProblematicTimelineItem` type which was not taken in account for
community posts.
Now community posts with a broken video will not display an embedded
video.
* Fix 0 view count on related videos
* Remove view_count variable since it's unused by Innertube
* Remove view_count from specs and API
---------
Co-authored-by: Fijxu <fijxu@nadeko.net>
This release primarily marks Invidious companion's ascend out of beta and its stable integration thereof into Invidious!
For those unaware Invidious companion is the successor to the `inv-sig-helper` tool, designed to securely pass YouTube's attestation checks and allow for the efficient retrieval and playback of video streams reliably.
Companion delivers YouTube fixes faster since it’s built on the community-driven [YouTube.js](https://github.com/LuanRT/YouTube.js) project, used by many open source projects such as [FreeTube](https://github.com/FreeTubeApp/FreeTube).
For more information see https://github.com/iv-org/invidious-companion and https://docs.invidious.io/installation/
But companion isn't the only new thing in this release!
Invidious will no longer error out completely as soon as a single item failed to parse in search results, channel pages, etc. Instead it now handles it gracefully by substituting those problematic items with an error card and rendering the page normally.
The player has gained some quality of life features such as being able to choose a default playlist for videos to be added to, or persisting caption appearance settings across the session.
Base Invidious video retrieval without Invidious companion has also been made more stable.
And finally a significant amount of bugs were fixed alongside many other minor improvements.
Co-authored-by: Émilien (perso) <4016501+unixfox@users.noreply.github.com>
* Prevent player microformat from being overwritten by the next microformat
Closes https://github.com/iv-org/invidious/issues/5443
The player microformat is what we need to get the published date,
premiere timestamp, allowed regions and more information of the video.
Youtube introduced a new `microformat.microformatDataRenderer` in the
next endpoint which overwrote the player microformat
`microformat.playerMicroformatRenderer` when merged
* Update src/invidious/videos/parser.cr
Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
---------
Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
This changes its behavior to align with the stdlib variant in that
compression is now delayed till the moment that the server begins to
send a response.
This allows the handler to avoid compressing empty responses,and
safeguards against any double compression of content that may occur
if another handler decides to compressi ts response.
This does however come at the drawback(?) of it now removing
`content-length` headers on requests if it exists; since compression
makes the value inaccurate anyway.
See: https://github.com/crystal-lang/crystal/pull/9625
The exception handling for database connections results in an
`ex` variable which Ameba sees as overshadowing the `ex` used by the
`ex` block arg used to define the HTTP status code 500 handler below.
Although this is a non-issue since the db connection exception handling
will cause Invidious to exit, Ameba's nature as a static checker means
that it isn't aware of this.
The simplest fix without a dirty ameba ignore comment is to rename `ex`
within the Kemal handler block below, since `ex` within a begin rescue
block is a Crystal convention that will also cause Ameba to raise when
not adhered to.
`update_ticker_count` used to use STORAGE_KEY_STREAM to get the number of notifications which is a boolean value, now it uses STORAGE_KEY_NOTIF_COUNT which is an integer
textcaptcha.com seems to be down since April and it does not appear that
service will be restored.
Text captchas can be easily automated using free LLMs, so keeping the
text captcha is more like a gate to create accounts in mass on public
Invidious instances.
It also gives headaches like bots automating account creation to modify
the videos that appear popular page of each instance (since the popular
page is based on the subscriptions of the registered users).
Fixes https://github.com/iv-org/invidious/issues/5295
textcaptcha.com seems to be down since April and it does not appear that service will be restored.
Text captchas can be easily automated using free LLMs, so keeping the text captcha is more like a gate to create accounts in mass on public Invidious instances.
It also gives headaches like bots automating account creation to modify the videos that appear popular page of each instance (since the popular page is based on the subscriptions of the registered users).
Currently, Invidious uses QEMU to build it's ARM64 Invidious image,
which is slow (since we are basically using a virtual machine).
This helps with the speed of building ARM64 binaries for Invidious
on each release/commit.
More information about the public ARM64 runners here:
https://github.com/orgs/community/discussions/148648
CI: Use ARM64 compose file for build-docker-arm64
This commit automates the process of documenting the licenses of
Invidious Javascript files through a compile time macro in the
licenses.ecr template file.
This should hopefully help keep the license documentation up-to-date
and allow extensions like LibreJS to always be able to load the latest
Javascript files of Invidious.
Currently only Invidious's first-party Javascript files are supported.
In the future it should be possible to leverage videojs-dependencies.yml
to automatically document the Javascript licenses for
VideoJS and co. as well.
Fixes https://github.com/iv-org/invidious/issues/5142
add reason why extra_media_csp is after reading user preferences from the database and cookies
set media-src after loading database user preferences
Fixes https://github.com/iv-org/invidious/issues/5095
On some videos, `label` is missing from the video information. Invidious
assumed that the `label` key existed.
Videos with label have this inside `metadataBadgeRenderer`:
```
{"style" => "BADGE_STYLE_TYPE_SIMPLE",
"label" => "4K",
"trackingParams" => "COMDENwwGAoiEwiCrebe6JWNAxWIxz8EHSQRFTU="}
```
but other videos, for some reason, look like this:
```
{"icon" => {"iconType" => "PERSON_RADAR"},
"style" => "BADGE_STYLE_TYPE_SIMPLE",
"trackingParams" => "CM4DENwwGAsiEwiCrebe6JWNAxWIxz8EHSQRFTU="}
```
Remove explicit `self.` from #process of parsers
Remove explicit return tuple in get_issue_template
Fix formatting
Move inline issue template style to stylesheet
Use @id in ProblematicTimelineItem xml repr
Fix naming
Prior to this commit, if even a single item fails to parse Invidious
will throw out an error. This means that even if everything else
on a page can be parsed and rendered without issues, the single
problematic item will cause the entire page to be unusable.
This commit gracefully handles parse errors by catching and then
replacing the problematic item with a new "timeline error" object
that represents the parse error. This will allow the rest of the page
to be rendered and an error card that will replace the location of the
problematic item.
* add support for invidious companion
* redirect latest_version and dash manifest to invidious companion
* fix Shadowing outer local variable `response`
* fixing condition for Content-Security-Policy
* throw error if inv_sig_helper and invidious_companion used same time
* Use sample instead of Random.rand
Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
* Remove debug puts functions
Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
* modify the description for config.example.yaml about invidious companion
* move config checks for invidious companion
* separate invidious_companion logic + better config.yaml config
* fixing "end" misplacement
* fix linting + use .empty?
* crystal handle decompression already by itself
* fix download function when invidious companion used
* fix linting
* invidious companion always used so always add CSP and redirect latest_version
* apply all the suggestions + rework invidious_companion parameter
* format watch.cr
* fix ameba Redundant use of `Object#to_s` in interpolation
* add ability for invidious companion to check request from invidious
* Better document private_url and public_url
* Better doc for invidious_companion_key
* !empty? to present?
* skip proxy for invidious companion
* fixing format
* missing ,
* add companion pooling http
* fix: don't use http proxy when sending requests to companion
* fix: logic where we want to have the invidious logic if companion is not used
* chore: remove baseurl usage from invidious companion
* chore: change from inv-sig-helper to companion for required playback
* fix: use puts + add warning for inv-sig-helper deprecated
---------
Co-authored-by: syeopite <70992037+syeopite@users.noreply.github.com>
The crystal compiler seems to evaluate `require` in an alphabetical way,
so if anyone in the future, wants to add another job and that job is
above `base_job.cr` in alphabetical order, the compiler is going to fail
with `Error: undefined constant: Invidious::Jobs::BaseJob`.
This doesn't fix anything, but it will prevent a future headache.
Invidious does not currently support non-livestream hls playback
Originally, the HLS manifest check was essentially a boolean:
if the HLS manifest field was present, it was assumed to be a
livestream. Some videos include the HLS Manifest but aren't
livestreams.
In the case where they are livestreams, the video contains a videoType
field with the value "Livestream". In the case that they're normal
videos, the videoType is "Video". This is exposed via the
`video.live_now` property.
This commit just checks that `video.live_now` is true before treating
it as a livestream
The automatic instance redirection has the potential to pick
the same instance the user is currently on. This is especially
prevalent when the instance list is limited in number like how it is
today.
This PR checks the domain of the instance and ensures that it is not
the same as the current instane before redirecting the user to it.
Otherwise, it just sends the user to rediret.invidious.io
Originally, the HLS manifest check was essentially a boolean: if the HLS
manifest field was present, it was assumed to be a livestream. Some
videos include the HLS Manifest but aren't livestreams.
In the case where they are livestreams, the video contains a videoType
field with the value "Livestream". In the case that they're normal
videos, the videoType is "Video". This is exposed via the video.live_now
method.
This commit just checks that video.live_now is true before treating it
as a livestream
Kilt is unmaintained and the ECR templating logic has been
natively integrated into Kemal with the issues previously seen
having been resolved.
This commit is mostly a precursor to support the next Kemal
release which will add the ability to create error handlers for
raised exceptions.
See https://github.com/kemalcr/kemal/pull/688
Update Chinese (Traditional Han script) translation
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
The http_proxy section was not commented out in the example config
causing Invidious to error out unless an HTTP proxy was configured.
This problem affects new manual installs in which the example config
is copied to create the actual config Invidious uses
- language id
- language display name
- main/default track
Sort audio formats so that main/default is first (for clients not using dash)
* Note: this should be a non-breaking change; if audio track info is not availablle, the behavior does not change from current
Ameba could be built with an older version of Crystal that follows
a different set of formatting rules than the latest version causing
the Lint/Formatting rule to fail when in actuality the code is actually
compliant with the formatting rules in the latest version of Crystal
Use the WEB client when a potoken is configured, otherwise try with Android
test suite if there is no potoken configured.
This PR reverts some of the changes made in 4928
Related to 4734
This pull request fixes the parsing for the 'live_now' and 'premiere_timestamp'
variables so that they work without the 'microformat' data being present.
Related to 4929
Change explanation, courtesy of iBicha:
The \n is basically a decimal 10, which is 1010 binary. That is a field number
1, and a wire type 2 (length-delimited). Then the $ is a decimal 36, which is
exactly the length of 00000000-0000-0000-0000-000000000000.
So both objects end up being encoded into the same data.
This PR add an MT option to the Makefile. When make is invoked with 'MT=1',
the 'preview_mt' flag is passed to the Crystal compiler.
It doesn't mean that invidious fully supports multi-threading, but at least
it provides an easy way for trying that out.
No related issue.
Fijxu have been using it for more than 3 weeks on their instance and
they report that it works really well.
This only works if 'inv_sig_helper' itself crashes and restarts (via systemd
or docker restart policy) but it will not work if 'inv_sig_helper' hangs and
stops responding to invidious (but this is an issue with 'inv_sig_helper',
not Invidious).
Closes issue 4926
Theoretically this should improve memory usage and performance by quite a bit
as we aren't creating a new HTTP::Client and in a turn a new connection for
every image we request from YouTube.
Closes issue 4009
Use the proper URL argument when transforming youtu.be URLs to their
youtube.com equivalents.
Thanks to Tuhgy on the fediverse for reporting this!
No related issue
In Crystal, handling multi-byte sequences in UTF-8 requires understanding that
slicing by bytes can lead to invalid sequences if the slicing isn't aligned
with character boundaries. In this case, attempting to slice a string by bytes
can cut through multi-byte UTF-8 sequences, leading to invalid sequences.
To avoid this, strings should be sliced based on characters rather than bytes.
Fixes issue 4886
This PR makes it possible to display badges in the search results for third
party Invidious applications (ex: FreeTube)
See also: https://github.com/FreeTubeApp/FreeTube/pull/5590
No related issue
This PR adds the error message to the "search on Github" link located on
the crash page, so that the search bar is already filled and the issues
filtered when the user opens said link.
As seen with #4584 and other critical problems, duplicate issues end up
unnecessarily flooding the issue reports. While this change won't entirely
stop this behavior, this will help the user to easily identify if the error
they have received has been reported yet and discourage them from creating
a duplicate (hopefully...).
No associated issue was open
This PR adds a configuration option to control the preloading of video data on
page load with the HTML5 'preload'[1] attribute on the `<video>` element.
The option is enabled by default, meaning that the `preload` attribute's value
will be 'auto'. If users want to prevent preloading of video data, they
can disable the option, which will set the attribute value to 'none'.
[1](https://www.w3schools.com/tags/att_video_preload.asp)
Closes issue 4110
The automatic instance redirection implemented in #1940 fetches a new list of
instances each time someone queries the /redirect endpoint. This is extremely
inefficient...
This PR optimizes all that into a background job that only fetches a single
list every 30 minutes. This should performance quite a bit.
No related issue was opened.
Although available this method should be discouraged as it requires
an extra request to YouTube to get caption data in order to
map label -> language code and auto-generated status, which are needed
to fetch transcripts.
The HTTP::Client created via `make_client` is affected by the
force_resolve configuration option. However, api.invidious.io
does not support ipv6 and as such any request with ipv6 to
api.invidious.io will instead raise.
Directly calling the HTTP::Client will ignore the force_resolve option
allowing requests to go through ipv4 when needed.
Fix#4110 by adding an option to control the preloading of video data on
page load. If disabled ("false"), the browser will not preload any video
data until the user explicitly hits the "Play" button.
If enabled ("true"), the default behavior will be used, which means the
browser decides how much of the video will be preloaded.
* Use the search function to check if there is already an issue open for your problem!
* Read the FAQ: https://docs.invidious.io/faq/!
* Use the search function to check if there is already an issue open for your problem: https://github.com/search?q=repo%3Aiv-org%2Finvidious+replace+me+with+your+bug&type=issues!
MAKE SURE TO FOLLOW THE TWO STEPS ABOVE BEFORE REPORTING A BUG. A BUG THAT ALREADY EXIST WILL IMMEDIATELY CLOSED.
If you want to suggest a new feature please use "Feature request" instead
If you want to suggest an enhancement to an existing feature please use "Enhancement" instead
stale-issue-message:'This issue has been automatically marked as stale and will be closed in 30 days because it has not had recent activity and is much likely outdated. If you think this issue is still relevant and applicable, you just have to post a comment and it will be unmarked.'
stale-pr-message:'This pull request has been automatically marked as stale and will be closed in 30 days because it has not had recent activity and is much likely abandoned or outdated. If you think this pull request is still relevant and applicable, you just have to post a comment and it will be unmarked.'
stale-issue-label:"stale"
stale-pr-label:"stale"
ascending:true
# Never mark feature requests/enhancements as stale
This release hardens the Invidious companion pipeline and cleans up a long list of UI papercuts. Companion downloads now work end-to-end, CSP headers and check identifiers are generated once and reused, proxy responses strip stray headers, and the final traces of the legacy signature helper are gone so the helper can be rolled out safely.
Livestream navigation, playlists, and channel metadata also see overdue fixes: Trending once again lists livestreams, "Watch on YouTube" buttons stop jumping to arbitrary timestamps, playlist imports/API calls handle missing data, and channel pages now display creator pronouns and playlist thumbnails. Deployments benefit from compiling OpenSSL into docker images to mitigate a long-standing memory leak observed with Alpine-provided OpenSSL, Crystal pinned back to 1.16.3 for docker and OCI builds, a rewritten static file handler, clarified README/HTTP proxy/unix socket docs, and dozens of smaller cleanups.
### New features & important changes
#### For Users
- Livestream experiences are restored: Trending shows livestreams again, the gaming feed remains accessible, and "Watch on YouTube" links stop carrying stale timestamps (#5480, #5555, #5481)
- Channel and playlist metadata is richer thanks to pronoun support, topic playlist thumbnails, and accurate related video counts (#5617, #5616, #5446)
- Downloads get smoother because download actions are URL-safe and downloads can flow through Invidious companion when available (#5367, #5561)
- Users see clearer feedback with Erroneous CAPTCHA messages, DMCA controls restored, and a footer link pointing at the current release (#5508, #5228, #4702)
#### For instance owners
- Companion integration is sturdier: CSP is generated once, check identifiers persist, and the helper hyperlink is fixed (#5497, #5575, #5491)
- Runtime and packaging updates pin docker/OCI builds to Crystal 1.16.3, bring an optional Crystal 1.18.2 + Alpine 3.23 image, and compile OpenSSL from source to mitigate the memory leak seen with Alpine-provided OpenSSL (#5604, #5577, #5574, #5441)
- Configuration docs saw polish with unix socket instructions, refreshed HTTP proxy comments, and corrected README commands (#5347, #5586, #5607)
- Server stability improves via a larger `max_request_line_size` that is required to be able to access some next pages of Youtube channels videos and a rewritten static file handler (#5566, #5338)
#### For developers
- Top-level constants moved into dedicated modules, preferences handling was cleaned up, and the legacy signature helper is finally removed (#5596, #5450, #5550)
- Crystal API updates replaced the deprecated `Socket#blocking` property and restored the shard target plus SPDX license metadata (#5538, #5608, #5552)
- CI/tooling stayed current with newer GitHub Actions, install-crystal releases, and cache/checkout bumps (#5569, #5544, #5530, #5499)
### Bugs fixed
#### User-side
- Playlist importer edge cases, playlist API author URLs, and channel continuation tokens now handle empty values without crashing (#4787, #5618, #5614)
- Thin mode community posts, posts that reference unavailable videos, and DMCA content toggles work again (#5567, #5549, #5228)
- URL encoding fixes in the download widget and socket API updates prevent regressions when upgrading Crystal (#5367, #5538)
### Full list of pull requests merged since the last release (newest first)
* refactor: Move top level constants to it's own modules (https://github.com/iv-org/invidious/pull/5596, by @Fijxu)
* pages/watch: URL encode 'action' in download widget (https://github.com/iv-org/invidious/pull/5367, by @SamantazFox)
* Document use of unix sockets for `db` (https://github.com/iv-org/invidious/pull/5347, by @Fijxu)
* Generate companion CSP only once to reuse it (https://github.com/iv-org/invidious/pull/5497, by @Fijxu)
* Fix youtube CSV playlist importer (https://github.com/iv-org/invidious/pull/4787, by @ThatMatrix)
* Playlist API: return empty author url if ucid is empty (https://github.com/iv-org/invidious/pull/5618, by @radmorecameron)
* Channels: parse pronouns and display them on channel page (https://github.com/iv-org/invidious/pull/5617, by @radmorecameron)
* playlist: parse playlist thumbnails for topic autogenerated playlists (https://github.com/iv-org/invidious/pull/5616, by @radmorecameron)
* fix: add missing embedded protobuf message in continuation token for channel videos (https://github.com/iv-org/invidious/pull/5614, by @Fijxu)
* Update shard.yml to include target that was removed in commit 9d54cf9 (https://github.com/iv-org/invidious/pull/5608, by @Harm133)
* chore: Do not convert thin_mode preference to string to compare it in before_all (https://github.com/iv-org/invidious/pull/5568, by @Fijxu)
* Fix thin_mode preference for channel community page (https://github.com/iv-org/invidious/pull/5567, by @Fijxu)
* Fix commit command in README instructions, as per #5606 (https://github.com/iv-org/invidious/pull/5607, by @kirisakow)
* Revert "Bump crystallang/crystal from 1.16.3-alpine to 1.19.0-alpine in /docker" (https://github.com/iv-org/invidious/pull/5604, by @unixfox)
* Bump crystallang/crystal from 1.16.3-alpine to 1.19.0-alpine in /docker (https://github.com/iv-org/invidious/pull/5603, by @dependabot[bot])
* doc: Update HTTP proxy configuration comments (https://github.com/iv-org/invidious/pull/5586, by @unixfox)
* Strip unwanted headers from response headers in images and videoplayback (https://github.com/iv-org/invidious/pull/5595, by @Fijxu)
* Generate companion check id one time and add missing companion check id on captions (https://github.com/iv-org/invidious/pull/5575, by @Fijxu)
* Downgrade Crystal to 1.16.3 in OCI (https://github.com/iv-org/invidious/pull/5577, by @Fijxu)
* Allow downloading via companion (https://github.com/iv-org/invidious/pull/5561, by @JeroenBoersma)
* chore: crystal 1.8.2 + alpine 3.23 (https://github.com/iv-org/invidious/pull/5574, by @unixfox)
* Replace deprecated `blocking` property of `Socket` (https://github.com/iv-org/invidious/pull/5538, by @Fijxu)
* Replace `Kemal::StaticFileHandler` with direct subclass of stdlib `HTTP::StaticFileHandler` on Crystal >= 1.17.0 (https://github.com/iv-org/invidious/pull/5338, by @syeopite)
* dockerfile: compile openssl instead of using the one bundled on the crystal alpine image. (https://github.com/iv-org/invidious/pull/5441, by @Fijxu)
* Bump actions/cache from 4 to 5 (https://github.com/iv-org/invidious/pull/5569, by @dependabot[bot])
* Set Kemal `max_request_line_size` to 16384 for large channel continuation query parameters. (https://github.com/iv-org/invidious/pull/5566, by @Fijxu)
* Add link to GitHub release/tag/commit in footer (https://github.com/iv-org/invidious/pull/4702, by @shaedrich)
* Display "Erroneous CAPTCHA" for invalid captchas (https://github.com/iv-org/invidious/pull/5508, by @Fijxu)
* Fix channel name overflow (https://github.com/iv-org/invidious/pull/5553, by @Fijxu)
* Fix trending page by leaving livestream and gaming trending pages (https://github.com/iv-org/invidious/pull/5555, by @Fijxu)
* fix: restore dmca_content functionality (https://github.com/iv-org/invidious/pull/5228, by @Fijxu)
* Remove signature helper completely from Invidious (https://github.com/iv-org/invidious/pull/5550, by @Fijxu)
* Fix community posts when there is a unavailable video in a post (https://github.com/iv-org/invidious/pull/5549, by @Fijxu)
* chore: Update shard.yml to use SPDX license identifier (https://github.com/iv-org/invidious/pull/5552, by @Fijxu)
* Store `preferences` in a variable when reused and rename `prefs` to `preferences` (https://github.com/iv-org/invidious/pull/5450, by @Fijxu)
* Bump actions/checkout from 5 to 6 (https://github.com/iv-org/invidious/pull/5544, by @dependabot[bot])
* Bump crystal-lang/install-crystal from 1.8.3 to 1.9.1 (https://github.com/iv-org/invidious/pull/5530, by @dependabot[bot])
* Fix 0 view count on related videos section (https://github.com/iv-org/invidious/pull/5446, by @shiny-comic)
* Prevent timestamp from being set for Livestreams on "Watch on Youtube" links (https://github.com/iv-org/invidious/pull/5481, by @Fijxu)
* Add Livestreams to trending page (https://github.com/iv-org/invidious/pull/5480, by @Fijxu)
* Fix button overflow (https://github.com/iv-org/invidious/pull/5452, by @Fijxu)
* Bump crystal-lang/install-crystal from 1.8.2 to 1.8.3 (https://github.com/iv-org/invidious/pull/5499, by @dependabot[bot])
* Fixed broken companion hyperlink (https://github.com/iv-org/invidious/pull/5491, by @ndsvw)
## v2.20250913.0
### Wrap-up
This release primarily marks Invidious companion's ascend out of beta and its stable integration thereof into Invidious!
For those unaware Invidious companion is the successor to the `inv-sig-helper` tool, designed to securely pass YouTube's attestation checks and allow for the efficient retrieval and playback of video streams reliably.
Companion delivers YouTube fixes faster since it’s built on the community-driven [YouTube.js](https://github.com/LuanRT/YouTube.js) project, used by many open source projects such as [FreeTube](https://github.com/FreeTubeApp/FreeTube).
For more information see https://github.com/iv-org/invidious-companion and https://docs.invidious.io/installation/
But companion isn't the only new thing in this release!
Invidious will no longer error out completely as soon as a single item failed to parse in search results, channel pages, etc. Instead it now handles it gracefully by substituting those problematic items with an error card and rendering the page normally.
The player has gained some quality of life features such as being able to choose a default playlist for videos to be added to, or persisting caption appearance settings across the session.
Base Invidious video retrieval without Invidious companion has also been made more stable.
And finally a significant amount of bugs were fixed alongside many other minor improvements.
### New features & important changes
#### For Users
- DASH is now enabled by default due to YouTube's removal of the 720p non-dash streams
- Javascript licencing info has been added to all of Invidious' scripts, restoring full compatibility with LibreJS
- There is no longer an option for a text captcha during registration due to the shutdown (presumably) of the upstream service
- Parse errors in feeds will no longer render the entire feed unusable and instead will substitute only the broken items with error cards
- Keyboard shortcuts have been added to configure caption styles:
-`-`,`=` can be used to change the font size
-`o` can be used to cycle the opacity of the caption text
-`w` can be used to cycle the opacity of the caption box
- Caption styles changed through the VideoJS menu will now persist
- You can now choose a default playlist to add videos to instead of needing to manually select one each time
#### For instance owners
- Invidious companion support has been added to replace the deprecated inv-sig-helper
- **DASH is now the default resolution! Please ensure that your instances can withstand the significantly higher bandwidth usage or manually configure your instance to use non-dash streams by default**
- Invidious will now warn when it is unable to connect to the database instead of failing silently
- **The text captcha during registration has been removed due to the shutdown (presumably) of the upstream service**
#### For developers
- Dependabot has been added to keep Github Actions and Docker dependencies up-to-date.
- CI version matrix has been bumped to the latest patch release for each minor version
- The versions of Crystal that we test in CI/CD are now: `1.12.2`, `1.13.3`, `1.14.1`, `1.15.1`, `1.16.3`
-`Kilt` is no longer a dependency of Invidious
- The ARM64 docker image builds (and the test CI) has been changed to use Github's ARM64 runner instead of QEMU
- **An "error" JSON object can now be returned in various API responses in-place of an item that has failed to parse**:
```json
{
"type": "parse-error",
"errorMessage": "...",
"errorBacktrace": "..."
}
```
### Bugs fixed
#### User-side
- Livestream will now be properly proxied again allowing playback from the UI
- The proxy video preference for logged-in users will no longer get ignored when a default value is set by the instance
- Fixes the missing `label` key error on select search results and other feeds
- Invidious will no longer strip out spaces from search queries when navigating back from the preferences page
- Restores functionality to the `subscriptions:true` search keyword
- The channel RSS feeds will no longer have an empty title
- Individual community posts can be viewed again
- The playlists tab of channels can be viewed again
- Fix incorrect dates, region, etc of videos
- Various minor fixes were made to how video info is extracted in setups without Invidious companion to improve resiliency and chances of success
- Fix issue where the notification count becomes `TRUE` rather than an actual number
#### For instance owners
- Fixed a minor typo in config.example.yml (`effet` -> `effect`)
#### For developers
- The docker image test CI will now properly check whether Invidious has started
### Full list of pull requests merged since the last release (newest first)
* Add Invidious companion support (https://github.com/iv-org/invidious/pull/4985, by @unixfox)
* Bump shards.yml version to dev version (https://github.com/iv-org/invidious/pull/5206, by @syeopite)
* chore: enforce 16 characters for invidious_companion_key (https://github.com/iv-org/invidious/pull/5220, by @unixfox)
* chore: set dash by default (https://github.com/iv-org/invidious/pull/5216, by @unixfox)
* Fix minor casing issues in brand names (https://github.com/iv-org/invidious/pull/5258, thanks @efb4f5ff-1298-471a-8973-3d47447115dc)
* feat: route to invidious companion on downloads (https://github.com/iv-org/invidious/pull/5224, by @alexmaras)
* Fix proxying live DASH streams (https://github.com/iv-org/invidious/pull/4589, thanks @absidue)
* Reflect companion secret character limit in example config comment (https://github.com/iv-org/invidious/pull/5269, thanks @Vyquos)
* chore: Add dependabot for docker and github actions (https://github.com/iv-org/invidious/pull/5285, by @unixfox)
* Bump actions/stale from 8 to 9 (https://github.com/iv-org/invidious/pull/5291, thanks @dependabot[bot])
* Bump actions/cache from 3 to 4 (https://github.com/iv-org/invidious/pull/5289, thanks @dependabot[bot])
* Bump alpine from 3.20 to 3.21 in /docker (https://github.com/iv-org/invidious/pull/5288, thanks @dependabot[bot])
* Bump docker/build-push-action from 5 to 6 (https://github.com/iv-org/invidious/pull/5287, thanks @dependabot[bot])
* Bump crystal-lang/install-crystal from 1.8.0 to 1.8.2 (https://github.com/iv-org/invidious/pull/5286, thanks @dependabot[bot])
* Bump crystallang/crystal from 1.12.2-alpine to 1.16.2-alpine in /docker (https://github.com/iv-org/invidious/pull/5290, thanks @dependabot[bot])
* Bump crystallang/crystal from 1.16.2-alpine to 1.16.3-alpine in /docker (https://github.com/iv-org/invidious/pull/5301, thanks @dependabot[bot])
* CI: Bump Crystal version matrix (https://github.com/iv-org/invidious/pull/5293, by @Fijxu)
* fix(typo): 'Salect' -> 'Select' (https://github.com/iv-org/invidious/pull/5242, by @Fijxu)
* fix: set CSP header after setting preferences of registered users (https://github.com/iv-org/invidious/pull/5275, by @Fijxu)
* fix: safely access "label" key (https://github.com/iv-org/invidious/pull/5282, by @Fijxu)
* Add missing javascript licenses (https://github.com/iv-org/invidious/pull/5292, by @Fijxu)
* Add Javascript licence information automatically (https://github.com/iv-org/invidious/pull/5297, by @syeopite)
* Remove text captcha due to textcaptcha.com being down (https://github.com/iv-org/invidious/pull/5308, by @Fijxu)
* Release versioning maintenance (https://github.com/iv-org/invidious/pull/5310, by @syeopite)
* Update Kemal to 1.6.0 and remove Kilt (https://github.com/iv-org/invidious/pull/5120, by @syeopite)
* Translations update from Hosted Weblate (https://github.com/iv-org/invidious/pull/5192, thanks @weblate)
* require base_job before the other jobs (https://github.com/iv-org/invidious/pull/5194, by @Fijxu)
* Handle parse errors gracefully on timeline items (https://github.com/iv-org/invidious/pull/5196, by @syeopite)
* fix: do not strip '+' character from referer (https://github.com/iv-org/invidious/pull/5276, by @Fijxu)
* fix: pass user to `query.process` if present. (https://github.com/iv-org/invidious/pull/5277, by @Fijxu)
* Add missing xml.text on "title" element for channels RSS (https://github.com/iv-org/invidious/pull/5320, by @Fijxu)
* Remove `@iv-org/developers` from codeowners (https://github.com/iv-org/invidious/pull/5314, by @syeopite)
* Make base-Invidious video info extraction more resilient (https://github.com/iv-org/invidious/pull/5312, by @syeopite)
* Bump actions/checkout from 4 to 5 (https://github.com/iv-org/invidious/pull/5415, thanks @dependabot[bot])
This release brings the long awaited feature of supporting multiple audio tracks in a video, some bug fixes and UX improvements, and many other things primarily oriented to self-hosting instances, and developers using the API.
The `Community` channel tab has been replaced by `Posts` in light of YouTube changes, but the URL remains the same.
Tamil is now available as an interface language
Automatic instance redirects will no longer have the chance to annoyingly redirect to the same instance you're on.
Due to their requirements for video playback, Invidious will log warning messages when either inv-sig-helper, `po_token` or `visitor_data` is not configured
Invidious is now able to listen through a UNIX socket
User notifications are now batched for each channel
**The minimum Crystal version supported by Invidious now `1.12.0`**
### New features & important changes
#### For users
* Invidious now supports videos with multiple audio tracks allowing you to select which one you want to hear with!
* Channel pages now have a proper previous page button
* RSS feeds for channels will no longer contain the channel's profile picture
* Support for channel `courses` page has been added
* `Community` tabs has been replaced with `Posts` to comply with YouTube changes
* Tamil is now an available interface language.
#### For instance owners
* Invidious is now able to listen on a UNIX socket
* User notifications are now batched by channels, significantly reducing database load.
* **`1.12.0` is now the oldest Crystal version that Invidious supports**
* The example config will no longer force an http proxy to be configured
* Invidious will now warn when any top-level config option must be set to a custom value, instead of just `HMAC_KEY`
* Due to their requirements for video playback, Invidious will log warning messages when either inv-sig-helper, `po_token` or `visitor_data` is not configured
#### For developers
* Invidious is now compliant to Crystal 1.15 formatting rules, which are incompatible with earlier versions.
* `/api/v1/transcripts/{id}` has been added to the API to allow for fetching the transcripts for a video. The arguments are the same as the captions endpoint.
* `author_thumbnail` field has been added to videos in the various paged api endpoints
* `published` field has been added to the API response for a video's related videos.
* Docker builds now uses the Crystal compiler cache, reducing build times on repeated builds significantly.
* Invidious ajax action handlers has undergone a clean up and may face compatibility issues with code that depends on these endpoints.
* The versions of Crystal that we test in CI/CD are now: `1.12.1`, `1.13.2`, `1.14.0`, `1.15.0`
### Bugs fixed
#### User-side
* Local video listen mode is now preserved when clicking on a video in the sidebar playlist widget
* Automatic instance redirects will no longer redirect to the same instance the user is on
* Fix some thumbnails responses returning 404
* Videos: Fix missing host parameter on playback URLs when `local=true`
* Fix HLS being used for non-livestream videos
* Fix timeupdate event errors when required elements are missing
* User: Ensure IO is properly closed when importing NewPipe subscriptions
#### For instance owners
* Fix http proxy configuration being forced by the standard example config
#### API
* `/api/v1/videos/{id}` will no longer return an occasional empty JSON response
### Full list of pull requests merged since the last release (newest first)
* Make Invidious compliant to Crystal 1.15 formatting rules (https://github.com/iv-org/invidious/pull/5014, by @syeopite)
* Remove formatter check on container workflows (https://github.com/iv-org/invidious/pull/5153, by @syeopite)
* Videos: Fix missing host parameter on playback URLs when `local=true` (https://github.com/iv-org/invidious/pull/4992, by @SamantazFox)
* Remove stdlib override for proxy initialization (https://github.com/iv-org/invidious/pull/5065, by @syeopite)
* Add support for author thumbnails in search api for videos (https://github.com/iv-org/invidious/pull/5072, thanks @ChunkyProgrammer)
* Skip route if resp got closed by before handlers (https://github.com/iv-org/invidious/pull/5073, by @syeopite)
* Fix video thumbnails in mixes (https://github.com/iv-org/invidious/pull/5116, thanks @iBicha)
* CI: Drop support for versions prior to 1.12 and add 1.15.0 (https://github.com/iv-org/invidious/pull/5148, by @syeopite)
* [Continuing #5094] Set language info for dash audio streams and sort (https://github.com/iv-org/invidious/pull/5149, thanks @giuliano-macedo)
* Warn when any top-level config is "CHANGE_ME!!" (https://github.com/iv-org/invidious/pull/5150, by @syeopite)
* Comment out http_proxy in example config (https://github.com/iv-org/invidious/pull/5151, by @syeopite)
* API: Add a 'published' video parameter for related videos (https://github.com/iv-org/invidious/pull/4149, thanks @RadoslavL)
* Ensure IO is properly closed when importing NewPipe subscriptions (https://github.com/iv-org/invidious/pull/4346, thanks @ChunkyProgrammer)
* Carry over audio-only mode in playlist links (https://github.com/iv-org/invidious/pull/4784, thanks @krystof1119)
* Routes: Clean ajax actions handlers (https://github.com/iv-org/invidious/pull/5036, by @SamantazFox)
* Frontend: Add a first page and previous page buttons for channel navigation (https://github.com/iv-org/invidious/pull/4123, thanks @RadoslavL)
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.":"Hallo! Anscheinend haben Sie JavaScript deaktiviert. Klicken Sie hier um Kommentare anzuzeigen, beachten sie dass es etwas länger dauern kann um sie zu laden.",
"Premieres `x`":"Premiere `x`",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.":"Hallo! Anscheinend hast du JavaScript deaktiviert. Klicke hier, um Kommentare anzuzeigen, beachte, dass es etwas länger dauern kann, um sie zu laden.",
"crash_page_search_issue":"Nach <a href=\"`x`\">bereits gemeldeten Bugs auf GitHub</a> gesucht haben",
"crash_page_report_issue":"Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffnen Sie bitte ein neues Problem (issue) auf Github</a> (vorzugsweise auf Englisch) und fügen Sie den folgenden Text in Ihre Nachricht ein (bitte übersetzen Sie diesen Text NICHT):",
"crash_page_search_issue":"Nach <a href=\"`x`\">bereits gemeldeten Bugs auf GitHub</a> gesucht hast",
"crash_page_report_issue":"Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffne bitte ein neues Problem (issue) auf GitHub</a> (vorzugsweise auf Englisch) und füge den folgenden Text in deine Nachricht ein (bitte übersetze diesen Text NICHT):",
"error_video_not_in_playlist":"Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>",
"error_video_not_in_playlist":"Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicke hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>",
"timeline_parse_error_placeholder_heading":"Element kann nicht geparsed werden",
"timeline_parse_error_placeholder_message":"Invidious ist beim Parsen dieses Elements auf einen Fehler gestossen. Für weitere Informationen siehe unten:"
"preferences_watch_history_label":"Habilitar historial de reproducciones: ",
"search_message_no_results":"No se han encontrado resultados.",
@@ -478,9 +478,9 @@
"tokens_count_0":"{{count}} token",
"tokens_count_1":"{{count}} tokens",
"tokens_count_2":"{{count}} tokens",
"search_message_use_another_instance":"También puede <a href=\"`x`\">buscar en otra instancia</a>.",
"search_message_use_another_instance":"También puedes <a href=\"`x`\">buscar en otra instancia</a>.",
"Popular enabled: ":"¿Habilitar la sección popular? ",
"error_video_not_in_playlist":"El video que solicitaste no existe en esta lista de reproducción. <a href=\"`x`\">Haz clic aquí para acceder a la página de inicio de la lista de reproducción.</a>",
"error_video_not_in_playlist":"El vídeo que has solicitado no existe en esta lista de reproducción. <a href=\"`x`\">Haz clic aquí para acceder a la página de inicio de la lista de reproducción.</a>",
"channel_tab_streams_label":"Directos",
"channel_tab_channels_label":"Canales",
"channel_tab_shorts_label":"Cortos",
@@ -500,7 +500,7 @@
"generic_button_cancel":"Cancelar",
"generic_button_rss":"RSS",
"channel_tab_podcasts_label":"Podcasts",
"channel_tab_releases_label":"Publicaciones",
"channel_tab_releases_label":"Lanzamientos",
"generic_channels_count_0":"{{count}} canal",
"generic_channels_count_1":"{{count}} canales",
"generic_channels_count_2":"{{count}} canales",
@@ -513,5 +513,13 @@
"The Popular feed has been disabled by the administrator.":"El feed Popular ha sido desactivado por el administrador.",
"carousel_slide":"Diapositiva {{current}} de {{total}}",
"carousel_skip":"Saltar el carrusel",
"carousel_go_to":"Ir a la diapositiva `x`"
"carousel_go_to":"Ir a la diapositiva `x`",
"preferences_preload_label":"Precargar datos del vídeo: ",
"crash_page_search_issue":"otsinud <a href=\"`x`\">GitHubist sarnaseid ja juba teaeatud vigu</a>",
"crash_page_report_issue":"Kui ükski ülaltoodud võimalustest seda viga ei lahendanud, siis palun <a href=\"`x`\">koosta GitHubis meie veahalduses uus veateade</a> (soovitavalt inglise keeles) ja lisa sinnakogu järgnev tekst (palun ÄRA tõlgi seda teksti):",
"Import YouTube watch history (.json)":"درونبرد تاریخچهٔ تماشای یوتیوب (.json)",
"crash_page_you_found_a_bug":"به نظر میرسد که ایرادی در Invidious پیدا کردهاید!",
"channel_tab_podcasts_label":"پادکستها",
"channel_tab_streams_label":"پخش زندهها",
@@ -485,10 +483,10 @@
"channel_tab_playlists_label":"فهرستهای پخش",
"channel_tab_channels_label":"کانالها",
"error_video_not_in_playlist":"ویدیوی درخواستی معلق به این فهرست پخش نیست. <a href=\"`x`\">کلیک کنید تا به صفحهٔ اصلی فهرست پخش بروید.</a>",
"Add to playlist":"به لیست پخش افزوده شود",
"Add to playlist":"افزودن به فهرست پخش",
"Answer":"پاسخ",
"Search for videos":"جست و جو برای ویدیوها",
"Add to playlist: ":"افزودن به لیست پخش ",
"Search for videos":"جستوجو برای ویدیوها",
"Add to playlist: ":"افزودن به فهرست پخش ",
"The Popular feed has been disabled by the administrator.":"بخش ویدیوهای پرطرفدار توسط مدیر غیرفعال شده است.",
"carousel_slide":"اسلاید {{current}} از {{total}}",
"carousel_skip":"رد شدن از گرداننده",
@@ -496,5 +494,12 @@
"crash_page_search_issue":"دنبال <a href=\"`x`\"> گشتیم بین مشکلات در گیت هاب </a>",
"crash_page_report_issue":"اگر هیچ یک از روش های بالا کمکی نکردند لطفا <a href=\"`x`\"> (ترجیحا به انگلیسی) یک سوال جدید در گیت هاب بپرسید و </a> طوری که سوالتون شامل متن زیر باشه:",
"channel_tab_releases_label":"آثار",
"toggle_theme":"تغییر وضعیت تم"
"toggle_theme":"تغییر وضعیت تم",
"preferences_preload_label":"پیش بار کردن دادههای ویدیو: ",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.":"Hallo! Anschinend hesch du JavaScript deaktiviert. Klick da, zum Kommentär aazzeige, beacht, dass es chli länger duure cha, zum sie z lade.",
"crash_page_report_issue":"Wenn all das nöd ghulfe het, <a href=\"`x`\">öffne bitte es neus Problem (issue) uf GitHub</a> (vorzugswiis uf Englisch) und füeg de folgendi Text i dini Nachricht ii (bitte übersetz de Text NÖD):",
"error_video_not_in_playlist":"S agforderete Video existiert nöd i dere Widergabelischte. <a href=\"`x`\">Klick da, zum zur Startsiite vo de Widergabelischte z cho.</a>",