Add-ons for Frunk.tv
An add-on brings films, series or channels to Frunk.tv: to Movies & Series and to TV, in the Android app, on the web and in the car. Anyone can make one. It is a set of JSON files asked for over https: Frunk.tv reads them and shows them, and never runs any of the add-on's code. This page explains the format.
How it works
- The user opens the add-on's install link, or pastes its address in Movies & Series («+»), in the car or sending it from their phone with a QR code.
- Frunk.tv shows them its name, who says they publish it, the domain it comes from, its contact and what it brings, and asks them to confirm.
- While they browse, the device asks the add-on for its lists, details and links directly: nothing goes through Frunk.tv's server. Requests carry no cookies and nothing of the user's account.
- Films and series show in Movies & Series. Live channels show in TV, next to the IPTV lists, and are always free in Frunk.tv.
The manifest
A JSON file served over https with Access-Control-Allow-Origin: * (the web asks for it from
frunk.tv). The other routes are relative to the manifest's folder.
{
"frunk_addon": 1,
"id": "org.example.cinema",
"name": "Example cinema",
"description": "What it has, in a sentence or two.",
"version": "1.0.0",
"publisher": { "name": "Example", "url": "https://example.org", "contact": "[email protected]" },
"logo": "logo.png",
"types": ["movie", "series", "channel"],
"resources": ["catalog", "meta", "stream", "search", "live"],
"catalogs": [
{ "type": "movie", "id": "new", "name": "New films", "search": true,
"filters": [{ "key": "genre", "name": "Genre", "options": ["Comedy", "Drama"] }] },
{ "type": "series", "id": "all", "name": "Series" },
{ "type": "channel", "id": "channels", "name": "Channels", "live": true }
],
"settings": [],
"debrid": false
}
frunk_addon: the format's version,1.id: lowercase and dots, stable.name(up to 60 characters),description(up to 400) andversion(only shown).publisher: required, withnameandcontact(an email or an https address) so that a rights holder can write to you.types:movie,seriesorchannel.catalogs: your lists.search: trueif it can be searched;filters, up to three;live: trueon one of live channels.debrid:trueif the links open with the user's own AllDebrid account.private(optional):truemarks the add-on as private; the app does not offer to share it.
The routes
All are GET, all end in .json and all answer JSON. So an add-on can be a folder of
static files (GitHub Pages, for instance); it only loses search and pages.
catalog/<type>/<catalog>.json?skip=&search=&genre=
meta/<type>/<id>.json
stream/<type>/<id>.json
epg/<channel id>.json?from=&to=
catalog:{"items": [{"id", "name", "year", "poster", "rating", "quality", "genres"}]}, up to 100 a page.skipsays how many have already arrived; the list ends with an empty page or one with nothing new.meta:{"meta": {…, "description", "background", "ids": {"imdb", "tmdb"}, "videos": [{"id", "season", "episode", "name"}]}}. An episode is<series>:<season>:<episode>.epg:{"programmes": [{"start", "end", "title", "description"}]}, times in seconds since 1970.- Every request carries
lang, the user's language, in case you want to answer in it.
The links
stream is asked for right before playing, so links may be signed and short-lived:
{ "streams": [{
"url": "https://cdn.example.org/film/master.m3u8",
"kind": "hls",
"name": "1080p · English",
"quality": "1080p",
"audio": ["en", "es"],
"subtitles": [{ "lang": "en", "url": "https://cdn.example.org/film/en.vtt", "format": "vtt" }],
"headers": { "Referer": "https://example.org/" },
"drm": { "system": "widevine", "license": "https://license.example.org/wv" },
"live": false
}] }
url: always http(s). No torrents, no other schemes.kind:hls,dash,mp4ormpegts.headersanddrm(Widevine or ClearKey) only work in the app; the web and the car drop that link. So does DASH. If you want it seen in the car, give an HLS without headers too.- WebVTT subtitles show everywhere; SRT ones, only in the app.
Settings
If your add-on needs something from the user (their region, their account on your service), declare it in
settings and Frunk.tv draws the form:
"settings": [
{ "key": "region", "type": "select", "name": "Region", "options": ["us", "uk"], "default": "us" },
{ "key": "user", "type": "text", "name": "User", "required": true },
{ "key": "pass", "type": "password", "name": "Password", "required": true }
]
The values are kept on the user's device and reach you in the path, before the resource:
c/<settings>/catalog/…, with <settings> the values' JSON in base64url.
Add-on repositories
If you publish several add-ons, you can gather them in a repository. It installs with the same link as an add-on, and adding it installs nothing: each add-on is installed on its own, with its own confirmation.
{
"frunk_addon_repo": 1,
"id": "org.example.repo",
"name": "Example add-ons",
"publisher": { "name": "Example", "contact": "[email protected]" },
"addons": [
{ "manifest": "cinema/manifest.json", "name": "Example cinema", "types": ["movie", "series"] }
]
}
The install link
https://frunk.tv/#/addons/add/ followed by the manifest's (or the repository's) address, encoded
with encodeURIComponent. To open it straight in the Android app, use
https://frunk.tv/addon?m= with the same address.
A catalog in a single file (the catalog format) is an add-on too: a manifest with
"frunk_addon": 1 and "bundle" instead of routes is treated as a catalog, and
frunk_catalog manifests keep working.
Rules Frunk.tv sets
- An add-on's live channels show in TV and are free in Frunk.tv: never behind a payment.
- Nothing of an add-on is behind a payment in Frunk.tv, and Frunk.tv does not sell, charge for or promote add-ons.
- Frunk.tv stops opening an add-on or a repository when the rights holder of what it offers asks.