Skip to content

Commit

Permalink
Got Jellyfin working pretty well
Browse files Browse the repository at this point in the history
  • Loading branch information
Prince527GitHub committed Mar 29, 2024
1 parent 5984282 commit baf3331
Show file tree
Hide file tree
Showing 39 changed files with 981 additions and 933 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
## Supported

- [Subsonic](https://www.subsonic.org/pages/index.jsp) <sub><sup>*(75%)*</sub></sup>
- [Jellyfin](https://jellyfin.org/)*
- [Jellyfin](https://jellyfin.org/) <sub><sup>*(40%)*</sub></sup>
- [Euterpe](https://listen-to-euterpe.eu/) <sub><sup>*(100%)*</sub></sup>

> *Jellyfin support is under heavy development and should not be used at the current moment.
> Note: Client compatibility varies; the percentages reflect my experience with client compatibility, not the entire API.
## Images

| ![Euterpe](https://api.serversmp.xyz/upload/66002233195e65d6b608bc1e.webp) <a href="https://github.com/ironsmile/euterpe-mobile" align="center">Euterpe</a> | ![Subtracks](https://api.serversmp.xyz/upload/66002232195e65d6b608bc1c.webp) <a href="https://github.com/austinried/subtracks" align="center">Subtracks</a> | ![Ultrasonic](https://api.serversmp.xyz/upload/6600222d195e65d6b608bc1a.webp) <a href="https://gitlab.com/ultrasonic/ultrasonic" align="center">Ultrasonic</a> |
|------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
| ![Euterpe](https://api.serversmp.xyz/upload/66002233195e65d6b608bc1e.webp) <a href="https://github.com/ironsmile/euterpe-mobile" align="center">Euterpe</a> | ![Subtracks](https://api.serversmp.xyz/upload/66002232195e65d6b608bc1c.webp) <a href="https://github.com/austinried/subtracks" align="center">Subtracks</a> | ![Ultrasonic](https://api.serversmp.xyz/upload/6600222d195e65d6b608bc1a.webp) <a href="https://gitlab.com/ultrasonic/ultrasonic" align="center">Ultrasonic</a> | ![Finamp](https://api.serversmp.xyz/upload/6606fcd5195e65d6b608c1e6.webp) <a href="https://github.com/jmshrv/finamp" align="center">Finamp</a> |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|

## Docker

Expand Down
2 changes: 1 addition & 1 deletion config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"url": "http://ip:port", // url of this api
"api": { // enable of disable api implementation
"subsonic": true,
"jellyfin": false, // I would disable jellyfin for now, its a work in progress
"jellyfin": true,
"euterpe": true
},
"users": [ // list of users, if the array is empty then authentication is disabled
Expand Down
2 changes: 1 addition & 1 deletion config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"url": "http://ip:port",
"api": {
"subsonic": true,
"jellyfin": false,
"jellyfin": true,
"euterpe": true
},
"users": [
Expand Down
33 changes: 12 additions & 21 deletions router/jellyfin/artists.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,23 @@ const express = require("express");
const router = express.Router();

router.get("/albumartists", async(req, res) => {
let { StartIndex, Limit } = req.query;
const { StartIndex = "0", Limit = "50" } = req.query;

const artists = await (await fetch(`${global.config.music}/getall/artists?start=${StartIndex || '0'}&limit=${Limit || '50'}&sortby=created_date&reverse=1`)).json();
const artists = await (await fetch(`${global.config.music}/getall/artists?start=${StartIndex}&limit=${Limit}&sortby=created_date&reverse=1`)).json();

const output = artists.items.map(artist => ({
"Name": artist.name,
"ServerId": "server",
"Id": artist.artisthash,
"SortName": artist.name,
"ChannelId": null,
"RunTimeTicks": 0,
"Type": "MusicArtist",
"UserData": {
"PlaybackPositionTicks": 0,
"PlayCount": 0,
"IsFavorite": false,
"Played": false
},
"PrimaryImageAspectRatio": 1,
"LocationType": "FileSystem"
const items = artists.items.map(artist => ({
Name: artist.name,
Id: artist.artisthash,
Type: "MusicArtist",
UserData: { PlaybackPositionTicks: 0, PlayCount: 0, IsFavorite: false, Played: false },
PrimaryImageAspectRatio: 1,
LocationType: "FileSystem"
}));

res.json({
"Items": output,
"TotalRecordCount": artists.total,
"StartIndex": 0
Items: items,
TotalRecordCount: artists.total,
StartIndex: Number(StartIndex)
});
});

Expand Down
2 changes: 1 addition & 1 deletion router/jellyfin/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const router = express.Router();

const proxy = require("../../packages/proxy");

router.get("/:id/universal", async(req, res) => {
router.get("/:id/*", async(req, res) => {
const id = req.params.id;

const url = `${global.config.music}/file/${id}`;
Expand Down
9 changes: 9 additions & 0 deletions router/jellyfin/branding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const express = require("express");
const router = express.Router();

router.all("/*", (req, res) => res.send("ok"));

module.exports = {
router: router,
name: "branding"
}
34 changes: 14 additions & 20 deletions router/jellyfin/displaypreferences.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
const express = require("express");
const router = express.Router();

router.route("/usersettings")
.post(userSettings)
.get(userSettings);

function userSettings(req, res) {
res.json({
"Id": "user",
"SortBy": "SortName",
"RememberIndexing": true,
"PrimaryImageHeight": 0,
"PrimaryImageWidth": 0,
"CustomPrefs": {},
"ScrollDirection": "Horizontal",
"ShowBackdrop": false,
"RememberSorting": true,
"SortOrder": "Ascending",
"ShowSidebar": true,
"Client": "emby"
});
}
router.all("/usersettings", async(req, res) => res.json({
Id: "user",
SortBy: "SortName",
RememberIndexing: true,
PrimaryImageHeight: 0,
PrimaryImageWidth: 0,
CustomPrefs: {},
ScrollDirection: "Horizontal",
ShowBackdrop: false,
RememberSorting: true,
SortOrder: "Ascending",
ShowSidebar: true,
Client: "emby"
}))

module.exports = {
router: router,
Expand Down
6 changes: 3 additions & 3 deletions router/jellyfin/genres.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const express = require("express");
const router = express.Router();

router.all("/*", (req, res) => res.json({
"Items": [],
"TotalRecordCount": 0,
"StartIndex": 0
Items: [],
TotalRecordCount: 0,
StartIndex: 0
}));

module.exports = {
Expand Down
28 changes: 26 additions & 2 deletions router/jellyfin/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
const { getFileList } = require("../../packages/files");

async function checkAuth(req, res, next) {
const login = ["/branding/configuration", "/displaypreferences/usersettings", "/playback/bitratetest", "/quickconnect/enabled", "/sessions/capabilities/full", "/system/endpoint", "/system/info", "/system/info/public", "/users/authenticatebyname", "/users/public", "/users/user", "/userviews/","/branding/css"];

const { server } = global.config;

if (server.users.length && !login.includes(`${req.baseUrl.toLowerCase()}${req.path.toLowerCase()}`)) {
const tokenHeader = req.headers["x-emby-token"] || req.headers["x-emby-authorization"] || req.headers["x-mediabrowser-token"] || req.headers["authorization"] || req.query.api_key || req.query.ApiKey;
if (!tokenHeader) return res.sendStatus(401);

const token = tokenHeader.includes('Token=') ? tokenHeader.match(/Token="([^"]*)"/)?.[1] : tokenHeader;
if (!token) return res.sendStatus(401);

const [username, password] = token.split("@");
if (!server.users.some(user => user.username === username && user.password === password)) return res.sendStatus(401);
}

next();
}

module.exports = async(app) => {
const routeFiles = await getFileList(`${process.cwd()}/router/jellyfin`, { type: ".js", recursively: false });

routeFiles.map((value) => {
if (!value.includes("index.js")) {
const { name, router } = require(value);

app.use(`/${name}`, router);
const exclude = ["audio", "items"];

if (!exclude.includes(name)) app.use(`/${name}`, checkAuth, router);
else app.use(`/${name}`, router);
}
});
}
}

module.exports.checkAuth = checkAuth;
Loading

0 comments on commit baf3331

Please sign in to comment.