@francofantomius/jellyfin 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +24 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +24 -6
- package/dist/index.js.map +1 -1
- package/llms.txt +542 -0
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -306,10 +306,11 @@ interface AudioStreamOptions {
|
|
|
306
306
|
transcodingContainer?: string;
|
|
307
307
|
audioCodec?: string;
|
|
308
308
|
deviceId?: string;
|
|
309
|
+
mediaSourceId?: string;
|
|
309
310
|
/**
|
|
310
|
-
* Whether to include the
|
|
311
|
+
* Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
|
|
311
312
|
* Defaults to true for HTML5 <audio> tag compatibility.
|
|
312
|
-
*
|
|
313
|
+
* Set to false when providing modern Authorization headers to avoid conflicting authentication credentials in Jellyfin 12+.
|
|
313
314
|
*/
|
|
314
315
|
useQueryToken?: boolean;
|
|
315
316
|
}
|
|
@@ -320,10 +321,11 @@ interface AudioHlsStreamOptions {
|
|
|
320
321
|
audioCodec?: string;
|
|
321
322
|
segmentLength?: number;
|
|
322
323
|
deviceId?: string;
|
|
324
|
+
mediaSourceId?: string;
|
|
323
325
|
/**
|
|
324
|
-
* Whether to include the
|
|
326
|
+
* Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
|
|
325
327
|
* Defaults to true for legacy compatibility.
|
|
326
|
-
*
|
|
328
|
+
* Set to false when players (e.g. hls.js) are configured with Authorization headers via xhrSetup to prevent 401s from conflicting auth methods in Jellyfin 12+.
|
|
327
329
|
*/
|
|
328
330
|
useQueryToken?: boolean;
|
|
329
331
|
}
|
|
@@ -1146,8 +1148,11 @@ declare class MediaModule {
|
|
|
1146
1148
|
/**
|
|
1147
1149
|
* Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
|
|
1148
1150
|
* Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
|
|
1151
|
+
* Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
|
|
1149
1152
|
*/
|
|
1150
|
-
getStreamHeaders(
|
|
1153
|
+
getStreamHeaders(options?: {
|
|
1154
|
+
legacy?: boolean;
|
|
1155
|
+
}): Record<string, string>;
|
|
1151
1156
|
}
|
|
1152
1157
|
|
|
1153
1158
|
declare class LyricsModule {
|
package/dist/index.d.ts
CHANGED
|
@@ -306,10 +306,11 @@ interface AudioStreamOptions {
|
|
|
306
306
|
transcodingContainer?: string;
|
|
307
307
|
audioCodec?: string;
|
|
308
308
|
deviceId?: string;
|
|
309
|
+
mediaSourceId?: string;
|
|
309
310
|
/**
|
|
310
|
-
* Whether to include the
|
|
311
|
+
* Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
|
|
311
312
|
* Defaults to true for HTML5 <audio> tag compatibility.
|
|
312
|
-
*
|
|
313
|
+
* Set to false when providing modern Authorization headers to avoid conflicting authentication credentials in Jellyfin 12+.
|
|
313
314
|
*/
|
|
314
315
|
useQueryToken?: boolean;
|
|
315
316
|
}
|
|
@@ -320,10 +321,11 @@ interface AudioHlsStreamOptions {
|
|
|
320
321
|
audioCodec?: string;
|
|
321
322
|
segmentLength?: number;
|
|
322
323
|
deviceId?: string;
|
|
324
|
+
mediaSourceId?: string;
|
|
323
325
|
/**
|
|
324
|
-
* Whether to include the
|
|
326
|
+
* Whether to include the authentication token in the URL query parameters (ApiKey, api_key, X-Emby-Token).
|
|
325
327
|
* Defaults to true for legacy compatibility.
|
|
326
|
-
*
|
|
328
|
+
* Set to false when players (e.g. hls.js) are configured with Authorization headers via xhrSetup to prevent 401s from conflicting auth methods in Jellyfin 12+.
|
|
327
329
|
*/
|
|
328
330
|
useQueryToken?: boolean;
|
|
329
331
|
}
|
|
@@ -1146,8 +1148,11 @@ declare class MediaModule {
|
|
|
1146
1148
|
/**
|
|
1147
1149
|
* Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
|
|
1148
1150
|
* Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
|
|
1151
|
+
* Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
|
|
1149
1152
|
*/
|
|
1150
|
-
getStreamHeaders(
|
|
1153
|
+
getStreamHeaders(options?: {
|
|
1154
|
+
legacy?: boolean;
|
|
1155
|
+
}): Record<string, string>;
|
|
1151
1156
|
}
|
|
1152
1157
|
|
|
1153
1158
|
declare class LyricsModule {
|
package/dist/index.js
CHANGED
|
@@ -1186,6 +1186,7 @@ var MediaModule = class {
|
|
|
1186
1186
|
const qualityResolved = resolveAudioQuality(options.quality);
|
|
1187
1187
|
const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
|
|
1188
1188
|
const {
|
|
1189
|
+
mediaSourceId,
|
|
1189
1190
|
static: isStatic = false,
|
|
1190
1191
|
startTimeTicks = 0,
|
|
1191
1192
|
container = "opus,mp3|mp3,aac,m4a,m4b,flac,wav,ogg",
|
|
@@ -1196,12 +1197,14 @@ var MediaModule = class {
|
|
|
1196
1197
|
const endpoint = isStatic ? `/Audio/${itemId}/stream` : `/Audio/${itemId}/universal`;
|
|
1197
1198
|
const url = new URL(`${serverUrl}${endpoint}`);
|
|
1198
1199
|
if (token && useQueryToken) {
|
|
1200
|
+
url.searchParams.append("ApiKey", token);
|
|
1199
1201
|
url.searchParams.append("api_key", token);
|
|
1200
1202
|
url.searchParams.append("X-Emby-Token", token);
|
|
1201
1203
|
}
|
|
1202
1204
|
if (userId) url.searchParams.append("UserId", userId);
|
|
1203
1205
|
const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
|
|
1204
1206
|
if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
|
|
1207
|
+
if (mediaSourceId) url.searchParams.append("MediaSourceId", mediaSourceId);
|
|
1205
1208
|
if (isStatic) {
|
|
1206
1209
|
url.searchParams.append("static", "true");
|
|
1207
1210
|
} else {
|
|
@@ -1232,6 +1235,7 @@ var MediaModule = class {
|
|
|
1232
1235
|
const qualityResolved = resolveAudioQuality(options.quality);
|
|
1233
1236
|
const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
|
|
1234
1237
|
const {
|
|
1238
|
+
mediaSourceId,
|
|
1235
1239
|
startTimeTicks = 0,
|
|
1236
1240
|
audioCodec = "aac,mp3",
|
|
1237
1241
|
segmentLength = 3,
|
|
@@ -1239,13 +1243,16 @@ var MediaModule = class {
|
|
|
1239
1243
|
} = options;
|
|
1240
1244
|
const url = new URL(`${serverUrl}/Audio/${itemId}/master.m3u8`);
|
|
1241
1245
|
if (token && useQueryToken) {
|
|
1246
|
+
url.searchParams.append("ApiKey", token);
|
|
1242
1247
|
url.searchParams.append("api_key", token);
|
|
1243
1248
|
url.searchParams.append("X-Emby-Token", token);
|
|
1244
1249
|
}
|
|
1245
1250
|
if (userId) url.searchParams.append("UserId", userId);
|
|
1246
1251
|
const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
|
|
1247
1252
|
if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
|
|
1248
|
-
|
|
1253
|
+
if (mediaSourceId) {
|
|
1254
|
+
url.searchParams.append("MediaSourceId", mediaSourceId);
|
|
1255
|
+
}
|
|
1249
1256
|
url.searchParams.append("AudioCodec", audioCodec);
|
|
1250
1257
|
url.searchParams.append("TranscodingContainer", "ts");
|
|
1251
1258
|
url.searchParams.append("TranscodingProtocol", "hls");
|
|
@@ -1291,6 +1298,7 @@ var MediaModule = class {
|
|
|
1291
1298
|
const endpoint = container && !container.includes(",") ? `/Videos/${itemId}/stream.${container}` : `/Videos/${itemId}/stream`;
|
|
1292
1299
|
const url = new URL(`${serverUrl}${endpoint}`);
|
|
1293
1300
|
if (token && useQueryToken) {
|
|
1301
|
+
url.searchParams.append("ApiKey", token);
|
|
1294
1302
|
url.searchParams.append("api_key", token);
|
|
1295
1303
|
url.searchParams.append("X-Emby-Token", token);
|
|
1296
1304
|
}
|
|
@@ -1356,6 +1364,7 @@ var MediaModule = class {
|
|
|
1356
1364
|
} = options;
|
|
1357
1365
|
const url = new URL(`${serverUrl}/Videos/${itemId}/master.m3u8`);
|
|
1358
1366
|
if (token && useQueryToken) {
|
|
1367
|
+
url.searchParams.append("ApiKey", token);
|
|
1359
1368
|
url.searchParams.append("api_key", token);
|
|
1360
1369
|
url.searchParams.append("X-Emby-Token", token);
|
|
1361
1370
|
}
|
|
@@ -1398,6 +1407,7 @@ var MediaModule = class {
|
|
|
1398
1407
|
const sourceId = mediaSourceId || itemId;
|
|
1399
1408
|
const url = new URL(`${serverUrl}/Videos/${itemId}/${sourceId}/Subtitles/${subtitleStreamIndex}/Stream.${format}`);
|
|
1400
1409
|
if (token && useQueryToken) {
|
|
1410
|
+
url.searchParams.append("ApiKey", token);
|
|
1401
1411
|
url.searchParams.append("api_key", token);
|
|
1402
1412
|
}
|
|
1403
1413
|
if (startTimeTicks > 0) {
|
|
@@ -1471,6 +1481,7 @@ var MediaModule = class {
|
|
|
1471
1481
|
if (!serverUrl || !itemId) return "";
|
|
1472
1482
|
const url = new URL(`${serverUrl}/Items/${itemId}/Download`);
|
|
1473
1483
|
if (token && useQueryToken) {
|
|
1484
|
+
url.searchParams.append("ApiKey", token);
|
|
1474
1485
|
url.searchParams.append("api_key", token);
|
|
1475
1486
|
}
|
|
1476
1487
|
if (filename) {
|
|
@@ -1517,13 +1528,17 @@ var MediaModule = class {
|
|
|
1517
1528
|
/**
|
|
1518
1529
|
* Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
|
|
1519
1530
|
* Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
|
|
1531
|
+
* Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
|
|
1520
1532
|
*/
|
|
1521
|
-
getStreamHeaders() {
|
|
1533
|
+
getStreamHeaders(options = {}) {
|
|
1522
1534
|
const authHeader = this.http.getAuthHeader();
|
|
1523
|
-
|
|
1524
|
-
Authorization: authHeader
|
|
1525
|
-
"X-Emby-Authorization": authHeader
|
|
1535
|
+
const headers = {
|
|
1536
|
+
Authorization: authHeader
|
|
1526
1537
|
};
|
|
1538
|
+
if (options.legacy ?? true) {
|
|
1539
|
+
headers["X-Emby-Authorization"] = authHeader;
|
|
1540
|
+
}
|
|
1541
|
+
return headers;
|
|
1527
1542
|
}
|
|
1528
1543
|
};
|
|
1529
1544
|
|
|
@@ -2855,6 +2870,7 @@ var TrickplayModule = class {
|
|
|
2855
2870
|
const { mediaSourceId, useQueryToken = true } = options;
|
|
2856
2871
|
const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/tiles.m3u8`);
|
|
2857
2872
|
if (token && useQueryToken) {
|
|
2873
|
+
url.searchParams.append("ApiKey", token);
|
|
2858
2874
|
url.searchParams.append("api_key", token);
|
|
2859
2875
|
url.searchParams.append("X-Emby-Token", token);
|
|
2860
2876
|
}
|
|
@@ -2873,6 +2889,7 @@ var TrickplayModule = class {
|
|
|
2873
2889
|
const { mediaSourceId, useQueryToken = true } = options;
|
|
2874
2890
|
const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/${index}.jpg`);
|
|
2875
2891
|
if (token && useQueryToken) {
|
|
2892
|
+
url.searchParams.append("ApiKey", token);
|
|
2876
2893
|
url.searchParams.append("api_key", token);
|
|
2877
2894
|
url.searchParams.append("X-Emby-Token", token);
|
|
2878
2895
|
}
|
|
@@ -3063,6 +3080,7 @@ var ChaptersModule = class {
|
|
|
3063
3080
|
} = options;
|
|
3064
3081
|
const url = new URL(`${serverUrl}/Items/${itemId}/Images/Chapter/${chapterIndex}`);
|
|
3065
3082
|
if (token && useQueryToken) {
|
|
3083
|
+
url.searchParams.append("ApiKey", token);
|
|
3066
3084
|
url.searchParams.append("api_key", token);
|
|
3067
3085
|
url.searchParams.append("X-Emby-Token", token);
|
|
3068
3086
|
}
|
|
@@ -3747,7 +3765,7 @@ var JellyfinClient = class {
|
|
|
3747
3765
|
this.cache = new MemoryCacheAdapter();
|
|
3748
3766
|
this.clientInfo = {
|
|
3749
3767
|
name: options.clientInfo?.name || "@francofantomius/jellyfin",
|
|
3750
|
-
version: options.clientInfo?.version || "0.4.
|
|
3768
|
+
version: options.clientInfo?.version || "0.4.1",
|
|
3751
3769
|
device: options.clientInfo?.device || (typeof window !== "undefined" ? "Web Browser" : "Node.js"),
|
|
3752
3770
|
deviceId: options.clientInfo?.deviceId || generateDeviceId()
|
|
3753
3771
|
};
|