Move to mkdocs-material (#207)

This commit is contained in:
TheFrenchGhosty 2022-03-08 14:33:39 +00:00 committed by GitHub
parent 96122bed77
commit a1902ff41d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
91 changed files with 26607 additions and 37 deletions

895
docs/API.md Normal file
View file

@ -0,0 +1,895 @@
---
title: API
description:
published: true
date: 2021-05-23T16:58:08.783Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:38:53.557Z
---
### Language
All endpoints that return a JSON body support `&hl=LANGUAGE` for translating fields into the desired language. A list of languages are provided in [List of URL parameters](./List-of-URL-parameters).
### Pretty
All endpoints that return a JSON body support `&pretty=1` for printing the response as formatted JSON.
### Fields
All endpoints that return a JSON body support the [fields API](https://developers.google.com/youtube/v3/getting-started#fields) for specifying desired fields to reduce bandwidth consumption. This can be used by adding `&fields=FIELDS` with the desired fields, for example [`/api/v1/videos/aqz-KE-bpKQ?fields=videoId,title,description&pretty=1`](https://invidio.us/api/v1/videos/aqz-KE-bpKQ?fields=videoId,title,description&pretty=1).
##### GET `/api/v1/stats`
> Schema:
```javascript
{
"version": String,
"software": {
"name": "invidious",
"version": String,
"branch": String
},
"openRegistrations": Bool,
"usage": {
"users": {
"total": Int32,
"activeHalfyear": Int32,
"activeMonth": Int32
}
},
"metadata": {
"updatedAt": Int64,
"lastChannelRefreshedAt": Int64
}
}
```
##### GET `/api/v1/videos/:id`
> Schema:
```javascript
{
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"description": String,
"descriptionHtml": String,
"published": Int64,
"publishedText": String,
"keywords": Array(String),
"viewCount": Int64,
"likeCount": Int32,
"dislikeCount": Int32,
"paid": Bool,
"premium": Bool,
"isFamilyFriendly": Bool,
"allowedRegions": Array(String),
"genre": String,
"genreUrl": String,
"author": String,
"authorId": String,
"authorUrl": String,
"authorThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
],
"subCountText": String,
"lengthSeconds": Int32,
"allowRatings": Bool,
"rating": Float32,
"isListed": Bool,
"liveNow": Bool,
"isUpcoming": Bool,
"premiereTimestamp": Int64?,
"hlsUrl": String?,
"adaptiveFormats": [
{
"index": String,
"bitrate": String,
"init": String,
"url": String,
"itag": String,
"type": String,
"clen": String,
"lmt": String,
"projectionType": Int32,
"container": String,
"encoding": String,
"qualityLabel": String?,
"resolution": String?
}
],
"formatStreams": [
{
"url": String,
"itag": String,
"type": String,
"quality": String,
"container": String,
"encoding": String,
"qualityLabel": String,
"resolution": String,
"size": String
}
],
"captions": [
{
"label": String,
"languageCode": String,
"url": String
}
],
"recommendedVideos": [
{
"videoId": String,
"title": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"author": String,
"lengthSeconds": Int32,
"viewCountText": String
}
]
}
```
Parameters:
```
region: ISO 3166 country code (default: "US")
```
##### GET `/api/v1/annotations/:id`
Parameters:
```
source: "archive", "youtube" (default: "archive")
```
Returns annotation XML from YouTube's `/annotations_invideo` endpoint. Alternatively it provides access to legacy annotation data using [this collection](https://archive.org/details/youtubeannotations) on archive.org.
##### GET `/api/v1/comments/:id`
> Schema:
```javascript
{
"commentCount": Int32?,
"videoId": String,
"comments": [
{
"author": String,
"authorThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
],
"authorId": String,
"authorUrl": String,
"isEdited": Bool,
"content": String,
"contentHtml": String,
"published": Int64,
"publishedText": String,
"likeCount": Int32,
"commentId": String,
"authorIsChannelOwner": Bool,
"creatorHeart": {
"creatorThumbnail": String,
"creatorName": String
}?,
"replies": {
"replyCount": Int32,
"continuation": String
}?
}
],
"continuation": String?
}
```
Parameters:
```
sort_by: "top", "new" (default: top)
source: "youtube", "reddit" (default: youtube)
continuation: String
```
##### GET `/api/v1/captions/:id`
> Schema:
```javascript
{
"captions": [
{
"label": String,
"languageCode": String,
"url": String
}
]
}
```
Parameters:
```
label: String
lang: String
tlang: String
region: ISO 3166 country code (default: "US")
```
A request with `label` will return the selected captions in WebVTT format.
Captions can also be selected with an ISO `lang`, e.g. &lang=en, `tlang` will auto-translate from English into the requested language (if English captions are available).
##### GET `/api/v1/trending`
> Schema:
```javascript
[
{
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"lengthSeconds": Int32,
"viewCount": Int64,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String,
"description": String,
"descriptionHtml": String,
"liveNow": Bool,
"paid": Bool,
"premium": Bool
}
]
```
Parameters:
```
type: "music", "gaming", "news", "movies"
region: ISO 3166 country code (default: "US")
```
##### GET `/api/v1/popular`
> Schema:
```javascript
[
{
"type": "shortVideo",
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"lengthSeconds": Int32,
"viewCount": Int64,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String
}
]
```
##### GET `/api/v1/channels/:ucid`
> Schema:
```javascript
{
"author": String,
"authorId": String,
"authorUrl": String,
"authorBanners": [
{
"url": String,
"width": Int32,
"height": Int32
}
],
"authorThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
],
"subCount": Int32,
"totalViews": Int64,
"joined": Int64,
"paid": Bool,
"autoGenerated": Bool,
"isFamilyFriendly": Bool,
"description": String,
"descriptionHtml": String,
"allowedRegions": Array(String),
"latestVideos": [
{
"title": String,
"videoId": String,
"author": String,
"authorId": String,
"authorUrl": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"description": String,
"descriptionHtml": String,
"viewCount": Int64,
"published": Int64,
"publishedText": String,
"lengthSeconds": Int32,
"paid": Bool,
"premium": Bool
}
],
"relatedChannels": [
{
"author": String,
"authorId": String,
"authorUrl": String,
"authorThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
]
}
]
}
```
Parameters:
```
sort_by: "newest", "oldest", "popular" (default: newest)
```
Note that a channel's username (if it doesn't include spaces) is also valid in place of `ucid`, e.g. `/api/v1/channels/BlenderFoundation`.
##### GET `/api/v1/channels/:ucid/videos`, `/api/v1/channels/videos/:ucid`
> Schema:
```javascript
[
{
title: String,
videoId: String,
author: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
description: String,
descriptionHtml: String,
viewCount: Int64,
published: Int64,
publishedText: String,
lengthSeconds: Int32
paid: Bool,
premium: Bool
}
]
```
Parameters:
```
page: Int32
sort_by: "newest", "oldest", "popular" (default: newest)
```
##### GET `/api/v1/channels/:ucid/latest`, `/api/v1/channels/latest/:ucid`
```javascript
[
{
title: String,
videoId: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
description: String,
descriptionHtml: String,
viewCount: Int64,
published: Int64,
publishedText: String,
lengthSeconds: Int32
paid: Bool,
premium: Bool
}
]
```
##### GET `/api/v1/channels/playlists/:ucid`, `/api/v1/channels/:ucid/playlists`
```javascript
{
"playlists": [
{
"title": String,
"playlistId": String,
"author": String,
"authorId": String,
"authorUrl": String,
"videoCount": Int32,
"videos": [
{
"title": String,
"videoId": String,
"lengthSeconds": Int32,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
]
}
]
],
"continuation": String?
}
```
Parameters:
```
continuation: String
sort_by: "oldest", "newest", "last"
```
##### GET `/api/v1/channels/comments/:ucid`, `/api/v1/channels/:ucid/comments`
```javascript
{
"authorId": String,
"comments": [
{
"author": String,
"authorThumbnails": [
"url": String,
"width": Int32,
"height": Int32
],
"authorId": String,
"authorUrl": String,
"isEdited": Bool,
"content": String,
"contentHtml": String,
"published": Int64,
"publishedText": String,
"likeCount": Int32,
"commentId": String,
"authorIsChannelOwner": Bool,
"creatorHeart": {
"creatorThumbnail": String,
"creatorName": String
}?,
"replies": {
"replyCount": Int32,
"continuation": String
}?,
"attachment": Attachment?
}
],
"continuation": String?
}
```
The `authorId` for top-level comments will always(?) be the same as the requested channel. Top-level comments will also have an optional `attachment`, which can be one of:
```javascript
{
"type": "image",
"imageThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
]
}
```
```javascript
{
"type": "video",
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"lengthSeconds": Int32,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String,
"viewCount": Int64,
"viewCountText": String
}
```
```javascript
{
"type": "unknown",
"error": "Unrecognized attachment type."
}
```
Some attachments may only have a `type` and `error`, similar to the above. Attachments will *only* be present on top-level comments.
Parameters:
```
continuation: String
```
##### GET `/api/v1/channels/search/:ucid`
> Schema:
```javascript
[
{
type: "video",
title: String,
videoId: String,
author: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
description: String,
descriptionHtml: String,
viewCount: Int64,
published: Int64,
publishedText: String,
lengthSeconds: Int32,
liveNow: Bool,
paid: Bool,
premium: Bool
},
{
type: "playlist",
title: String,
playlistId: String,
author: String,
authorId: String,
authorUrl: String,
videoCount: Int32,
videos: [
{
title: String,
videoId: String,
lengthSeconds: Int32,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
]
}
]
},
{
type: "channel",
author: String,
authorId: String,
authorUrl: String,
authorThumbnails: [
{
url: String,
width: Int32,
height: Int32
}
],
subCount: Int32,
videoCount: Int32,
description: String,
descriptionHtml: String
}
];
```
Parameters:
```
q: String
page: Int32
```
##### GET `/api/v1/search/suggestions`
> Schema:
```javascript
{
"query": String,
"suggestions": Array(String)
}
```
Parameters:
```
q: String
```
##### GET `/api/v1/search`
> Schema:
```javascript
[
{
type: "video",
title: String,
videoId: String,
author: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
description: String,
descriptionHtml: String,
viewCount: Int64,
published: Int64,
publishedText: String,
lengthSeconds: Int32,
liveNow: Bool,
paid: Bool,
premium: Bool
},
{
type: "playlist",
title: String,
playlistId: String,
author: String,
authorId: String,
authorUrl: String,
videoCount: Int32,
videos: [
{
title: String,
videoId: String,
lengthSeconds: Int32,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
]
}
]
},
{
type: "channel",
author: String,
authorId: String,
authorUrl: String,
authorThumbnails: [
{
url: String,
width: Int32,
height: Int32
}
],
subCount: Int32,
videoCount: Int32,
description: String,
descriptionHtml: String
}
];
```
Parameters:
```
q: String
page: Int32
sort_by: "relevance", "rating", "upload_date", "view_count"
date: "hour", "today", "week", "month", "year"
duration: "short", "long"
type: "video", "playlist", "channel", "all", (default: video)
features: "hd", "subtitles", "creative_commons", "3d", "live", "purchased", "4k", "360", "location", "hdr" (comma separated: e.g. "&features=hd,subtitles,3d,live")
region: ISO 3166 country code (default: "US")
```
##### GET `/api/v1/playlists/:plid`
> Schema:
```javascript
{
"title": String,
"playlistId": String,
"author": String,
"authorId": String,
"authorThumbnails": [
{
"url": String,
"width": String,
"height": String
}
],
"description": String,
"descriptionHtml": String,
"videoCount": Int32,
"viewCount": Int64,
"updated": Int64,
"videos": [
{
"title": String,
"videoId": String,
"author": String,
"authorId": String,
"authorUrl": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"index": Int32,
"lengthSeconds": Int32
}
]
}
```
Parameters:
```
page: Int32
```
##### GET `/api/v1/mixes/:rdid`
> Schema:
```javascript
{
title: String,
mixId: String,
videos: [
{
title: String,
videoId: String,
author: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
index: Int32,
lengthSeconds: Int32
}
]
}
```

View file

@ -0,0 +1,32 @@
---
title: Always-use-"local"-to-proxy-video-through-the-server-without-creating-an-account
description:
published: true
date: 2021-05-23T16:58:12.539Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:38:58.736Z
---
Download ViolentMonkey for your Browser:
[Firefox](https://addons.mozilla.org/en-US/firefox/addon/violentmonkey/)
[Chrome and Chromium](https://chrome.google.com/webstore/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag)
[Others](https://violentmonkey.github.io/get-it/)
Than add the following script in ViolentMonkey. It will always add `&local=true` to the end of the video URL.
```
// ==UserScript==
// @name Invidious Proxy automatically
// @match *://*.redirect.invidious.io/watch?v=*
// @run-at document-start
// @grant none
// ==/UserScript==
if (!(/[?&]local=/).test(location.search) && !(/[?&]quality=dash/).test(location.search)) {
location.search += (location.search ? "&" : "?") + "local=true";
}
```
You can also enable this by checking `Proxy videos?` in your preferences.

View file

@ -0,0 +1,70 @@
---
title: Apache2-Reverse-Proxy
description:
published: true
date: 2021-05-23T16:58:15.954Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:03.772Z
---
- A very basic config, secured with Let's Encrypt. Any log is disabled by default. Do not forget to replace `ServerName` with your domain.
```
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName invidious.domain.tld
ServerAdmin admin@localhost
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
# ErrorLog /var/log/apache2/invidious.domain.tld/error.log
CustomLog /dev/null combined
RewriteEngine on
SSLCertificateFile /etc/letsencrypt/live/invidious.domain.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/invidious.domain.tld/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/invidious.domain.tld/chain.pem
</VirtualHost>
</IfModule>
```
- Another config example without HTTPS, but with Apache Basic Auth HTTP login.
The user will connect to Apache on port 3333 and will be asked to log in. If authentification is successful, Apache will redirect the user to Invidious' page.
To make the VirtualHost config below actually work, you should as well:
- Create a [.htpasswd](http://httpd.apache.org/docs/current/programs/htpasswd.html) file and add required [username/login combos](http://aspirine.org/htpasswd_en.html) to it, if not already existing.
- Open port 3333 (or any other free port) adding `Listen 3333` to Apache `ports.conf` (Debian `/etc/apache2/ports.conf`)
- If you run Invidious with default parameters, you may need to replace default host binding (0.0.0.0) with localhost (127.0.0.1) instead. That way, Invidious won't be publicly available on port 3000 anymore, but only accessible via the reverse proxy on port 3333. So if you run Invidious via a systemd service, you would edit the service file (e.g. `/etc/systemd/system/invidious.service`) and modify the ExecStart line to include the -b switch as follows `ExecStart=/home/invidious/invidious/invidious -b 127.0.0.1 -o invidious.log` and then reload the daemon with `systemctl daemon-reload` so that changes are taken into account.
- A convenient way to open such protected Invidious page without having to log in manually everytime is to access use a URL with the following format: http://username:password@domain:3333
```
<VirtualHost *:3333>
ServerName invidious.domain.tld #add your own domain name (or localhost if you have none)
ServerAdmin admin@localhost
<Location />
Deny from all # Forbid access to all by default...
#Allow from 127.0.0.1 #...Except from specific IPs (which will not need to authenticate)...
AuthUserFile /etc/apache2/.htpasswd #path to .htpasswd file
AuthName "Restricted Area" # name displayed in the promptbox
AuthType Basic # http://httpd.apache.org/docs/current/howto/auth.html
Satisfy Any
Require valid-user # ...and except from authenticated users included in the .htpasswd file
</Location>
ProxyPass / http://127.0.0.1:3000/ nocanon
ProxyPassReverse / http://127.0.0.1:3000/
ProxyPreserveHost On
ProxyRequests Off
AllowEncodedSlashes On
#ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog /dev/null combined
</VirtualHost>
```

View file

@ -0,0 +1,47 @@
---
title: Apache2-reverse-proxy
description:
published: true
date: 2021-11-17T16:59:09.054Z
tags:
editor: markdown
dateCreated: 2021-11-17T20:40:07.950Z
---
This is the barebones SSL and non-SSL configs for Apache 2.2 and up. You will need to use Let's Encrypt to generate a certificate. Replace `your-domain` with your website. Logs are not recorded by default.
```
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerAlias your-domain
ProxyPass / http://0.0.0.0:3000/
ProxyPassReverse / http://0.0.0.0:3000/
RemoteIPHeader CF-Connecting-IP
ErrorLog /dev/null
CustomLog /dev/null
RewriteEngine on
RewriteCond %{SERVER_NAME} =your-domain
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerAlias your-domain
ErrorDocument 503 "Invidious is unavailable at this time."
ProxyPass / http://0.0.0.0:3000/
ProxyPassReverse / http://0.0.0.0:3000/
ErrorLog /dev/null
CustomLog /dev/null
#RemoteIPHeader CF-Connecting-IP
Include /etc/letsencrypt/options-ssl-apache.conf
ServerName your-domain
SSLCertificateFile /etc/letsencrypt/live/your-domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain/privkey.pem
</VirtualHost>
</IfModule>
```

View file

@ -0,0 +1,428 @@
---
title: Authenticated-Endpoints
description:
published: true
date: 2021-05-23T16:58:20.048Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:08.568Z
---
All endpoints under namespace `/api/v1/auth` require authentication.
Authentication can be in one of two forms:
- A `Cookie: <SID>` header (for logged in users)
- An `Authentication: Bearer <TOKEN>` (recommended)
A new token can be generated from `/authorize_token` with the given parameters:
```
scopes: Comma-separated list of scopes
callback_url: URL to redirect to with generated token
expire: Int64 how long a given token should be valid (in seconds)
```
Each `scope` has the following format:
```
METHOD1;METHOD2...:ENDPOINT(*)?
```
Where `METHOD` can be one of `GET`, `POST`, `PUT`, `DELETE`, `PATCH`.
An `ENDPOINT` can be any of the documented endpoints below.
Examples:
- `POST:playlists*`: authorizes `POST` methods to _any_ endpoint under `/api/v1/auth/playlists` (`/api/v1/auth/playlists`, `/api/v1/playlists/:id/videos`, etc.)
- `:playlists/*`: authorizes _any_ method to endpoints under `/api/v1/auth/playlists/` (`/api/v1/auth/playlists/:id`, `/api/v1/playlists/:id/videos`, etc.)
- `GET:playlists/IVPAAAAAAA`: authorizes `GET` only to playlist `IVPAAAAAAA`.
- `:preferences`: authorizes _any_ method to `/api/v1/auth/preferences`
- `GET;POST:preferences`: authorizes `GET` or `POST` to `/api/v1/auth/preferences`
When a `callback_url` is specified, after a user has authorized a token with the desired `scopes`, a GET request will be made to the `callback_url` with the token URL-escaped and appended as `token=TOKEN`.
##### GET `/api/v1/auth/feed`
Get subscription feed for the authenticated user.
Parameters:
```
max_results: Int32
page: Int32
```
> Schema:
```javascript
{
"notifications": [
{
"type": "shortVideo",
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int64,
"height": Int64
}
],
"lengthSeconds": Int64,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String,
"viewCount": Int64
}
],
"videos": [
{
"type": "shortVideo",
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int64,
"height": Int64
}
],
"lengthSeconds": Int64,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String,
"viewCount": Int64
}
]
}
```
##### GET `/api/v1/auth/notifications`
Parameters:
```
topics: Array(String) (comma separated: e.g. "UCID1,UCID2) limit of 1000 topics
since: Int64, timestamp
```
Provides an [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) for receiving changes from each `topic` in `topics`. Currently the only supported topic-type is `ucid`, which will return an updated video object whenever the given channel uploads a video.
Important to note is that an event will also be sent when a channel _changes_ an already uploaded video, for example changing description or title.
Each event is a JSON object with the same schema as `/api/v1/videos`. The `fields` API can be used, which will be applied to each object.
A `debug` topic can also provided which will return a (psuedo-)randomly selected video every minute.
`since` will return all videos uploaded since `TIMESTAMP`, with a limit of the 15 most recent videos from each topic.
More details in [#469](https://github.com/iv-org/invidious/issues/469).
##### POST `/api/v1/auth/notifications`
Same as above `GET` endpoint, however `topics` is moved into post body as `Content-Type: application/x-www-form-urlencoded`.
##### GET `/api/v1/auth/playlists`
Get list of playlists for the given user.
> Schema:
```javascript
[
{
"type": "invidiousPlaylist",
"title": String,
"playlistId": String,
"author": String,
"authorId": null,
"authorUrl": null,
"authorThumbnails": [],
"description": String,
"descriptionHtml": String,
"videoCount": Int32,
"viewCount": 0,
"updated": Int64,
"isListed": Boolean,
"videos": [
{
"title": String,
"videoId": String,
"author": String,
"authorId": String,
"authorUrl": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"index": Int32,
"indexId": String,
"lengthSeconds": Int32
}
]
}
]
```
##### POST `/api/v1/auth/playlists`
`Content-Type: application/json`
Create new playlist.
Example request body:
```javascript
{
"title": String,
"privacy": "private"
}
```
`privacy` can be any of: `public`, `unlisted`, `private`
If successful, returns 201, a link to the created resource as a `Location` header, and the following response:
```javascript
{
"title": String,
"playlistId": String
}
```
##### GET `/api/v1/auth/playlists/:id`
Returns same result as unauthenticated `/api/v1/playlists/:id`.
Important to note is that if the requested playlist is marked as `private`, it will return an error if the request is not authenticated as the playlist's author.
##### PATCH `/api/v1/auth/playlists/:id`
`Content-Type: application/json`
Modify a playlist's `description`, `title`, `description`, or `privacy`.
Example request body:
```javascript
{
"title": String,
"description": String,
"privacy": "private"
}
```
`privacy` can be any of: `public`, `unlisted`, `private`
Will return 204 on success.
##### DELETE `/api/v1/auth/playlists/:id`
Delete a given playlist `:id`.
Will return 204 on success.
##### POST `/api/v1/auth/playlists/:id/videos`
`Content-Type: application/json`
Add a video to the given playlist `:id`.
Example request body:
```javascript
{
"videoId": String
}
```
Returns a 201 on success with the following schema:
```javascript
{
"title": String,
"videoId": String,
"author": String,
"authorId": String,
"authorUrl": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
]
}
```
##### DELETE `/api/v1/auth/playlists/:id/videos/:index`
Delete a video from the given playlist `:id` with `indexId` `:index`.
Will return 204 on success.
##### GET `/api/v1/auth/preferences`
Get preferences for authenticated user.
> Schema:
```javascript
{
"annotations": false,
"annotations_subscribed": false,
"autoplay": false,
"captions": [
"",
"",
""
],
"comments": [
"youtube",
""
],
"continue": false,
"continue_autoplay": true,
"dark_mode": "light",
"latest_only": false,
"listen": false,
"local": false,
"locale": "en-US",
"max_results": 40,
"notifications_only": false,
"player_style": "invidious",
"quality": "hd720",
"default_home": "Popular",
"feed_menu": [
"Trending",
"Playlists"
],
"related_videos": true,
"sort": "published",
"speed": 1.0,
"thin_mode": false,
"unseen_only": false,
"video_loop": false,
"volume": 100
}
```
##### POST `/api/v1/auth/preferences`
`Content-Type: application/json`
Patch user preferences.
Example body:
```javascript
{
"speed": 2.0,
"volume": 10
}
```
##### GET `/api/v1/auth/subscriptions`
Get user's subscriptions.
> Schema:
```javascript
[
{
"author": String,
"authorId": String
}
]
```
##### POST `/api/v1/auth/subscriptions/:ucid`
`Content-Type: application/json`
Add a given `ucid` to a user's subscriptions.
Will return 204 on success.
##### DELETE `/api/v1/auth/subscriptions/:ucid`
Removes a given `ucid` from a user's subscriptions.
Will return 204 on success.
##### GET `/api/v1/auth/tokens`
Get a list of tokens for the authenticated user.
> Schema:
```javascript
[
{
"session": String,
"issued": Int64
}
]
```
##### POST `/api/v1/auth/tokens/register`
`Content-Type: application/json`
Create a new token for the authenticated user.
Example request body:
```javascript
{
"scopes": Array(String), // Each scope has same format as each scope in `/authorize_token`
"callbackUrl": String?,
"expire": Int64
}
```
Returns a 200 on success with the newly created token as the response body.
Example response:
```javascript
{
"session":"v1:YUwKEL1XwHQzp7-AAAAAAAAAAAAAAAAAA=",
"scopes":["GET:notifications"],
"signature":"jNYdAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAXGb__2Gv-w="
}
```
##### POST `/api/v1/auth/tokens/unregister`
`Content-Type: application/json`
Revoke a token for the authenticated user.
Example request:
```javascript
{
"session": "v1:YUwKEL1XwHQzp7-AAAAAAAAAAAAAAAAAA="
}
```
Returns 204 on success.

81
docs/Configuration.md Normal file
View file

@ -0,0 +1,81 @@
---
title: Configuration
description:
published: true
date: 2021-05-23T16:58:24.054Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:13.768Z
---
### What can be configured and what are these configuration options?
The configuration file is located at [invidious/config/config.yml](https://github.com/iv-org/invidious/blob/master/config/config.example.yml).
- `channel_threads` (default `1`) Number of threads to use for crawling videos from channels
- `feed_threads` (default `1`) Number of threads to use for refreshing subscription feeds
```
db:
user: kemal # your database user
password: kemal # your database password
host: localhost # database host
port: 5432 # postgres port
```
- `full_refresh` (default `false`) When crawling channel videos, threads should refresh *all* videos uploaded by a channel
- `https_only` (default `false`) Used to tell Invidious it is accessed via https, set to `true` if you have for example a reverse proxy with a ssl certificate
- `hmac_key` (default `nil`) Signing key for CSRF tokens (when `nil` is randomly generated on startup, can be any random string)
- `domain` (default `nil`) Domain to use for providing `self` links in RSS feeds, issuing cookies, etc.
- `use_pubsub_feeds` (default `false`) Use server-side notifications provided by [YouTube](https://developers.google.com/youtube/v3/guides/push_notifications). Requires `domain` and `hmac_key` to be set
- `default_home` (default `"Popular"`) Default home page **Moved into `default_user_preferences`**
- `feed_menu` (default `["Popular", "Trending", "Subscriptions"]`) Order of tabs on feed menu **Moved into `default_user_preferences`**
- `captcha_enabled` (default `true`) Determine if CAPTCHA should be required for registration
- `login_enabled` (default `true`) Whether users should be able to login
- `registration_enabled` (default `true`) Whether new users should be able to register
- `statistics_enabled` (default `false`) Whether statistics should be available from `/api/v1/stats`
- `admins` (default `[]`) List of user IDs that have access to administrator preferences
- `external_port` (default `nil`) Invidious should supply links to a different port (if running behind a proxy, for example). PubSub notifications (if enabled) will also be sent to this port
- `default_user_preferences` (default [`ConfigPreferences`](https://github.com/iv-org/invidious/blob/master/src/invidious/helpers/helpers.cr#L127)) Default preferences to use for new and unregistered users, see [#415](https://github.com/iv-org/invidious/issues/415)
- `dmca_content` (default `[]`) For compliance with DMCA requests, disables download widget for list of video IDs
- `check_tables` (default `false`) Check table integrity, automatically try to add any missing columns, create columns, etc.
- `cache_annotations` (default `false`) Cache annotations requested from IA, will not cache empty annotations or annotations that only contain cards
- `banner` (default `nil`) Optional banner to be displayed along top of page for announcements, etc.
- `hsts` (default `true`) For HTTP Strict Transport Security
- `disable_proxy` (default `false`) Disable proxy option serverwide (options: 'dash', 'livestreams', 'downloads', 'local')
- `force_resolve` (default `nil`) Force IPv4 or IPv6 connection to Google (options: 'ipv4', 'ipv6') see [#811](https://github.com/iv-org/invidious/issues/811)
- `pool_size` (default `100`) Pool size for HTTP connections for youtube.com and ytimg.com (each domain has a separate pool of `pool_size`)
- `admin_email` (default `omarroth@protonmail.com`) Email provided to users for bug reports
- `port` (default `3000`) Default port for HTTP server
- `host_binding` (default `0.0.0.0`) Default host for HTTP server
- `cookies` (default `nil`) Cookies to be used when connecting to YouTube
- `captcha_key` (default `nil`) [Anti-Captcha](https://anti-captcha.com/) API key for solving YouTube CAPTCHAs, see [#886](https://github.com/iv-org/invidious/issues/886).
- `popular_enabled` (default `false`) Whether to display popular videos of the instance.

View file

@ -0,0 +1,33 @@
---
title: Database-Information-and-Maintenance
description:
published: true
date: 2021-05-23T16:58:27.530Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:18.631Z
---
Invidious needs one PostgreSQL database which has the following tables.
- `annotations` Caches annotation data if `cache_annotations` is enabled in [`config.yml`](./Configuration)
- `channel_videos` Stores truncated video info, used to create user feeds
- `channels` Stores UCID and author name
- `nonces` Keeps track of tokens issued to prevent CSRF
- `users` Stores user info, such as preferences, username, subscriptions
- `session_ids` Keeps track of user sessions
- `videos` Stores video cache, used to create "top" page
The table `videos` grows a lot and needs the most storage. You can clean it up using following commands:
```bash
$ sudo -i -u postgres
$ psql invidious -c "DELETE FROM nonces * WHERE expire < current_timestamp"
$ psql invidious -c "TRUNCATE TABLE videos"
$ exit
```
For regular maintenance you should add a cronjob for these commands
```bash
@weekly psql invidious -c "DELETE FROM nonces * WHERE expire < current_timestamp" > /dev/null
@weekly psql invidious -c "TRUNCATE TABLE videos" > /dev/null
```

View file

@ -0,0 +1,23 @@
---
title: Export-YouTube-subscriptions
description:
published: true
date: 2021-05-23T16:58:30.841Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:23.334Z
---
**The steps below as well as the resulting file name are different depending on your Google language
settings.**
1. Open [Google Takeout](https://takeout.google.com/takeout/custom/youtube).
2. Under `Create a new export` choose `YouTube and YouTube Music`.
3. Click on `All YouTube data included` and only tick `subscriptions` in the dialog that opens.
4. Click on `Next step`, make sure `Export once` is chosen and click on `Create export`.
5. Wait until the export creation is finished, then on the same page click on `Download` under
`Your latest export` that should now be visible.
6. Extract the downloaded archive and find the file `subscriptions.csv`.
7. While logged into your Invidious account go to Subscriptions -> Manage Subscriptions ->
Import/Export -> Import YouTube subscriptions, select the file you just downloaded and click on
`Import`.

36
docs/Extensions.md Normal file
View file

@ -0,0 +1,36 @@
---
title: Extensions
description:
published: true
date: 2021-05-23T16:58:34.318Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:27.709Z
---
### Browser extensions for Invidious
- [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect): Redirects YouTube to Invidious, Twitter to Nitter, and Instagram to Bibliogram. [Source](https://github.com/SimonBrazell/privacy-redirect) / [Firefox](https://addons.mozilla.org/addon/privacy-redirect) / [Chrome](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb)
- [Alter](https://addons.mozilla.org/addon/alter): Firefox extension that redirects YouTube, Twitter and Reddit to Invidious, Nitter and Teddit respectively. [Source](https://github.com/w3bdev1/alter) / [Firefox](https://addons.mozilla.org/addon/alter)
- [SponsorBlock](https://github.com/ajayyy/SponsorBlock): A crowd-sourced extension to skip sponsorships. Support invidious instances if enabled in the options. [Source](https://github.com/ajayyy/SponsorBlock) / [Firefox](https://addons.mozilla.org/addon/sponsorblock) / [Chrome](https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone)
- [Invidition](https://addons.mozilla.org/addon/invidition): Firefox extension that redirects YouTube links and embeds to their Invidious counterpart without any call to YouTube. [Source](https://codeberg.org/Booteille/Invidition) (**deprecated**).
- [Alternate Tube Redirector](https://gitlab.com/2vek/alternate-tube-redirector): Extension to automatically open YouTube Videos on alternate sites like Invidious or Hooktube. [Source](https://gitlab.com/2vek/alternate-tube-redirector)
- [Invidious Copy URL](https://github.com/recette-lemon/invidious-copy-url): Adds context menu options on Invidious to copy shortened YouTube URL at current time or not (Requires using developer mode in Chrome or a developer version of Firefox).
- [View on Invidious](https://omar.yt/722e5c15832840fe1ae8830b7c590254b9e0a45c/invidious-bookmarklet.html): View page on Invidious (bookmarklet).
- [Inviduration](https://addons.mozilla.org/addon/inviduration): Firefox extension that shows total duration of playlists on Invidious. [Source](https://github.com/rsapkf/inviduration) / [Firefox](https://addons.mozilla.org/addon/inviduration)
### Userscripts for Invidious.
- [Invidious Redirect](https://greasyfork.org/en/scripts/370461-invidious-redirect): Redirects YouTube URLs to Invidio.us.
- [YouTube to Invidious](https://greasyfork.org/en/scripts/375264-youtube-to-invidious): Scans current page for YouTube embeds and replace with Invidious.
- [No-Youtube](https://github.com/mperez01/no-youtube): Userscript to replace youtube links to invidio.us.
- [Invidious Audio Mode](https://greasyfork.org/en/scripts/397700-invidious-audio-mode): Adds a headphone icon next to all video links. Handy for those that just want to stream audio and not video.
- [FYTE](https://greasyfork.org/en/scripts/9252-fyte-fast-youtube-embedded-player): Replace all YouTube embeds on a page with the video's thumbnail. Click on the thumbnail to play the video. Invidious is supported in the Options panel.
### Extensions that integrate Invidious into other programs and apps
- [UntrackMe](https://f-droid.org/en/packages/app.fedilab.nitterizeme): Android app to rewrite YouTube links to Invidious. Can optionally play videos in the app as well.
- [iPhone Redirector Shortcut](https://www.icloud.com/shortcuts/6bbf26d989cf4d07a5fe1626efbc0950): Automatically open YouTube videos in Invidious (iPhone shortcut).
- [FreshRSS Extension](https://github.com/tmiland/freshrss-invidious): A FreshRSS extension to directly embed videos from Invidious channel feeds.
- [Kodi add-on](https://github.com/TheAssassin/kodi-invidious-plugin): Watch YouTube videos in the Kodi media center, using the Invidious API. Privacy-friendly alternative to the YouTube API add-on.
- [Another Kodi add-on](https://github.com/lekma/plugin.video.invidious): Seems to have been more recently updated than the above.
### Utilities for Invidious
- [Invidious-Updater (And Installer)](https://github.com/tmiland/Invidious-Updater): Automatic install and update script for Invidious.

152
docs/FAQ.md Normal file
View file

@ -0,0 +1,152 @@
# Frequently Asked Questions
## Table of Contents
- Using Invidious
* [Can I use Invidious on my device?](#q-can-i-use-invidious-on-my-device)
* [Do you plan to make an Android/iOS app?](#q-do-you-plan-to-make-an-androidios-app)
* [What data is collected by Invidious?](#q-what-data-is-collected-by-invidious)
* [What data is shared with YouTube?](#q-what-data-is-shared-with-youtube)
- Commonly encountered errors
* [The media could not be loaded…](#q-the-media-could-not-be-loaded)
* [Could not check out a connection in 2.0 seconds (DB::PoolTimeout)](
#q-could-not-check-out-a-connection-in-20-seconds-dbpooltimeout)
- Running your own instance
* [Do you provide pre-built binaries (`.deb`, `.rpm`, etc..)?](
#q-do-you-provide-pre-built-binaries-deb-rpm-etc)
* [How can I configure _[thing]_?](#q-how-can-i-configure-thing)
* [RSS feeds/links/etc... URLs redirect to `<IP>:3000` but I have a reverse proxy!](
#q-rss-feedslinksetc-urls-redirect-to-ip3000-but-i-have-a-reverse-proxy)
* [The "popular" feed/page on my instance is empty!](
#q-the-popular-feedpage-on-my-instance-is-empty)
# Using Invidious
## **Q:** Can I use Invidious on my device?
**A:** As long as your device is equipped with a modern web browser,
sure, of course! A responsive interface is available for mobile/tablets.
<br/>
## **Q:** Do you plan to make an Android/iOS app?
**A:** No. Invidious is and will always be a browser application.
If you have an Android phone/tablet, you can check the
[NewPipe](https://github.com/TeamNewPipe/NewPipe) application.
<br/>
## **Q:** What data is collected by Invidious?
**A:** Invidious by itself does not collect any data about its users, but
keep in mind that instance owners can log your IP address (like any other
server on the internet).
By default, the server logs which URLs were accessed, the associated error
code (e.g 404 if the URL was not found) and the time it took for the server
to respond.
Here is what the server logs look like:
```
2021-08-30 18:15:44 UTC [info] 200 GET /watch?v=GIAKHj9uJtM 781.21ms
2021-08-30 18:15:49 UTC [info] 200 GET /api/v1/search?q=Fly%20away 500.0ms
2021-08-30 18:15:49 UTC [info] 200 GET /vi/lJcqAzWFWLs/mqdefault.jpg 15.82ms
2021-08-30 18:15:49 UTC [info] 200 GET /vi/JoP_Tte7z7o/mqdefault.jpg 70.64ms
```
When you create an account, your watch history and the list of channels you
subscribed will be stored in the server's database. You can export, migrate
or delete these data at any time from your user account page.
<br/>
## **Q:** What data is shared with YouTube?
**A:** By default, the video stream is fetched directly from Google's servers
(`googlevideo.com`) in order to reduce the bandwidth required by invidious,
meaning that Google will be able to see your IP address and some other data
commonly sent by web browsers, like your user-agent string.
If you don't want that to happen, you can go to the `preferences` page and
check the `Proxy videos` option. When this option is enabled, the Invidious
instance will be used as a relay (also known as a "proxy") between you and
Google's servers, which will hide your IP address and the other information
sent by your browser.
<br/>
# Commonly encountered errors
## **Q:** The media could not be loaded…
**A:** This problem can occur in different scenarios:
* If you're trying to watch a music clip, Youtube is likely blocking the
video stream. Try enabling `Proxy videos` in the preferences (or add
`&local=1` in the URL). Switching to another instance is also a good
alternative, as this type of content is often geo-restricted.
* Youtube often sends corrupted video data for the `hd720`, `medium` and
`small` quality settings. Refreshing the page multiple times (5-7) can
fix the problem. You may also set your `preferred video quality` to
`dash` (or add `&quality=dash` to the URL).
* Rarely, it can be due to an internal failure of the instance and the
video stream can't be fetched. A simple page refresh can solve the issue.
If none of the solutions listed above fix the problem, try switching
instances. And if that still doesn't work, you'll have to watch the video
on YouTube itself (sorry for the inconvenience).
<br/>
## **Q:** Could not check out a connection in 2.0 seconds (DB::PoolTimeout)
**A: Please, do not open a bug report on github, we can't do anything!**
The instance you are using is having _database issues_. Please use another
instance from the [list of public instances](https://instances.invidious.io)
<br/>
# Running your own instance
## **Q:** Do you provide pre-built binaries (`.deb`, `.rpm`, etc.)?
**A:** We currently don't provide those, due to the rolling release nature
of Invidious. Get a fresh `clone` or `pull` the latest commits from `master`
instead.
<br/>
## **Q:** How can I configure _[thing]_?
**A:** Read the example config file (`config/config.example.yml`).
All the supported configuration options are documented there.
<br/>
## **Q:** RSS feeds/links/etc... URLs redirect to `<IP>:3000` but I have a reverse proxy!
**A:** Make sure that the following parameters are set according to your environment:
- `https_only`: if your instance is served over HTTPS
- `domain`: if you have a domain name that redirects to your instance
- `external_port`: if your instance is accessed from a different port than
the listening one (e.g your instance listens on :3000, but is available on
:443 through a reverse proxy, set `external_port` to `443`)
<br/>
## **Q:** The "popular" feed/page on my instance is empty!
**A:** The "popular" feed is generated from the videos that are popular amongst
the users registered on your instance. If nobody has created an account on your
instance (e.g if registration is disabled) the popular feed will be empty.

View file

@ -0,0 +1,31 @@
---
title: Geoblocking,-available-video-quality-and-DASH
description:
published: true
date: 2021-05-23T16:58:38.141Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:32.300Z
---
## Geoblocking
Sometimes you may notice that you cannot watch a video on Invidious. This is because YouTube is geoblocking, i.e. preventing access to videos based on your geographical location.
If the `Proxy videos?` setting is enabled, Invidious will proxy videos through itself, so the stream will be routed like this:
> YouTube → Invidious/server → Client/browser
If a video is blocked where the instance is hosted, then the route would be this:
> YouTube → Proxy server → Invidious/server → Client/browser
The current system works by cycling through proxies in different regions, and finding one where the video is not blocked.
The reason geoblocked videos may take a long time to load is because Invidious would have to cycle through all known proxy servers until it finds one that is able to play back the video.
If the `Proxy videos?` setting is disabled, then the stream would be routed like this:
> YouTube → Client/browser
## Video quality and DASH
On Invidious you often don't have the same quality options as on YouTube. This is because the audio and video streams are separated and Invidious currently can't sync them together.
DASH is a streaming technique used by YouTube to provide resolutions higher than 720p by providing multiple files for a client to use depending on network and user preferences.
You can enable DASH by selecting the appropriately named video quality in the settings or by appending `&quality=dash` to the end of a video's URL. With this option enabled, the stream is proxied through Invidious for you to then watch at a higher or automatic quality.

View file

@ -0,0 +1,15 @@
---
title: How-to-deal-with-uMatrix
description:
published: true
date: 2021-05-23T16:58:41.524Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:36.844Z
---
If you're using [uMatrix](https://github.com/gorhill/uMatrix), you won't be able to automatically play a video served by Invidious on other websites without unblocking requests to Invidious instances.
So, to make it work, you'll need to allow `css`, `image`, `media`, `script`, `xhr`, `frame` for the instance from which you're trying to play the video.
Since there are many Invidious instances, you can use the tool called [Invimatrix](https://booteille.gitlab.io/invimatrix) to automatically generate uMatrix rules for every known instance.

View file

@ -0,0 +1,20 @@
---
title: How-to-setup-Anti-Captcha
description:
published: true
date: 2021-05-23T16:58:44.758Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:41.544Z
---
1. [Register on anti-captcha.com](https://anti-captcha.com/clients/entrance/register) and finish the registration with the link provided in your mailbox.
2. Head over to the [Add fund](https://anti-captcha.com/clients/finance/refill) page and use whatever currency you prefer to use for adding $2 into your balance.
Do note that cryptocurrencies give a bonus of 20% the first time you add funds and then 10% for each new recharge.
3. After adding funds, go to the [API key link](https://anti-captcha.com/clients/settings/apisetup) and copy your `Account Key` (**never share it, it's confidential**).
4. Edit your Invidious `config.yml` file (should be located in the `config` directory) and add your account key at the end of the file after the `captcha_key` parameter.
Here is an example:
```yml
captcha_key: acuGae2riad5quashoug3Leeh
```
5. Restart Invidious and that's it!

261
docs/Installation.md Normal file
View file

@ -0,0 +1,261 @@
---
title: Installation
description:
published: true
date: 2021-05-23T16:58:48.374Z
tags:
editor: markdown
dateCreated: 2021-02-25T11:24:06.655Z
---
# Installation
Compiling Invidious requires at least 2GB of free RAM (We recommend to have at least 3GB installed).
If you have less (e.g on a cheap VPS) you can setup a SWAP file or partition, so the combined amount is >= 3GB.
After installation take a look at the [Post-install steps](#post-install-configuration).
Note: Any [PaaS](https://en.wikipedia.org/wiki/Platform_as_a_service) or [SaaS](https://en.wikipedia.org/wiki/Software_as_a_service) provider/software (Heroku, YunoHost, Repli...) are unsupported. Use them at your own risk. They **WILL** cause problems with Invidious and might even suspend your account for "abuse" since Invidious is heavy, bandwidth intensive and technically a proxy (and most providers don't like them). If you use one and want to report an issue, please mention which one you use.
## Automated Installation
[Invidious-Updater](https://github.com/tmiland/Invidious-Updater) is a self-contained script that can automatically install and update Invidious.
## Docker
> The Invidious docker image is only [available on Quay](https://quay.io/repository/invidious/invidious) because, unlike Docker Hub, [Quay is Free and Open Source Software](https://github.com/quay/quay/blob/master/LICENSE). This is reflected in the `docker-compose.yml` file used in this walk-through.{.is-warning}
Ensure [Docker Engine](https://docs.docker.com/engine/install) and [Docker Compose](https://docs.docker.com/compose/install) are installed before beginning.
### Docker-compose method (production)
**This method uses the pre-built Docker image from quay**
Note: Currently the repository has to be cloned, this is because the `init-invidious-db.sh` file and the `config/sql` directory have to be mounted to the postgres container (See the volumes section in the docker-compose file below). This "problem" will be solved in the future.
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
```
Edit the docker-compose.yml with this content:
```docker
version: "3"
services:
invidious:
image: quay.io/invidious/invidious:latest
# image: quay.io/invidious/invidious:latest-arm64 # ARM64/AArch64 devices
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
# Please read the following file for a comprehensive list of all available
# configuration options and their associated syntax:
# https://github.com/iv-org/invidious/blob/master/config/config.example.yml
INVIDIOUS_CONFIG: |
db:
dbname: invidious
user: kemal
password: kemal
host: invidious-db
port: 5432
check_tables: true
# external_port:
# domain:
# https_only: false
# statistics_enabled: false
healthcheck:
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
interval: 30s
timeout: 5s
retries: 2
depends_on:
- invidious-db
invidious-db:
image: docker.io/library/postgres:14
restart: unless-stopped
volumes:
- postgresdata:/var/lib/postgresql/data
- ./config/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: kemal
POSTGRES_PASSWORD: kemal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
volumes:
postgresdata:
```
Note: This compose is made for a true "production" setup, where Invidious is behind a reverse proxy. If you prefer to directly access Invidious, replace `127.0.0.1:3000:3000` with `3000:3000` under the `ports:` section.
> The environment variable `POSTGRES_USER` cannot be changed. The SQL config files that run the initial database migrations are hard-coded with the username `kemal`.
{.is-warning}
### Docker-compose method (development)
**This method builds a Docker image from source**
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
docker-compose up
```
## Manual Installation
### Linux
#### Install Crystal
Follow the instructions for your distribution here: https://crystal-lang.org/install/
#### Install the dependencies
Arch Linux
```bash
sudo pacman -S base-devel librsvg postgresql
```
Debian/Ubuntu
```bash
sudo apt install libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev zlib1g-dev libpcre3-dev libevent-dev
```
RHEL based and RHEL-like systems (RHEL, Fedora, AlmaLinux, RockyLinux...)
```bash
sudo dnf install -y openssl-devel libevent-devel libxml2-devel libyaml-devel gmp-devel readline-devel postgresql librsvg2-devel sqlite-devel zlib-devel gcc
```
#### Add an Invidious user and clone the repository
```bash
useradd -m invidious
su - invidious
git clone https://github.com/iv-org/invidious
exit
```
#### Set up PostgresSQL
```bash
systemctl enable --now postgresql
sudo -i -u postgres
psql -c "CREATE USER kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
psql invidious kemal < /home/invidious/invidious/config/sql/channels.sql
psql invidious kemal < /home/invidious/invidious/config/sql/videos.sql
psql invidious kemal < /home/invidious/invidious/config/sql/channel_videos.sql
psql invidious kemal < /home/invidious/invidious/config/sql/users.sql
psql invidious kemal < /home/invidious/invidious/config/sql/session_ids.sql
psql invidious kemal < /home/invidious/invidious/config/sql/nonces.sql
psql invidious kemal < /home/invidious/invidious/config/sql/annotations.sql
psql invidious kemal < /home/invidious/invidious/config/sql/playlists.sql
psql invidious kemal < /home/invidious/invidious/config/sql/playlist_videos.sql
exit
```
#### Set up Invidious
```bash
su - invidious
cd invidious
shards install --production
crystal build src/invidious.cr --release
exit
```
#### Systemd service
```bash
cp /home/invidious/invidious/invidious.service /etc/systemd/system/invidious.service
systemctl enable --now invidious.service
```
### MacOS
```bash
# Install dependencies
brew update
brew install shards crystal postgres imagemagick librsvg
# Clone the repository and set up a PostgreSQL database
git clone https://github.com/iv-org/invidious
cd invidious
brew services start postgresql
psql -c "CREATE ROLE kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
psql invidious kemal < config/sql/channels.sql
psql invidious kemal < config/sql/videos.sql
psql invidious kemal < config/sql/channel_videos.sql
psql invidious kemal < config/sql/users.sql
psql invidious kemal < config/sql/session_ids.sql
psql invidious kemal < config/sql/nonces.sql
psql invidious kemal < config/sql/annotations.sql
psql invidious kemal < config/sql/privacy.sql
psql invidious kemal < config/sql/playlists.sql
psql invidious kemal < config/sql/playlist_videos.sql
# Set up Invidious
shards update && shards install && crystal build src/invidious.cr --release
```
## Post-install configuration:
Detailed configuration available in the [configuration guide](./Configuration.md).
Because of various issues Invidious **must** be restarted often, at least once a day, ideally every hour.
If you use a reverse proxy, you **must** configure invidious to properly serve request through it:
`https_only: true` : if you are serving your instance via https, set it to true
`domain: domain.ext`: if you are serving your instance via a domain name, set it here
`external_port: 443`: if you are serving your instance via https, set it to 443
## Update Invidious
#### Updating a Docker install
```bash
docker-compose pull && docker-compose up && docker image prune -f
```
#### Update a manual install
```bash
sudo - invidious
cd invidious
shards update && shards install && crystal build src/invidious.cr --release
exit
systemctl restart invidious.service
```
## Usage:
```bash
./invidious
```
#### Logrotate configuration
```bash
echo "/home/invidious/invidious/invidious.log {
rotate 4
weekly
notifempty
missingok
compress
minsize 1048576
}" | tee /etc/logrotate.d/invidious.logrotate
chmod 0644 /etc/logrotate.d/invidious.logrotate
```

View file

@ -0,0 +1,87 @@
---
title: Invidious-Instances
description:
published: true
date: 2021-05-23T16:58:51.441Z
tags:
editor: markdown
dateCreated: 2021-05-23T16:58:48.431Z
---
# Public Invidious Instances:
[Uptime History provided by Uptimerobot](https://stats.uptimerobot.com/89VnzSKAn)
[Instances API](https://api.invidious.io/)
**Warning: Any public instance that isn't in this list is considered untrustworthy. Use them at your own risk.**
## List of public Invidious Instances (sorted from oldest to newest):
* [invidious.snopyta.org](https://invidious.snopyta.org) 🇫🇮
* [yewtu.be](https://yewtu.be) 🇳🇱 [![Uptime Robot status](https://img.shields.io/uptimerobot/status/m783898765-2a4efa67aa8d1c7be6b1dd9d)](https://uptime.invidious.io/784257752) - Source code/changes: https://github.com/unixfox/invidious-custom
* [invidious.kavin.rocks](https://invidious.kavin.rocks) 🇮🇳 [![Uptime Robot status](https://img.shields.io/uptimerobot/status/m786132664-f9fa738fba1c4dc2f7364f71)](https://status.kavin.rocks/786132664) [invidious-us.kavin.rocks](https://invidious-us.kavin.rocks) 🇺🇸 [![Uptime Robot status](https://img.shields.io/uptimerobot/status/m788216947-f3f63d30899a10dbe9a0338a)](https://status.kavin.rocks/788216947) (uses Cloudflare)
* [vid.puffyan.us](https://vid.puffyan.us) 🇺🇸 [![Uptime Robot status](https://img.shields.io/uptimerobot/status/m786947233-1131c3f67b9a20621b1926d3?style=plastic)](https://stats.uptimerobot.com/n7A08HGVl6/786947233)
* [invidious.namazso.eu](https://invidious.namazso.eu) 🇩🇪
* [inv.riverside.rocks](https://inv.riverside.rocks) 🇺🇸
* [invidious.osi.kr](https://invidious.osi.kr) 🇳🇱 [Status Page](https://status.osbusiness.net/report/uptime/6e47474f3737993d8a3fde06f33dc128/)
* [invidio.xamh.de](https://invidio.xamh.de) 🇩🇪 ![Uptime Robot status](https://img.shields.io/uptimerobot/status/m788804183-a33a0af7fb40e3bafa617cd8)
* [youtube.076.ne.jp](https://youtube.076.ne.jp) 🇯🇵 - Source code/changes: https://git.076.ne.jp/TechnicalSuwako/invidious-mod
* [yt.artemislena.eu](https://yt.artemislena.eu) 🇩🇪
* [tube.cthd.icu](https://tube.cthd.icu) 🇷🇸 - Source code/changes: https://gitlab.cthd.icu/cthd/invidious-custom
* [invidious.flokinet.to](https://invidious.flokinet.to) 🇷🇴
* [invidious.privacy.gd](https://invidious.privacy.gd) 🇺🇸
* [invidious.weblibre.org](https://invidious.weblibre.org) 🇨🇱
* [invidious.esmailelbob.xyz](https://invidious.esmailelbob.xyz) 🇨🇦
### Tor Onion Services:
* [c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion](http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion) 🇫🇮 (Onion of invidious.snopyta.org)
* [w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion](http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion)
* [kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion](http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion) 🇳🇱
* [grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion](http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion) 🇺🇸 (Onion of vid.puffyan.us)
* [hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion](http://hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion) 🇺🇸 (Onion of invidious-us.kavin.rocks)
* [osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion](http://osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion) 🇳🇱 (Onion of invidious.hub.ne.kr)
* [u2cvlit75owumwpy4dj2hsmvkq7nvrclkpht7xgyye2pyoxhpmclkrad.onion](http://u2cvlit75owumwpy4dj2hsmvkq7nvrclkpht7xgyye2pyoxhpmclkrad.onion) 🇺🇸 (Onion of inv.riverside.rocks)
* [2rorw2w54tr7jkasn53l5swbjnbvz3ubebhswscnc54yac6gmkxaeeqd.onion](http://2rorw2w54tr7jkasn53l5swbjnbvz3ubebhswscnc54yac6gmkxaeeqd.onion) 🇺🇸 (Onion of invidious.privacy.gd)
## Rules to have your instance in this list:
1. Instances MUST have been up for at least a month before it can be added to this list.
2. Instances MUST have been updated in the last month. An instance that hasn't been updated in the last month is considered unmaintained and is removed from the list.
3. Instances MUST have statistics (/api/v1/stats) enabled (`statistics_enabled:true` in the configuration file).
4. Instances MUST have an uptime of at least 90% ([according to uptime.invidious.io](https://uptime.invidious.io/)).
5. Instances MUST be served via domain name.
6. Instances MUST be served via HTTPS (or/and onion).
7. Instances using any DDoS Protection / MITM MUST be marked as such (eg: Cloudflare, DDoS-Guard...).
8. Instances using any type of anti-bot protection MUST be marked as such.
9. Instances MUST NOT use any type of analytics.
10. Any system whose goal is to modify the content served to the user (i.e web server HTML rewrite) is considered the same as modifying the source code.
11. Instances running a modified source code:
- MUST respect the AGPL by publishing their source code and stating their changes **before** they are be added to the list
- MUST publish any later modification in a timely manner
- MUST contain a link to both the modified and original source code of Invidious in the footer.
12. Instances MUST NOT serve ads (sponsorship links in the banner are considered ads) NOR promote products.
**NOTE:** We reserve the right to decline any instance from being added to the list, and to remove or ban any instance that repeatedly breaks the aforementioned rules.

View file

@ -0,0 +1,55 @@
---
title: Issues-with-CAPTCHA-on-Debian-and-Ubuntu
description:
published: true
date: 2021-05-23T16:58:57.747Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:51.349Z
---
#### Warning: If you use ImageMagick on Ubuntu for other services like Mastodon this guide may break them, please use [this guide](https://linuxconfig.org/how-to-install-imagemagick-7-on-ubuntu-18-04-linux) instead.
There is some issue on Debian 9 and Ubuntu 18.04 and later. It appears that the clock (the CAPTCHA) has no hands but you can see them outside the clock. You need to compile ImageMagick yourself with librsvg to solve this issue.
Thanks [Tmiland](https://github.com/tmiland) for showing us a solution at [#299](https://github.com/iv-org/invidious/issues/299)
For lazy people, a little hack is to disable CAPTCHA or use text one.
You can check if your version of ImageMagick is affected with `convert -list format`.
It should show the following if your installed version is okay.
```
SVG SVG rw+ Scalable Vector Graphics (RSVG 2.40.13)
SVGZ SVG rw+ Compressed Scalable Vector Graphics (RSVG 2.40.13)
```
If this is not the case, your version is not compiled with librsvg, then you get the following.
```
SVG SVG rw+ Scalable Vector Graphics (XML 2.9.4)
SVGZ SVG rw+ Compressed Scalable Vector Graphics (XML 2.9.4)
```
Follow the steps to fix this issue:
```bash
$ sudo apt purge imagemagick
$ cd /tmp
# check for new releases: https://github.com/ImageMagick/ImageMagick6/releases
$ wget https://github.com/ImageMagick/ImageMagick6/archive/6.9.11-19.tar.gz
$ tar -xvf 6.9.10-24.tar.gz
$ cd ImageMagick6-6.9.10-24
$ ./configure --with-rsvg
$ make
$ sudo make install
```
Set the correct path: `$ sudo ln -s /usr/local/bin/convert /usr/bin/convert`
If you get an error here that this file already exists, please execute `$ sudo apt autoremove`
Now `convert -list format` reports
SVG rw+ Scalable Vector Graphics (RSVG 2.40.16)
SVGZ rw+ Compressed Scalable Vector Graphics (RSVG 2.40.16)
Restart Invidious, just to be sure:
```bash
$ sudo systemctl restart invidious.service
```

View file

@ -0,0 +1,16 @@
---
title: Known-Exception-in-log
description:
published: true
date: 2021-05-23T16:59:00.917Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:39:56.877Z
---
In this wiki page some known exceptions from the logfile are listed. You normally do not have to worry if you see them.
#### Error reading socket: Connection reset by peer (Errno)
"Connection reset by peer" means the client disconnected before the site finished loading
#### Error writing to socket: Broken pipe (Errno)

View file

@ -0,0 +1,102 @@
---
title: List-of-URL-parameters
description:
published: true
date: 2021-05-23T16:59:05.685Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:40:01.812Z
---
A list of URL parameters for Invidious, which can automatically toggle various UI and player settings.
_This list is incomplete. You can help by expanding it._
| Parameter | Setting |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Site-wide parameters** | |
| _Dark mode_ | Configure default theme without setting cookies |
| `dark_mode=true` | Use dark theme |
| `dark_mode=false` | Use light theme |
| _Thin mode_ | Load HTML, CSS, JS and video elements (disables images) |
| `thin_mode=true` | Enabled |
| `thin_mode=false` | Disabled |
| _UI Language_ | Available locales are also listed [here](https://github.com/iv-org/invidious/blob/0.17.0/src/invidious.cr#L63-L75) |
| `hl=ar` | Arabic |
| `hl=de` | German |
| `hl=el` | Greek |
| `hl=en-US` | English |
| `hl=eo` | Esperanto |
| `hl=es` | Spanish |
| `hl=eu` | Basque |
| `hl=fr` | French |
| `hl=is` | Icelandic |
| `hl=it` | Italian |
| `hl=nb_NO` | Norwegian Bokmål |
| `hl=nl` | Dutch |
| `hl=pl` | Polish |
| `hl=ru` | Russian |
| `hl=uk` | Ukranian |
| `hl=zh-CN` | Chinese (traditional) |
| **Player parameters** | Available parameters also listed [here](https://github.com/iv-org/invidious/blob/0.17.0/src/invidious/videos.cr#L244) |
| _Annotations_ | Show legacy annotations, provided by the [Internet Archive](https://archive.org/details/youtubeannotations) |
| `iv_load_policy=1` | Show annotations |
| `iv_load_policy=3` | Hide annotations |
| _Autoplay_ | Automatically play video on load |
| `autoplay=1` | Enabled |
| `autoplay=0` | Disabled |
| _Continue_ | When video is done, automatically go to the next related video (similar to YouTubes _Autoplay_ feature) |
| `continue=1` | Enabled |
| `continue=0` | Disabled |
| _Listen_ | Play only audio portion of video |
| `listen=true` | Enabled |
| `listen=false` | Disabled |
| _Local_ | Proxy video streams, equivalent to enabling `Proxy videos?` in preferences |
| `local=true` | Enabled |
| `local=false` | Disabled |
| _Subtitles_ | List of ISO 639-1 language codes (comma-separated) |
| `subtitles=en` | English (will use `auto-generated` if native translation is unavailable) |
| _Quality_ | Default player quality |
| `quality=dash` | [DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) |
| `quality=hd720` | 720p |
| `quality=medium` | 480p |
| _Related Videos_ | Show "Related videos" tab on the right-hand side |
| `related_videos=false` | Disabled |
| _Speed_ | Default player speed, can be any positive number |
| `speed=0.5` | Play at 0.5x speed |
| `speed=2` | Play at 2x speed |
| `speed=9.34` | Play at 9.34x speed |
| _Loop_ | Loop player by default |
| `loop=1` | Enabled |
| `loop=0` | Disabled |
| _Volume_ | Default player volume, can be any whole number between 0 and 100 |
| `volume=10` | Play video at 10% volume |
| _Region_ | Provide "hint" (as ISO 3166 country code) for Invidious to load videos from the specified region |
| `region=JP` | Attempt to load video as if the user were in Japan |
| `region=DE` | Attempt to load video as if the user were in Germany |
| _Controls_ | Provide player controls |
| `controls=1` | Enabled |
| `controls=0` | Disabled |
| _Raw_ | Redirect to latest copy of video at the specified `quality` and optionally proxy video |
| `raw=1` | Enabled |
| `raw=0` | Disabled |
| _Time controls_ | Control when the player starts and stops playback. Providing `loop=1` will only loop the specified section |
| `start=TIME`, `t=TIME`, `time_continue=TIME` | Start playback at `TIME` seconds into the video. Supports `TIME` as either an integer specifying seconds or using `12h30m10s22ms` syntax. For example, `t=12m9s` is equivalent to `t=729` |
| `end=TIME` | Stop playback at either `TIME` seconds or using the above mentioned `12h56m10s22ms` syntax. |
| **Search parameters** | |
| _Region_ | Provide "hint" (as ISO 3166 country code) for Invidious to load search results from the specified region |
| `region=JP` | Attempt to load search results as if the user were in Japan |
| `region=DE` | Attempt to load search results as if the user were in Germany |
| **Trending parameters** | |
| _Trending type_ | View trending videos only in a specific category |
| `type=Default` | Default |
| `type=Music` | Music |
| `type=Gaming` | Gaming |
| `type=News` | News |
| `type=Movies` | Movies |
| _Region_ | Provide "hint" (as ISO 3166 country code) for Invidious to load trending videos from the specified region | |
| `region=JP` | Load videos that are trending in Japan |
| `region=DE` | Load videos that are trending in Germany |
| **Player Style** | |
| `player_style=invidious` | Invidious, the default |
| `player_style=youtube` | YouTube, using a centered play button and always visible video control bar |

View file

@ -0,0 +1,38 @@
---
title: NGINX-Reverse-Proxy
description:
published: true
date: 2021-05-23T16:59:09.054Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:40:07.950Z
---
This is a very basic config, secured with Let's Encrypt. Any log is disabled by default. Do not forget to replace `server_name` with your domain.
```
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name invidious.domain.tld;
access_log off;
error_log /var/log/nginx/error.log crit;
ssl_certificate /etc/letsencrypt/live/invidious.domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/invidious.domain.tld/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; # so Invidious knows domain
proxy_http_version 1.1; # to keep alive
proxy_set_header Connection ""; # to keep alive
}
if ($https = '') { return 301 https://$host$request_uri; } # if not connected to HTTPS, perma-redirect to HTTPS
}
```

54
docs/Preferences.md Normal file
View file

@ -0,0 +1,54 @@
---
title: Preferences
description:
published: true
date: 2021-05-23T16:59:12.665Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:40:12.674Z
---
Preferences for Invidious can be stored in a cookie named `PREFS`. This cookie can be set on the Invidious Preferences page.
If setting the cookie value yourself, the value must be in JSON format and then URL-encoded.
These are the preferences you can set:
```
{
"video_loop":true, // Always loop
"annotations":true, // Show annotations
"annotations_subscribed":true, // Show annotations for subscribed channels
"autoplay":true, // Autoplay current video
"continue":true, // Load next video when current video finishes
"continue_autoplay":true, // Load and autoplay next video
"listen":true, // Audio-only mode by default
"local": true, // Proxy requests via Invidious instance for privacy
"speed":1.0, // Also accepts '0.5', '1.5', '2.0'
"quality":"hd720", // Also accepts 'dash' for 1080p, 'medium', 'small'
"volume":100, // Default audio volume (0 = Min, 100 = Max)
"comments":[ // Source to use for comments; 'youtube' or 'reddit'
"youtube",
""
],
"captions":[ // Language captions in order of preference
"",
"",
""
],
"related_videos":true, // Show related videos
"redirect_feed":true, // Redirect homepage to subscription feed
"locale":"en-US", // Choose interface language
"dark_mode":true, // Use dark mode
"thin_mode":true, // Don't include pictures in page load
"player_style":"invidious", // Invidious style, the default
"player_style":"youtube", // YouTube style, using a centered play button and always visible video control bar
// For registered users (currently unused):
"max_results":40,
"sort":"published",
"latest_only":false,
"unseen_only":false,
"notifications_only":false
}
```

57
docs/Search-operators.md Normal file
View file

@ -0,0 +1,57 @@
---
title: Search-operators
description:
published: true
date: 2021-05-23T16:59:19.319Z
tags:
editor: markdown
dateCreated: 2021-01-28T20:40:22.456Z
---
Invidious supports the various search filters provided by YouTube.
Support for more user-friendly search is planned, see [#179](https://github.com/iv-org/invidious/issues/179).
Search filters are currently implemented as `key:value` operators, similar to [DuckDuckGo](https://help.duckduckgo.com/duckduckgo-help-pages/results/syntax/) and other search engines. Operators can be added to the search query to filter results, for example: [`type:playlist sort:views music`](https://invidio.us/search?q=type%3Aplaylist+sort%3Adate+music).
When using `subscriptions:true` or `channel:UCxxx` other filters are not applied.
Supported operators:
- `sort:`
- `relevance` (default)
- `rating`
- `upload_date`, `date`
- `view_count`, `views`
- `date:`
- `hour`
- `today`
- `week`
- `month`
- `year`
- `type:`
- `all` (default)
- `video`
- `channel`
- `playlist`
- `movie`
- `show`
- `duration:`
- `short`
- `long`
- `features:` Multiple can be specified, for example `features:live,4k,subtitles`
- `hd`
- `subtitles`
- `creative_commons`,`cc`
- `live`, `livestream`
- `purchased`
- `4k`
- `360`
- `location`
- `hdr`
- `channel:`, `user:`
- `UCxxxxxxxxxxxxxxxxxxxxxx`
- `author` Can be ambiguous, so using `UCID` is recommended
- `subscriptions:` If logged in, search only for videos from subscribed channels
- `true`
- `false`

45
docs/Takedowns.md Normal file
View file

@ -0,0 +1,45 @@
---
title: DMCA
description:
published: true
date: 2021-11-16T16:58:51.441Z
tags:
editor: markdown
dateCreated: 2021-11-16T16:58:48.431Z
---
While running Invidious, it is very possible you will recive a DMCA at some point. A copyright agent will probably at some point search the ID of an infringing video on a search engine and see an Invidious instance appear. At least in the United States, Invidious instances should in theory be immune to DMCA laws because of [17 U.S. Code § 512](https://www.law.cornell.edu/uscode/text/17/512) stating that a provider is not responsible for content assuming that "the material is transmitted through the system or network without modification of its content."
## Sample DMCA (United States)
```
Hello,
I am writing on behalf of {{website}}. I am the webmaster of {{website}} and all of its subdomains.
I see you are filing a claim for {{invidious instance url}}. {{invidious instance url}} hosts Invidious, a private YouTube front-end, meaning it is simply a proxy to access YouTube assets and user generated content without tracking from Google. Thus, all content is proxied from YouTube and is not stored on our servers and if YouTube chooses to remove an asset, it will no longer appear on our site.
Our {{server hosting}} {{invidious instance url}} is hosted in the United States, so the United States's laws apply. Under United States copyright law 17 U.S.C. § 512(a), part of the Digital Millennium Copyright Act, we cannot be liable for content that "is transmitted through the system or network without modification of its content."
As such, all takedown requests must be sent to YouTube, as we don't have any control on the data that they have on their servers.
Thank you,
{{name}}
```
## Sample Template (EU)
```
Hello,
I am writing on behalf of {{website}}. I am the webmaster of {{website}} and all of its subdomains.
I see you are filing a claim for {{invidious instance url}}. {{invidious instance url}} hosts Invidious, a private YouTube front-end, meaning it is simply a proxy to access YouTube assets and user generated content without tracking from Google. Thus, all content is proxied from YouTube and is not stored on our servers and if YouTube chooses to remove an asset, it will no longer appear on our site.
Our {{server hosting}} {{invidious instance url}} is hosted in the European Union, so the European Union's laws apply. Under the directive 2001/29/EC of the European Parliament and of the Council of 22 May 2001 on the harmonization of certain aspects of copyright and related rights in the information society, "temporary acts of reproduction referred to in Article 2, which are transient or incidental [and] an integral and essential part of a technological process and whose sole purpose is to enable: a transmission in a network between third parties by an intermediary" is allowed, and legal.
As such, all takedown requests must be sent to YouTube, as we don't have any control on the data that they have on their servers.
Thank you,
{{name}}
```

BIN
docs/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/images/invidious.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

35
docs/index.md Normal file
View file

@ -0,0 +1,35 @@
---
title: HOME
description:
published: true
date: 2021-05-23T16:59:25.925Z
tags:
editor: markdown
dateCreated: 2021-02-25T18:13:08.338Z
---
## General
- [Public Invidious Instances](./Invidious-Instances.md)
- [Extensions](./Extensions.md)
- [Always proxy videos through server](./Always-use-"local"-to-proxy-video-through-the-server-without-creating-an-account.md)
- [Preferences](./Preferences.md)
- [Geoblocking, available quality and DASH](./Geoblocking,-available-video-quality-and-DASH.md)
- [Using search operators](./Search-operators.md)
- [List of URL parameters](./List-of-URL-parameters.md)
- [How to deal with uMatrix](./How-to-deal-with-uMatrix.md)
## For Administrators
- [Installation](./Installation.md)
- [Configuration](./Configuration.md)
- [Apache2 Virtual Host with Reverse Proxy](./Apache2-Reverse-Proxy.md)
- [Nginx Reverse Proxy Configuration](./NGINX-Reverse-Proxy.md)
- [Database Information and Maintenance](./Database-Information-and-Maintenance.md)
- [Issues with CAPTCHA](./Issues-with-CAPTCHA-on-Debian-and-Ubuntu.md)
- [How to setup Anti-Captcha](./How-to-setup-Anti-Captcha.md)
## For Developers
- [API](./API.md)
- [Authenticated Endpoints](./Authenticated-Endpoints.md)