aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs2
-rw-r--r--Emby.Server.Implementations/Localization/Core/id.json7
-rw-r--r--Emby.Server.Implementations/Localization/Core/sk.json31
-rw-r--r--Emby.Server.Implementations/Localization/Core/uk.json9
-rw-r--r--Jellyfin.Api/Controllers/MediaInfoController.cs58
-rw-r--r--Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs86
-rw-r--r--Jellyfin.Api/Models/VideoDtos/DeviceProfileDto.cs15
-rw-r--r--MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs20
-rw-r--r--MediaBrowser.Common/Json/JsonDefaults.cs1
9 files changed, 177 insertions, 52 deletions
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index 2de447ad9..f7507e6ba 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -63,7 +63,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
var extension = "ts";
var requiresRemux = false;
- var contentType = response.Content.Headers.ContentType.ToString();
+ var contentType = response.Content.Headers.ContentType?.ToString() ?? string.Empty;
if (contentType.IndexOf("matroska", StringComparison.OrdinalIgnoreCase) != -1)
{
requiresRemux = true;
diff --git a/Emby.Server.Implementations/Localization/Core/id.json b/Emby.Server.Implementations/Localization/Core/id.json
index ef3ed2580..105ef7be9 100644
--- a/Emby.Server.Implementations/Localization/Core/id.json
+++ b/Emby.Server.Implementations/Localization/Core/id.json
@@ -112,5 +112,10 @@
"TaskRefreshPeople": "Muat ulang Orang",
"TaskCleanLogsDescription": "Menghapus file log yang lebih dari {0} hari.",
"TaskCleanLogs": "Bersihkan Log Direktori",
- "TaskRefreshLibrary": "Pindai Pustaka Media"
+ "TaskRefreshLibrary": "Pindai Pustaka Media",
+ "TaskCleanActivityLogDescription": "Menghapus log aktivitas yang lebih tua dari umur yang dikonfigurasi.",
+ "TaskCleanActivityLog": "Bersihkan Log Aktivitas",
+ "Undefined": "Tidak terdefinisi",
+ "Forced": "Dipaksa",
+ "Default": "Bawaan"
}
diff --git a/Emby.Server.Implementations/Localization/Core/sk.json b/Emby.Server.Implementations/Localization/Core/sk.json
index 8e75b358c..99fbd3954 100644
--- a/Emby.Server.Implementations/Localization/Core/sk.json
+++ b/Emby.Server.Implementations/Localization/Core/sk.json
@@ -15,13 +15,13 @@
"Favorites": "Obľúbené",
"Folders": "Priečinky",
"Genres": "Žánre",
- "HeaderAlbumArtists": "Umelci albumu",
+ "HeaderAlbumArtists": "Interpreti albumu",
"HeaderContinueWatching": "Pokračovať v pozeraní",
"HeaderFavoriteAlbums": "Obľúbené albumy",
- "HeaderFavoriteArtists": "Obľúbení umelci",
+ "HeaderFavoriteArtists": "Obľúbení interpreti",
"HeaderFavoriteEpisodes": "Obľúbené epizódy",
"HeaderFavoriteShows": "Obľúbené seriály",
- "HeaderFavoriteSongs": "Obľúbené piesne",
+ "HeaderFavoriteSongs": "Obľúbené skladby",
"HeaderLiveTV": "Živá TV",
"HeaderNextUp": "Nasleduje",
"HeaderRecordingGroups": "Skupiny nahrávok",
@@ -33,13 +33,13 @@
"LabelRunningTimeValue": "Dĺžka: {0}",
"Latest": "Najnovšie",
"MessageApplicationUpdated": "Jellyfin Server bol aktualizovaný",
- "MessageApplicationUpdatedTo": "Jellyfin Server bol aktualizový na verziu {0}",
+ "MessageApplicationUpdatedTo": "Jellyfin Server bol aktualizovaný na verziu {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "Sekcia {0} konfigurácie servera bola aktualizovaná",
"MessageServerConfigurationUpdated": "Konfigurácia servera bola aktualizovaná",
"MixedContent": "Zmiešaný obsah",
"Movies": "Filmy",
"Music": "Hudba",
- "MusicVideos": "Hudobné videá",
+ "MusicVideos": "Hudobné videoklipy",
"NameInstallFailed": "Inštalácia {0} zlyhala",
"NameSeasonNumber": "Séria {0}",
"NameSeasonUnknown": "Neznáma séria",
@@ -71,7 +71,7 @@
"ScheduledTaskStartedWithName": "{0} zahájených",
"ServerNameNeedsToBeRestarted": "{0} vyžaduje reštart",
"Shows": "Seriály",
- "Songs": "Piesne",
+ "Songs": "Skladby",
"StartupEmbyServerIsLoading": "Jellyfin Server sa spúšťa. Prosím, skúste to o chvíľu znova.",
"SubtitleDownloadFailureForItem": "Sťahovanie titulkov pre {0} zlyhalo",
"SubtitleDownloadFailureFromForItem": "Sťahovanie titulkov z {0} pre {1} zlyhalo",
@@ -89,29 +89,34 @@
"UserPolicyUpdatedWithName": "Používateľské zásady pre {0} boli aktualizované",
"UserStartedPlayingItemWithValues": "{0} spustil prehrávanie {1} na {2}",
"UserStoppedPlayingItemWithValues": "{0} ukončil prehrávanie {1} na {2}",
- "ValueHasBeenAddedToLibrary": "{0} bol pridané do vašej knižnice médií",
+ "ValueHasBeenAddedToLibrary": "{0} bol pridaný do vašej knižnice médií",
"ValueSpecialEpisodeName": "Špeciál - {0}",
"VersionNumber": "Verzia {0}",
"TaskDownloadMissingSubtitlesDescription": "Vyhľadá na internete chýbajúce titulky podľa toho, ako sú nakonfigurované metadáta.",
"TaskDownloadMissingSubtitles": "Stiahnuť chýbajúce titulky",
"TaskRefreshChannelsDescription": "Obnoví informácie o internetových kanáloch.",
"TaskRefreshChannels": "Obnoviť kanály",
- "TaskCleanTranscodeDescription": "Vymaže súbory transkódovania, ktoré sú staršie ako jeden deň.",
- "TaskCleanTranscode": "Vyčistiť priečinok pre transkódovanie",
+ "TaskCleanTranscodeDescription": "Vymaže prekódované súbory, ktoré sú staršie ako jeden deň.",
+ "TaskCleanTranscode": "Vyčistiť priečinok pre prekódovanie",
"TaskUpdatePluginsDescription": "Stiahne a nainštaluje aktualizácie pre zásuvné moduly, ktoré sú nastavené tak, aby sa aktualizovali automaticky.",
"TaskUpdatePlugins": "Aktualizovať zásuvné moduly",
"TaskRefreshPeopleDescription": "Aktualizuje metadáta pre hercov a režisérov vo vašej mediálnej knižnici.",
"TaskRefreshPeople": "Obnoviť osoby",
- "TaskCleanLogsDescription": "Vymaže log súbory, ktoré su staršie ako {0} deň/dni/dní.",
+ "TaskCleanLogsDescription": "Vymaže log súbory, ktoré sú staršie ako {0} deň/dni/dní.",
"TaskCleanLogs": "Vyčistiť priečinok s logmi",
"TaskRefreshLibraryDescription": "Hľadá vo vašej mediálnej knižnici nové súbory a obnovuje metadáta.",
"TaskRefreshLibrary": "Prehľadávať knižnicu medií",
"TaskRefreshChapterImagesDescription": "Vytvorí náhľady pre videá, ktoré majú kapitoly.",
"TaskRefreshChapterImages": "Extrahovať obrázky kapitol",
- "TaskCleanCacheDescription": "Vymaže cache súbory, ktoré nie sú už potrebné pre systém.",
- "TaskCleanCache": "Vyčistiť Cache priečinok",
+ "TaskCleanCacheDescription": "Vymaže súbory vyrovnávacej pamäte, ktoré už nie sú potrebné pre systém.",
+ "TaskCleanCache": "Vyčistiť priečinok vyrovnávacej pamäte",
"TasksChannelsCategory": "Internetové kanály",
"TasksApplicationCategory": "Aplikácia",
"TasksLibraryCategory": "Knižnica",
- "TasksMaintenanceCategory": "Údržba"
+ "TasksMaintenanceCategory": "Údržba",
+ "TaskCleanActivityLogDescription": "Vymaže záznamy aktivít v logu, ktoré sú staršie ako zadaná doba.",
+ "TaskCleanActivityLog": "Vyčistiť log aktivít",
+ "Undefined": "Nedefinované",
+ "Forced": "Vynútené",
+ "Default": "Predvolené"
}
diff --git a/Emby.Server.Implementations/Localization/Core/uk.json b/Emby.Server.Implementations/Localization/Core/uk.json
index 06cc5f633..b6073bf6a 100644
--- a/Emby.Server.Implementations/Localization/Core/uk.json
+++ b/Emby.Server.Implementations/Localization/Core/uk.json
@@ -27,7 +27,7 @@
"Channels": "Канали",
"CameraImageUploadedFrom": "Нова фотографія завантажена з {0}",
"Books": "Книги",
- "AuthenticationSucceededWithUserName": "{0} успішно авторизований",
+ "AuthenticationSucceededWithUserName": "{0} успішно автентифіковано",
"Artists": "Виконавці",
"Application": "Додаток",
"AppDeviceValues": "Додаток: {0}, Пристрій: {1}",
@@ -112,5 +112,10 @@
"MessageServerConfigurationUpdated": "Конфігурація сервера оновлена",
"MessageNamedServerConfigurationUpdatedWithValue": "Розділ конфігурації сервера {0} оновлено",
"Inherit": "Успадкувати",
- "HeaderRecordingGroups": "Групи запису"
+ "HeaderRecordingGroups": "Групи запису",
+ "Forced": "Примусово",
+ "TaskCleanActivityLogDescription": "Видаляє старші за встановлений термін записи з журналу активності.",
+ "TaskCleanActivityLog": "Очистити журнал активності",
+ "Undefined": "Не визначено",
+ "Default": "За замовчуванням"
}
diff --git a/Jellyfin.Api/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs
index b42e6686e..a76dc057a 100644
--- a/Jellyfin.Api/Controllers/MediaInfoController.cs
+++ b/Jellyfin.Api/Controllers/MediaInfoController.cs
@@ -8,7 +8,6 @@ using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.MediaInfoDtos;
-using Jellyfin.Api.Models.VideoDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
@@ -81,6 +80,9 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets live playback media info for an item.
/// </summary>
+ /// <remarks>
+ /// For backwards compatibility parameters can be sent via Query or Body, with Query having higher precedence.
+ /// </remarks>
/// <param name="itemId">The item id.</param>
/// <param name="userId">The user id.</param>
/// <param name="maxStreamingBitrate">The maximum streaming bitrate.</param>
@@ -90,13 +92,13 @@ namespace Jellyfin.Api.Controllers
/// <param name="maxAudioChannels">The maximum number of audio channels.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="liveStreamId">The livestream id.</param>
- /// <param name="deviceProfile">The device profile.</param>
/// <param name="autoOpenLiveStream">Whether to auto open the livestream.</param>
/// <param name="enableDirectPlay">Whether to enable direct play. Default: true.</param>
/// <param name="enableDirectStream">Whether to enable direct stream. Default: true.</param>
/// <param name="enableTranscoding">Whether to enable transcoding. Default: true.</param>
/// <param name="allowVideoStreamCopy">Whether to allow to copy the video stream. Default: true.</param>
/// <param name="allowAudioStreamCopy">Whether to allow to copy the audio stream. Default: true.</param>
+ /// <param name="playbackInfoDto">The playback info.</param>
/// <response code="200">Playback info returned.</response>
/// <returns>A <see cref="Task"/> containing a <see cref="PlaybackInfoResponse"/> with the playback info.</returns>
[HttpPost("Items/{itemId}/PlaybackInfo")]
@@ -111,18 +113,17 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? maxAudioChannels,
[FromQuery] string? mediaSourceId,
[FromQuery] string? liveStreamId,
- [FromBody] DeviceProfileDto? deviceProfile,
- [FromQuery] bool autoOpenLiveStream = false,
- [FromQuery] bool enableDirectPlay = true,
- [FromQuery] bool enableDirectStream = true,
- [FromQuery] bool enableTranscoding = true,
- [FromQuery] bool allowVideoStreamCopy = true,
- [FromQuery] bool allowAudioStreamCopy = true)
+ [FromQuery] bool? autoOpenLiveStream,
+ [FromQuery] bool? enableDirectPlay,
+ [FromQuery] bool? enableDirectStream,
+ [FromQuery] bool? enableTranscoding,
+ [FromQuery] bool? allowVideoStreamCopy,
+ [FromQuery] bool? allowAudioStreamCopy,
+ [FromBody] PlaybackInfoDto? playbackInfoDto)
{
var authInfo = _authContext.GetAuthorizationInfo(Request);
- var profile = deviceProfile?.DeviceProfile;
-
+ var profile = playbackInfoDto?.DeviceProfile;
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", profile);
if (profile == null)
@@ -134,6 +135,23 @@ namespace Jellyfin.Api.Controllers
}
}
+ // Copy params from posted body
+ // TODO clean up when breaking API compatibility.
+ userId ??= playbackInfoDto?.UserId;
+ maxStreamingBitrate ??= playbackInfoDto?.MaxStreamingBitrate;
+ startTimeTicks ??= playbackInfoDto?.StartTimeTicks;
+ audioStreamIndex ??= playbackInfoDto?.AudioStreamIndex;
+ subtitleStreamIndex ??= playbackInfoDto?.SubtitleStreamIndex;
+ maxAudioChannels ??= playbackInfoDto?.MaxAudioChannels;
+ mediaSourceId ??= playbackInfoDto?.MediaSourceId;
+ liveStreamId ??= playbackInfoDto?.LiveStreamId;
+ autoOpenLiveStream ??= playbackInfoDto?.AutoOpenLiveStream ?? false;
+ enableDirectPlay ??= playbackInfoDto?.EnableDirectPlay ?? true;
+ enableDirectStream ??= playbackInfoDto?.EnableDirectStream ?? true;
+ enableTranscoding ??= playbackInfoDto?.EnableTranscoding ?? true;
+ allowVideoStreamCopy ??= playbackInfoDto?.AllowVideoStreamCopy ?? true;
+ allowAudioStreamCopy ??= playbackInfoDto?.AllowAudioStreamCopy ?? true;
+
var info = await _mediaInfoHelper.GetPlaybackInfo(
itemId,
userId,
@@ -161,18 +179,18 @@ namespace Jellyfin.Api.Controllers
maxAudioChannels,
info!.PlaySessionId!,
userId ?? Guid.Empty,
- enableDirectPlay,
- enableDirectStream,
- enableTranscoding,
- allowVideoStreamCopy,
- allowAudioStreamCopy,
+ enableDirectPlay.Value,
+ enableDirectStream.Value,
+ enableTranscoding.Value,
+ allowVideoStreamCopy.Value,
+ allowAudioStreamCopy.Value,
Request.HttpContext.GetNormalizedRemoteIp());
}
_mediaInfoHelper.SortMediaSources(info, maxStreamingBitrate);
}
- if (autoOpenLiveStream)
+ if (autoOpenLiveStream.Value)
{
var mediaSource = string.IsNullOrWhiteSpace(mediaSourceId) ? info.MediaSources[0] : info.MediaSources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.Ordinal));
@@ -183,9 +201,9 @@ namespace Jellyfin.Api.Controllers
new LiveStreamRequest
{
AudioStreamIndex = audioStreamIndex,
- DeviceProfile = deviceProfile?.DeviceProfile,
- EnableDirectPlay = enableDirectPlay,
- EnableDirectStream = enableDirectStream,
+ DeviceProfile = playbackInfoDto?.DeviceProfile,
+ EnableDirectPlay = enableDirectPlay.Value,
+ EnableDirectStream = enableDirectStream.Value,
ItemId = itemId,
MaxAudioChannels = maxAudioChannels,
MaxStreamingBitrate = maxStreamingBitrate,
diff --git a/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs b/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs
new file mode 100644
index 000000000..2cfdba507
--- /dev/null
+++ b/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs
@@ -0,0 +1,86 @@
+using System;
+using MediaBrowser.Model.Dlna;
+
+namespace Jellyfin.Api.Models.MediaInfoDtos
+{
+ /// <summary>
+ /// Plabyback info dto.
+ /// </summary>
+ public class PlaybackInfoDto
+ {
+ /// <summary>
+ /// Gets or sets the playback userId.
+ /// </summary>
+ public Guid? UserId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the max streaming bitrate.
+ /// </summary>
+ public int? MaxStreamingBitrate { get; set; }
+
+ /// <summary>
+ /// Gets or sets the start time in ticks.
+ /// </summary>
+ public long? StartTimeTicks { get; set; }
+
+ /// <summary>
+ /// Gets or sets the audio stream index.
+ /// </summary>
+ public int? AudioStreamIndex { get; set; }
+
+ /// <summary>
+ /// Gets or sets the subtitle stream index.
+ /// </summary>
+ public int? SubtitleStreamIndex { get; set; }
+
+ /// <summary>
+ /// Gets or sets the max audio channels.
+ /// </summary>
+ public int? MaxAudioChannels { get; set; }
+
+ /// <summary>
+ /// Gets or sets the media source id.
+ /// </summary>
+ public string? MediaSourceId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the live stream id.
+ /// </summary>
+ public string? LiveStreamId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the device profile.
+ /// </summary>
+ public DeviceProfile? DeviceProfile { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable direct play.
+ /// </summary>
+ public bool? EnableDirectPlay { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable direct stream.
+ /// </summary>
+ public bool? EnableDirectStream { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable transcoding.
+ /// </summary>
+ public bool? EnableTranscoding { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable video stream copy.
+ /// </summary>
+ public bool? AllowVideoStreamCopy { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to allow audio stream copy.
+ /// </summary>
+ public bool? AllowAudioStreamCopy { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to auto open the live stream.
+ /// </summary>
+ public bool? AutoOpenLiveStream { get; set; }
+ }
+} \ No newline at end of file
diff --git a/Jellyfin.Api/Models/VideoDtos/DeviceProfileDto.cs b/Jellyfin.Api/Models/VideoDtos/DeviceProfileDto.cs
deleted file mode 100644
index db55dc34b..000000000
--- a/Jellyfin.Api/Models/VideoDtos/DeviceProfileDto.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using MediaBrowser.Model.Dlna;
-
-namespace Jellyfin.Api.Models.VideoDtos
-{
- /// <summary>
- /// Device profile dto.
- /// </summary>
- public class DeviceProfileDto
- {
- /// <summary>
- /// Gets or sets device profile.
- /// </summary>
- public DeviceProfile? DeviceProfile { get; set; }
- }
-}
diff --git a/MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs b/MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs
new file mode 100644
index 000000000..37e6f64e3
--- /dev/null
+++ b/MediaBrowser.Common/Json/Converters/JsonVersionConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+ /// <summary>
+ /// Converts a Version object or value to/from JSON.
+ /// </summary>
+ public class JsonVersionConverter : JsonConverter<Version>
+ {
+ /// <inheritdoc />
+ public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ => new Version(reader.GetString());
+
+ /// <inheritdoc />
+ public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
+ => writer.WriteStringValue(value.ToString());
+ }
+}
diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs
index 9a94664ac..1aaf4a43b 100644
--- a/MediaBrowser.Common/Json/JsonDefaults.cs
+++ b/MediaBrowser.Common/Json/JsonDefaults.cs
@@ -40,6 +40,7 @@ namespace MediaBrowser.Common.Json
};
options.Converters.Add(new JsonGuidConverter());
+ options.Converters.Add(new JsonVersionConverter());
options.Converters.Add(new JsonStringEnumConverter());
options.Converters.Add(new JsonNullableStructConverterFactory());
options.Converters.Add(new JsonDateTimeIso8601Converter());