@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 CHANGED
@@ -6,7 +6,7 @@ A modern, lightweight, modular, and type-safe Jellyfin SDK for Node.js and the B
6
6
  [![Documentation](https://img.shields.io/badge/docs-Material%20Design%203-6f42c1.svg)](https://francofantomius.github.io/jellyfin-sdk/)
7
7
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
8
 
9
- **Current Version: `v0.4.0`** (THE PROJECT IS BEING ACTIVELY DEVELOPED. WAIT FOR VERSION 0.5.0 TO USE IT)
9
+ **Current Version: `v0.4.1`** (THE PROJECT IS BEING ACTIVELY DEVELOPED. WAIT FOR VERSION 0.5.0 TO USE IT)
10
10
 
11
11
 
12
12
  ---
package/dist/index.cjs CHANGED
@@ -1188,6 +1188,7 @@ var MediaModule = class {
1188
1188
  const qualityResolved = resolveAudioQuality(options.quality);
1189
1189
  const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
1190
1190
  const {
1191
+ mediaSourceId,
1191
1192
  static: isStatic = false,
1192
1193
  startTimeTicks = 0,
1193
1194
  container = "opus,mp3|mp3,aac,m4a,m4b,flac,wav,ogg",
@@ -1198,12 +1199,14 @@ var MediaModule = class {
1198
1199
  const endpoint = isStatic ? `/Audio/${itemId}/stream` : `/Audio/${itemId}/universal`;
1199
1200
  const url = new URL(`${serverUrl}${endpoint}`);
1200
1201
  if (token && useQueryToken) {
1202
+ url.searchParams.append("ApiKey", token);
1201
1203
  url.searchParams.append("api_key", token);
1202
1204
  url.searchParams.append("X-Emby-Token", token);
1203
1205
  }
1204
1206
  if (userId) url.searchParams.append("UserId", userId);
1205
1207
  const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
1206
1208
  if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
1209
+ if (mediaSourceId) url.searchParams.append("MediaSourceId", mediaSourceId);
1207
1210
  if (isStatic) {
1208
1211
  url.searchParams.append("static", "true");
1209
1212
  } else {
@@ -1234,6 +1237,7 @@ var MediaModule = class {
1234
1237
  const qualityResolved = resolveAudioQuality(options.quality);
1235
1238
  const maxStreamingBitrate = options.maxStreamingBitrate ?? qualityResolved.maxStreamingBitrate;
1236
1239
  const {
1240
+ mediaSourceId,
1237
1241
  startTimeTicks = 0,
1238
1242
  audioCodec = "aac,mp3",
1239
1243
  segmentLength = 3,
@@ -1241,13 +1245,16 @@ var MediaModule = class {
1241
1245
  } = options;
1242
1246
  const url = new URL(`${serverUrl}/Audio/${itemId}/master.m3u8`);
1243
1247
  if (token && useQueryToken) {
1248
+ url.searchParams.append("ApiKey", token);
1244
1249
  url.searchParams.append("api_key", token);
1245
1250
  url.searchParams.append("X-Emby-Token", token);
1246
1251
  }
1247
1252
  if (userId) url.searchParams.append("UserId", userId);
1248
1253
  const targetDeviceId = options.deviceId !== void 0 ? options.deviceId : clientInfo.deviceId;
1249
1254
  if (targetDeviceId) url.searchParams.append("DeviceId", targetDeviceId);
1250
- url.searchParams.append("MediaSourceId", itemId);
1255
+ if (mediaSourceId) {
1256
+ url.searchParams.append("MediaSourceId", mediaSourceId);
1257
+ }
1251
1258
  url.searchParams.append("AudioCodec", audioCodec);
1252
1259
  url.searchParams.append("TranscodingContainer", "ts");
1253
1260
  url.searchParams.append("TranscodingProtocol", "hls");
@@ -1293,6 +1300,7 @@ var MediaModule = class {
1293
1300
  const endpoint = container && !container.includes(",") ? `/Videos/${itemId}/stream.${container}` : `/Videos/${itemId}/stream`;
1294
1301
  const url = new URL(`${serverUrl}${endpoint}`);
1295
1302
  if (token && useQueryToken) {
1303
+ url.searchParams.append("ApiKey", token);
1296
1304
  url.searchParams.append("api_key", token);
1297
1305
  url.searchParams.append("X-Emby-Token", token);
1298
1306
  }
@@ -1358,6 +1366,7 @@ var MediaModule = class {
1358
1366
  } = options;
1359
1367
  const url = new URL(`${serverUrl}/Videos/${itemId}/master.m3u8`);
1360
1368
  if (token && useQueryToken) {
1369
+ url.searchParams.append("ApiKey", token);
1361
1370
  url.searchParams.append("api_key", token);
1362
1371
  url.searchParams.append("X-Emby-Token", token);
1363
1372
  }
@@ -1400,6 +1409,7 @@ var MediaModule = class {
1400
1409
  const sourceId = mediaSourceId || itemId;
1401
1410
  const url = new URL(`${serverUrl}/Videos/${itemId}/${sourceId}/Subtitles/${subtitleStreamIndex}/Stream.${format}`);
1402
1411
  if (token && useQueryToken) {
1412
+ url.searchParams.append("ApiKey", token);
1403
1413
  url.searchParams.append("api_key", token);
1404
1414
  }
1405
1415
  if (startTimeTicks > 0) {
@@ -1473,6 +1483,7 @@ var MediaModule = class {
1473
1483
  if (!serverUrl || !itemId) return "";
1474
1484
  const url = new URL(`${serverUrl}/Items/${itemId}/Download`);
1475
1485
  if (token && useQueryToken) {
1486
+ url.searchParams.append("ApiKey", token);
1476
1487
  url.searchParams.append("api_key", token);
1477
1488
  }
1478
1489
  if (filename) {
@@ -1519,13 +1530,17 @@ var MediaModule = class {
1519
1530
  /**
1520
1531
  * Returns authentication headers for media streaming requests (e.g., configuring hls.js xhrSetup).
1521
1532
  * Crucial for Jellyfin 12+ servers where query-based auth (?api_key=) is disabled.
1533
+ * Pass { legacy: false } to only send Authorization and avoid conflicting headers or reverse-proxy CORS rejections.
1522
1534
  */
1523
- getStreamHeaders() {
1535
+ getStreamHeaders(options = {}) {
1524
1536
  const authHeader = this.http.getAuthHeader();
1525
- return {
1526
- Authorization: authHeader,
1527
- "X-Emby-Authorization": authHeader
1537
+ const headers = {
1538
+ Authorization: authHeader
1528
1539
  };
1540
+ if (options.legacy ?? true) {
1541
+ headers["X-Emby-Authorization"] = authHeader;
1542
+ }
1543
+ return headers;
1529
1544
  }
1530
1545
  };
1531
1546
 
@@ -2857,6 +2872,7 @@ var TrickplayModule = class {
2857
2872
  const { mediaSourceId, useQueryToken = true } = options;
2858
2873
  const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/tiles.m3u8`);
2859
2874
  if (token && useQueryToken) {
2875
+ url.searchParams.append("ApiKey", token);
2860
2876
  url.searchParams.append("api_key", token);
2861
2877
  url.searchParams.append("X-Emby-Token", token);
2862
2878
  }
@@ -2875,6 +2891,7 @@ var TrickplayModule = class {
2875
2891
  const { mediaSourceId, useQueryToken = true } = options;
2876
2892
  const url = new URL(`${serverUrl}/Videos/${itemId}/Trickplay/${width}/${index}.jpg`);
2877
2893
  if (token && useQueryToken) {
2894
+ url.searchParams.append("ApiKey", token);
2878
2895
  url.searchParams.append("api_key", token);
2879
2896
  url.searchParams.append("X-Emby-Token", token);
2880
2897
  }
@@ -3065,6 +3082,7 @@ var ChaptersModule = class {
3065
3082
  } = options;
3066
3083
  const url = new URL(`${serverUrl}/Items/${itemId}/Images/Chapter/${chapterIndex}`);
3067
3084
  if (token && useQueryToken) {
3085
+ url.searchParams.append("ApiKey", token);
3068
3086
  url.searchParams.append("api_key", token);
3069
3087
  url.searchParams.append("X-Emby-Token", token);
3070
3088
  }
@@ -3749,7 +3767,7 @@ var JellyfinClient = class {
3749
3767
  this.cache = new MemoryCacheAdapter();
3750
3768
  this.clientInfo = {
3751
3769
  name: options.clientInfo?.name || "@francofantomius/jellyfin",
3752
- version: options.clientInfo?.version || "0.4.0",
3770
+ version: options.clientInfo?.version || "0.4.1",
3753
3771
  device: options.clientInfo?.device || (typeof window !== "undefined" ? "Web Browser" : "Node.js"),
3754
3772
  deviceId: options.clientInfo?.deviceId || generateDeviceId()
3755
3773
  };