mirror of
https://github.com/jellyfin/jellyfin-plugin-dlna.git
synced 2024-11-26 16:00:55 +00:00
Add Dlna device profile code
This commit is contained in:
parent
ce934aae8e
commit
53142d6743
@ -13,7 +13,7 @@ namespace Jellyfin.Plugin.Dlna.Model;
|
||||
public static class ContentFeatureBuilder
|
||||
{
|
||||
public static string BuildImageHeader(
|
||||
DeviceProfile profile,
|
||||
DlnaDeviceProfile profile,
|
||||
string container,
|
||||
int? width,
|
||||
int? height,
|
||||
@ -58,7 +58,7 @@ public static class ContentFeatureBuilder
|
||||
}
|
||||
|
||||
public static string BuildAudioHeader(
|
||||
DeviceProfile profile,
|
||||
DlnaDeviceProfile profile,
|
||||
string container,
|
||||
string audioCodec,
|
||||
int? audioBitrate,
|
||||
@ -118,7 +118,7 @@ public static class ContentFeatureBuilder
|
||||
}
|
||||
|
||||
public static IEnumerable<string> BuildVideoHeader(
|
||||
DeviceProfile profile,
|
||||
DlnaDeviceProfile profile,
|
||||
string container,
|
||||
string videoCodec,
|
||||
string audioCodec,
|
||||
|
60
src/Jellyfin.Plugin.Dlna.Model/DeviceIdentification.cs
Normal file
60
src/Jellyfin.Plugin.Dlna.Model/DeviceIdentification.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public class DeviceIdentification
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the friendly.
|
||||
/// </summary>
|
||||
/// <value>The name of the friendly.</value>
|
||||
public string FriendlyName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model number.
|
||||
/// </summary>
|
||||
/// <value>The model number.</value>
|
||||
public string ModelNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the serial number.
|
||||
/// </summary>
|
||||
/// <value>The serial number.</value>
|
||||
public string SerialNumber { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the model.
|
||||
/// </summary>
|
||||
/// <value>The name of the model.</value>
|
||||
public string ModelName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model description.
|
||||
/// </summary>
|
||||
/// <value>The model description.</value>
|
||||
public string ModelDescription { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model URL.
|
||||
/// </summary>
|
||||
/// <value>The model URL.</value>
|
||||
public string ModelUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the manufacturer.
|
||||
/// </summary>
|
||||
/// <value>The manufacturer.</value>
|
||||
public string Manufacturer { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the manufacturer URL.
|
||||
/// </summary>
|
||||
/// <value>The manufacturer URL.</value>
|
||||
public string ManufacturerUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the headers.
|
||||
/// </summary>
|
||||
/// <value>The headers.</value>
|
||||
public HttpHeaderInfo[] Headers { get; set; } = Array.Empty<HttpHeaderInfo>();
|
||||
}
|
24
src/Jellyfin.Plugin.Dlna.Model/DeviceProfileInfo.cs
Normal file
24
src/Jellyfin.Plugin.Dlna.Model/DeviceProfileInfo.cs
Normal file
@ -0,0 +1,24 @@
|
||||
#nullable disable
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public class DeviceProfileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
/// <value>The identifier.</value>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public DeviceProfileType Type { get; set; }
|
||||
}
|
7
src/Jellyfin.Plugin.Dlna.Model/DeviceProfileType.cs
Normal file
7
src/Jellyfin.Plugin.Dlna.Model/DeviceProfileType.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public enum DeviceProfileType
|
||||
{
|
||||
System = 0,
|
||||
User = 1
|
||||
}
|
403
src/Jellyfin.Plugin.Dlna.Model/DlnaDeviceProfile.cs
Normal file
403
src/Jellyfin.Plugin.Dlna.Model/DlnaDeviceProfile.cs
Normal file
@ -0,0 +1,403 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
[XmlRoot("Profile")]
|
||||
public class DlnaDeviceProfile : DeviceProfile
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Identification.
|
||||
/// </summary>
|
||||
public DeviceIdentification? Identification { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the friendly name of the device profile, which can be shown to users.
|
||||
/// </summary>
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the manufacturer of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an url for the manufacturer of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? ManufacturerUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model name of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? ModelName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model description of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? ModelDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the model number of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? ModelNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ModelUrl.
|
||||
/// </summary>
|
||||
public string? ModelUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the serial number of the device which this profile represents.
|
||||
/// </summary>
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether EnableAlbumArtInDidl.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool EnableAlbumArtInDidl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether EnableSingleAlbumArtLimit.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool EnableSingleAlbumArtLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether EnableSingleSubtitleLimit.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool EnableSingleSubtitleLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SupportedMediaTypes.
|
||||
/// </summary>
|
||||
public string SupportedMediaTypes { get; set; } = "Audio,Photo,Video";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserId.
|
||||
/// </summary>
|
||||
public string? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AlbumArtPn.
|
||||
/// </summary>
|
||||
public string? AlbumArtPn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MaxAlbumArtWidth.
|
||||
/// </summary>
|
||||
public int? MaxAlbumArtWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the MaxAlbumArtHeight.
|
||||
/// </summary>
|
||||
public int? MaxAlbumArtHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum allowed width of embedded icons.
|
||||
/// </summary>
|
||||
public int? MaxIconWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum allowed height of embedded icons.
|
||||
/// </summary>
|
||||
public int? MaxIconHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace.
|
||||
/// </summary>
|
||||
public string? SonyAggregationFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ProtocolInfo.
|
||||
/// </summary>
|
||||
public string? ProtocolInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the TimelineOffsetSeconds.
|
||||
/// </summary>
|
||||
[DefaultValue(0)]
|
||||
public int TimelineOffsetSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether RequiresPlainVideoItems.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool RequiresPlainVideoItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether RequiresPlainFolders.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool RequiresPlainFolders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether EnableMSMediaReceiverRegistrar.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool EnableMSMediaReceiverRegistrar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether IgnoreTranscodeByteRangeRequests.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool IgnoreTranscodeByteRangeRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the XmlRootAttributes.
|
||||
/// </summary>
|
||||
public XmlAttribute[] XmlRootAttributes { get; set; } = Array.Empty<XmlAttribute>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ResponseProfiles.
|
||||
/// </summary>
|
||||
public ResponseProfile[] ResponseProfiles { get; set; } = Array.Empty<ResponseProfile>();
|
||||
|
||||
/// <summary>
|
||||
/// The GetSupportedMediaTypes.
|
||||
/// </summary>
|
||||
/// <returns>The .</returns>
|
||||
public MediaType[] GetSupportedMediaTypes()
|
||||
{
|
||||
return ContainerProfile.SplitValue(SupportedMediaTypes)
|
||||
.Select(m => Enum.TryParse<MediaType>(m, out var parsed) ? parsed : MediaType.Unknown)
|
||||
.Where(m => m != MediaType.Unknown)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the audio transcoding profile.
|
||||
/// </summary>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="audioCodec">The audio Codec.</param>
|
||||
/// <returns>A <see cref="TranscodingProfile"/>.</returns>
|
||||
public TranscodingProfile? GetAudioTranscodingProfile(string? container, string? audioCodec)
|
||||
{
|
||||
container = (container ?? string.Empty).TrimStart('.');
|
||||
|
||||
return TranscodingProfiles
|
||||
.Where(i => i.Type == DlnaProfileType.Audio)
|
||||
.Where(i => string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault(i => i.GetAudioCodecs().Contains(audioCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video transcoding profile.
|
||||
/// </summary>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="audioCodec">The audio Codec.</param>
|
||||
/// <param name="videoCodec">The video Codec.</param>
|
||||
/// <returns>The <see cref="TranscodingProfile"/>.</returns>
|
||||
public TranscodingProfile? GetVideoTranscodingProfile(string? container, string? audioCodec, string? videoCodec)
|
||||
{
|
||||
container = (container ?? string.Empty).TrimStart('.');
|
||||
|
||||
return TranscodingProfiles
|
||||
.Where(i => i.Type == DlnaProfileType.Video)
|
||||
.Where(i => string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(i => i.GetAudioCodecs().Contains(audioCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault(i => string.Equals(videoCodec, i.VideoCodec, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the audio media profile.
|
||||
/// </summary>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="audioCodec">The audio codec.</param>
|
||||
/// <param name="audioChannels">The audio channels.</param>
|
||||
/// <param name="audioBitrate">The audio bitrate.</param>
|
||||
/// <param name="audioSampleRate">The audio sample rate.</param>
|
||||
/// <param name="audioBitDepth">The audio bit depth.</param>
|
||||
/// <returns>The <see cref="ResponseProfile"/>.</returns>
|
||||
public ResponseProfile? GetAudioMediaProfile(string? container, string? audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth)
|
||||
{
|
||||
foreach (var i in ResponseProfiles)
|
||||
{
|
||||
if (i.Type != DlnaProfileType.Audio)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ContainerProfile.ContainsContainer(i.GetContainers(), container))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var audioCodecs = i.GetAudioCodecs();
|
||||
if (audioCodecs.Length > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var anyOff = false;
|
||||
foreach (ProfileCondition c in i.Conditions)
|
||||
{
|
||||
if (!ConditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth))
|
||||
{
|
||||
anyOff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyOff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image media profile.
|
||||
/// </summary>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <returns>The <see cref="ResponseProfile"/>.</returns>
|
||||
public ResponseProfile? GetImageMediaProfile(string container, int? width, int? height)
|
||||
{
|
||||
foreach (var i in ResponseProfiles)
|
||||
{
|
||||
if (i.Type != DlnaProfileType.Photo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ContainerProfile.ContainsContainer(i.GetContainers(), container))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var anyOff = false;
|
||||
foreach (var c in i.Conditions)
|
||||
{
|
||||
if (!ConditionProcessor.IsImageConditionSatisfied(GetModelProfileCondition(c), width, height))
|
||||
{
|
||||
anyOff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyOff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video media profile.
|
||||
/// </summary>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="audioCodec">The audio codec.</param>
|
||||
/// <param name="videoCodec">The video codec.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="bitDepth">The bit depth.</param>
|
||||
/// <param name="videoBitrate">The video bitrate.</param>
|
||||
/// <param name="videoProfile">The video profile.</param>
|
||||
/// <param name="videoRangeType">The video range type.</param>
|
||||
/// <param name="videoLevel">The video level.</param>
|
||||
/// <param name="videoFramerate">The video framerate.</param>
|
||||
/// <param name="packetLength">The packet length.</param>
|
||||
/// <param name="timestamp">The timestamp<see cref="TransportStreamTimestamp"/>.</param>
|
||||
/// <param name="isAnamorphic">True if anamorphic.</param>
|
||||
/// <param name="isInterlaced">True if interlaced.</param>
|
||||
/// <param name="refFrames">The ref frames.</param>
|
||||
/// <param name="numVideoStreams">The number of video streams.</param>
|
||||
/// <param name="numAudioStreams">The number of audio streams.</param>
|
||||
/// <param name="videoCodecTag">The video Codec tag.</param>
|
||||
/// <param name="isAvc">True if Avc.</param>
|
||||
/// <returns>The <see cref="ResponseProfile"/>.</returns>
|
||||
public ResponseProfile? GetVideoMediaProfile(
|
||||
string? container,
|
||||
string? audioCodec,
|
||||
string? videoCodec,
|
||||
int? width,
|
||||
int? height,
|
||||
int? bitDepth,
|
||||
int? videoBitrate,
|
||||
string? videoProfile,
|
||||
VideoRangeType videoRangeType,
|
||||
double? videoLevel,
|
||||
float? videoFramerate,
|
||||
int? packetLength,
|
||||
TransportStreamTimestamp timestamp,
|
||||
bool? isAnamorphic,
|
||||
bool? isInterlaced,
|
||||
int? refFrames,
|
||||
int? numVideoStreams,
|
||||
int? numAudioStreams,
|
||||
string? videoCodecTag,
|
||||
bool? isAvc)
|
||||
{
|
||||
foreach (var i in ResponseProfiles)
|
||||
{
|
||||
if (i.Type != DlnaProfileType.Video)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ContainerProfile.ContainsContainer(i.GetContainers(), container))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var audioCodecs = i.GetAudioCodecs();
|
||||
if (audioCodecs.Length > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var videoCodecs = i.GetVideoCodecs();
|
||||
if (videoCodecs.Length > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var anyOff = false;
|
||||
foreach (ProfileCondition c in i.Conditions)
|
||||
{
|
||||
if (!ConditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
||||
{
|
||||
anyOff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyOff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ProfileCondition GetModelProfileCondition(ProfileCondition c)
|
||||
{
|
||||
return new ProfileCondition
|
||||
{
|
||||
Condition = c.Condition,
|
||||
IsRequired = c.IsRequired,
|
||||
Property = c.Property,
|
||||
Value = c.Value
|
||||
};
|
||||
}
|
||||
}
|
8
src/Jellyfin.Plugin.Dlna.Model/HeaderMatchType.cs
Normal file
8
src/Jellyfin.Plugin.Dlna.Model/HeaderMatchType.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public enum HeaderMatchType
|
||||
{
|
||||
Equals = 0,
|
||||
Regex = 1,
|
||||
Substring = 2
|
||||
}
|
17
src/Jellyfin.Plugin.Dlna.Model/HttpHeaderInfo.cs
Normal file
17
src/Jellyfin.Plugin.Dlna.Model/HttpHeaderInfo.cs
Normal file
@ -0,0 +1,17 @@
|
||||
#nullable disable
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public class HttpHeaderInfo
|
||||
{
|
||||
[XmlAttribute("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[XmlAttribute("value")]
|
||||
public string Value { get; set; }
|
||||
|
||||
[XmlAttribute("match")]
|
||||
public HeaderMatchType Match { get; set; }
|
||||
}
|
@ -20,26 +20,26 @@ public interface IDlnaManager
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile? GetProfile(IHeaderDictionary headers);
|
||||
DlnaDeviceProfile? GetProfile(IHeaderDictionary headers);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default profile.
|
||||
/// </summary>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile GetDefaultProfile();
|
||||
DlnaDeviceProfile GetDefaultProfile();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the profile.
|
||||
/// </summary>
|
||||
/// <param name="profile">The profile.</param>
|
||||
void CreateProfile(DeviceProfile profile);
|
||||
void CreateProfile(DlnaDeviceProfile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the profile.
|
||||
/// </summary>
|
||||
/// <param name="profileId">The profile id.</param>
|
||||
/// <param name="profile">The profile.</param>
|
||||
void UpdateProfile(string profileId, DeviceProfile profile);
|
||||
void UpdateProfile(string profileId, DlnaDeviceProfile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the profile.
|
||||
@ -52,14 +52,14 @@ public interface IDlnaManager
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile? GetProfile(string id);
|
||||
DlnaDeviceProfile? GetProfile(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile.
|
||||
/// </summary>
|
||||
/// <param name="deviceInfo">The device information.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile? GetProfile(DeviceIdentification deviceInfo);
|
||||
DlnaDeviceProfile? GetProfile(DeviceIdentification deviceInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the server description XML.
|
||||
|
@ -5,7 +5,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Extensions" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20240112.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
50
src/Jellyfin.Plugin.Dlna.Model/ResponseProfile.cs
Normal file
50
src/Jellyfin.Plugin.Dlna.Model/ResponseProfile.cs
Normal file
@ -0,0 +1,50 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
public class ResponseProfile
|
||||
{
|
||||
public ResponseProfile()
|
||||
{
|
||||
Conditions = Array.Empty<ProfileCondition>();
|
||||
}
|
||||
|
||||
[XmlAttribute("container")]
|
||||
public string Container { get; set; }
|
||||
|
||||
[XmlAttribute("audioCodec")]
|
||||
public string AudioCodec { get; set; }
|
||||
|
||||
[XmlAttribute("videoCodec")]
|
||||
public string VideoCodec { get; set; }
|
||||
|
||||
[XmlAttribute("type")]
|
||||
public DlnaProfileType Type { get; set; }
|
||||
|
||||
[XmlAttribute("orgPn")]
|
||||
public string OrgPn { get; set; }
|
||||
|
||||
[XmlAttribute("mimeType")]
|
||||
public string MimeType { get; set; }
|
||||
|
||||
public ProfileCondition[] Conditions { get; set; }
|
||||
|
||||
public string[] GetContainers()
|
||||
{
|
||||
return ContainerProfile.SplitValue(Container);
|
||||
}
|
||||
|
||||
public string[] GetAudioCodecs()
|
||||
{
|
||||
return ContainerProfile.SplitValue(AudioCodec);
|
||||
}
|
||||
|
||||
public string[] GetVideoCodecs()
|
||||
{
|
||||
return ContainerProfile.SplitValue(VideoCodec);
|
||||
}
|
||||
}
|
23
src/Jellyfin.Plugin.Dlna.Model/XmlAttribute.cs
Normal file
23
src/Jellyfin.Plugin.Dlna.Model/XmlAttribute.cs
Normal file
@ -0,0 +1,23 @@
|
||||
#nullable disable
|
||||
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the <see cref="XmlAttribute" />.
|
||||
/// </summary>
|
||||
public class XmlAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the attribute.
|
||||
/// </summary>
|
||||
[XmlAttribute("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the attribute.
|
||||
/// </summary>
|
||||
[XmlAttribute("value")]
|
||||
public string Value { get; set; }
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
@ -144,7 +145,7 @@ public class StreamState : EncodingJobInfo, IDisposable
|
||||
/// <summary>
|
||||
/// Gets or sets the device profile.
|
||||
/// </summary>
|
||||
public DeviceProfile? DeviceProfile { get; set; }
|
||||
public DlnaDeviceProfile? DeviceProfile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the transcoding job.
|
||||
|
@ -528,7 +528,7 @@ public static class StreamingHelpers
|
||||
if (state.DeviceProfile is null)
|
||||
{
|
||||
var caps = deviceManager.GetCapabilities(deviceProfileId);
|
||||
state.DeviceProfile = caps is null ? dlnaManager.GetProfile(request.Headers) : caps.DeviceProfile;
|
||||
state.DeviceProfile = caps is null ? dlnaManager.GetProfile(request.Headers) : caps.DeviceProfile as DlnaDeviceProfile;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class DlnaController : ControllerBase
|
||||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||
[HttpPost("Profiles")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult CreateProfile([FromBody] DeviceProfile deviceProfile)
|
||||
public ActionResult CreateProfile([FromBody] DlnaDeviceProfile deviceProfile)
|
||||
{
|
||||
_dlnaManager.CreateProfile(deviceProfile);
|
||||
return NoContent();
|
||||
@ -119,7 +119,7 @@ public class DlnaController : ControllerBase
|
||||
[HttpPost("Profiles/{profileId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult UpdateProfile([FromRoute, Required] string profileId, [FromBody] DeviceProfile deviceProfile)
|
||||
public ActionResult UpdateProfile([FromRoute, Required] string profileId, [FromBody] DlnaDeviceProfile deviceProfile)
|
||||
{
|
||||
var existingDeviceProfile = _dlnaManager.GetProfile(profileId);
|
||||
if (existingDeviceProfile is null)
|
||||
|
@ -3,9 +3,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using Jellyfin.Plugin.Dlna.Service;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.ConnectionManager;
|
||||
@ -15,14 +15,14 @@ namespace Jellyfin.Plugin.Dlna.ConnectionManager;
|
||||
/// </summary>
|
||||
public class ControlHandler : BaseControlHandler
|
||||
{
|
||||
private readonly DeviceProfile _profile;
|
||||
private readonly DlnaDeviceProfile _profile;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ControlHandler"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The <see cref="ILogger"/> for use with the <see cref="ControlHandler"/> instance.</param>
|
||||
/// <param name="profile">The <see cref="DeviceProfile"/> for use with the <see cref="ControlHandler"/> instance.</param>
|
||||
public ControlHandler(ILogger logger, DeviceProfile profile)
|
||||
/// <param name="profile">The <see cref="DlnaDeviceProfile"/> for use with the <see cref="ControlHandler"/> instance.</param>
|
||||
public ControlHandler(ILogger logger, DlnaDeviceProfile profile)
|
||||
: base(logger)
|
||||
{
|
||||
_profile = profile;
|
||||
|
@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using Jellyfin.Plugin.Dlna.Service;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Library;
|
||||
@ -129,7 +130,7 @@ public class ContentDirectoryService : BaseService, IContentDirectory
|
||||
/// </summary>
|
||||
/// <param name="profile">The <see cref="DeviceProfile"/>.</param>
|
||||
/// <returns>The <see cref="User"/>.</returns>
|
||||
private User? GetUser(DeviceProfile profile)
|
||||
private User? GetUser(DlnaDeviceProfile profile)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(profile.UserId))
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ public class ControlHandler : BaseControlHandler
|
||||
|
||||
private readonly DidlBuilder _didlBuilder;
|
||||
|
||||
private readonly DeviceProfile _profile;
|
||||
private readonly DlnaDeviceProfile _profile;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ControlHandler"/> class.
|
||||
@ -73,7 +73,7 @@ public class ControlHandler : BaseControlHandler
|
||||
public ControlHandler(
|
||||
ILogger logger,
|
||||
ILibraryManager libraryManager,
|
||||
DeviceProfile profile,
|
||||
DlnaDeviceProfile profile,
|
||||
string serverAddress,
|
||||
string accessToken,
|
||||
IImageProcessor imageProcessor,
|
||||
|
@ -36,7 +36,7 @@ using StreamBuilder = MediaBrowser.Model.Dlna.StreamBuilder;
|
||||
using StreamInfo = MediaBrowser.Model.Dlna.StreamInfo;
|
||||
using SubtitleDeliveryMethod = MediaBrowser.Model.Dlna.SubtitleDeliveryMethod;
|
||||
using SubtitleStreamInfo = MediaBrowser.Model.Dlna.SubtitleStreamInfo;
|
||||
using XmlAttribute = MediaBrowser.Model.Dlna.XmlAttribute;
|
||||
using XmlAttribute = Jellyfin.Plugin.Dlna.Model.XmlAttribute;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Didl;
|
||||
|
||||
@ -47,7 +47,7 @@ public class DidlBuilder
|
||||
private const string NsUpnp = "urn:schemas-upnp-org:metadata-1-0/upnp/";
|
||||
private const string NsDlna = "urn:schemas-dlna-org:metadata-1-0/";
|
||||
|
||||
private readonly DeviceProfile _profile;
|
||||
private readonly DlnaDeviceProfile _profile;
|
||||
private readonly IImageProcessor _imageProcessor;
|
||||
private readonly string _serverAddress;
|
||||
private readonly string? _accessToken;
|
||||
@ -60,7 +60,7 @@ public class DidlBuilder
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public DidlBuilder(
|
||||
DeviceProfile profile,
|
||||
DlnaDeviceProfile profile,
|
||||
User? user,
|
||||
IImageProcessor imageProcessor,
|
||||
string serverAddress,
|
||||
@ -126,7 +126,7 @@ public class DidlBuilder
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteXmlRootAttributes(DeviceProfile profile, XmlWriter writer)
|
||||
public static void WriteXmlRootAttributes(DlnaDeviceProfile profile, XmlWriter writer)
|
||||
{
|
||||
foreach (var att in profile.XmlRootAttributes)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Extensions.Json;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using Jellyfin.Plugin.Dlna.Profiles;
|
||||
using Jellyfin.Plugin.Dlna.Server;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
@ -37,7 +38,8 @@ public class DlnaManager : IDlnaManager
|
||||
private static readonly Assembly _assembly = typeof(DlnaManager).Assembly;
|
||||
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
|
||||
|
||||
private readonly Dictionary<string, Tuple<InternalProfileInfo, DeviceProfile>> _profiles = new Dictionary<string, Tuple<InternalProfileInfo, DeviceProfile>>(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, Tuple<InternalProfileInfo, DlnaDeviceProfile>> _profiles
|
||||
= new(StringComparer.Ordinal);
|
||||
|
||||
public DlnaManager(
|
||||
IXmlSerializer xmlSerializer,
|
||||
@ -81,7 +83,7 @@ public class DlnaManager : IDlnaManager
|
||||
.OrderBy(i => i.Name));
|
||||
}
|
||||
|
||||
public IEnumerable<DeviceProfile> GetProfiles()
|
||||
public IEnumerable<DlnaDeviceProfile> GetProfiles()
|
||||
{
|
||||
lock (_profiles)
|
||||
{
|
||||
@ -94,13 +96,13 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DeviceProfile GetDefaultProfile()
|
||||
public DlnaDeviceProfile GetDefaultProfile()
|
||||
{
|
||||
return new DefaultProfile();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DeviceProfile? GetProfile(DeviceIdentification deviceInfo)
|
||||
public DlnaDeviceProfile? GetProfile(DeviceIdentification deviceInfo)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(deviceInfo);
|
||||
|
||||
@ -167,7 +169,7 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DeviceProfile? GetProfile(IHeaderDictionary headers)
|
||||
public DlnaDeviceProfile? GetProfile(IHeaderDictionary headers)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(headers);
|
||||
|
||||
@ -239,23 +241,23 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
}
|
||||
|
||||
private DeviceProfile? ParseProfileFile(string path, DeviceProfileType type)
|
||||
private DlnaDeviceProfile? ParseProfileFile(string path, DeviceProfileType type)
|
||||
{
|
||||
lock (_profiles)
|
||||
{
|
||||
if (_profiles.TryGetValue(path, out Tuple<InternalProfileInfo, DeviceProfile>? profileTuple))
|
||||
if (_profiles.TryGetValue(path, out Tuple<InternalProfileInfo, DlnaDeviceProfile>? profileTuple))
|
||||
{
|
||||
return profileTuple.Item2;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var tempProfile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
|
||||
var tempProfile = (DlnaDeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DlnaDeviceProfile), path);
|
||||
var profile = ReserializeProfile(tempProfile);
|
||||
|
||||
profile.Id = path.ToLowerInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||
|
||||
_profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
||||
_profiles[path] = new Tuple<InternalProfileInfo, DlnaDeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
||||
|
||||
return profile;
|
||||
}
|
||||
@ -269,7 +271,7 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DeviceProfile? GetProfile(string id)
|
||||
public DlnaDeviceProfile? GetProfile(string id)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(id);
|
||||
|
||||
@ -370,7 +372,7 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void CreateProfile(DeviceProfile profile)
|
||||
public void CreateProfile(DlnaDeviceProfile profile)
|
||||
{
|
||||
profile = ReserializeProfile(profile);
|
||||
|
||||
@ -383,7 +385,7 @@ public class DlnaManager : IDlnaManager
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void UpdateProfile(string profileId, DeviceProfile profile)
|
||||
public void UpdateProfile(string profileId, DlnaDeviceProfile profile)
|
||||
{
|
||||
profile = ReserializeProfile(profile);
|
||||
|
||||
@ -411,11 +413,11 @@ public class DlnaManager : IDlnaManager
|
||||
SaveProfile(profile, path, DeviceProfileType.User);
|
||||
}
|
||||
|
||||
private void SaveProfile(DeviceProfile profile, string path, DeviceProfileType type)
|
||||
private void SaveProfile(DlnaDeviceProfile profile, string path, DeviceProfileType type)
|
||||
{
|
||||
lock (_profiles)
|
||||
{
|
||||
_profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
||||
_profiles[path] = new Tuple<InternalProfileInfo, DlnaDeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
|
||||
}
|
||||
|
||||
SerializeToXml(profile, path);
|
||||
@ -432,9 +434,9 @@ public class DlnaManager : IDlnaManager
|
||||
/// </summary>
|
||||
/// <param name="profile">The device profile.</param>
|
||||
/// <returns>The re-serialized device profile.</returns>
|
||||
private DeviceProfile ReserializeProfile(DeviceProfile profile)
|
||||
private DlnaDeviceProfile ReserializeProfile(DlnaDeviceProfile profile)
|
||||
{
|
||||
if (profile.GetType() == typeof(DeviceProfile))
|
||||
if (profile.GetType() == typeof(DlnaDeviceProfile))
|
||||
{
|
||||
return profile;
|
||||
}
|
||||
@ -442,7 +444,7 @@ public class DlnaManager : IDlnaManager
|
||||
var json = JsonSerializer.Serialize(profile, _jsonOptions);
|
||||
|
||||
// Output can't be null if the input isn't null
|
||||
return JsonSerializer.Deserialize<DeviceProfile>(json, _jsonOptions)!;
|
||||
return JsonSerializer.Deserialize<DlnaDeviceProfile>(json, _jsonOptions)!;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -5,8 +5,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.9.0-20240112.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Plugin.Dlna.Common;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.PlayTo;
|
||||
|
||||
|
@ -11,6 +11,7 @@ using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Data.Events;
|
||||
using Jellyfin.Plugin.Dlna.Didl;
|
||||
using Jellyfin.Plugin.Dlna.Extensions;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
@ -579,7 +580,7 @@ public class PlayToController2 : ISessionController, IDisposable
|
||||
return null;
|
||||
}
|
||||
|
||||
private PlaylistItem GetPlaylistItem(BaseItem item, MediaSourceInfo[] mediaSources, DeviceProfile profile, string deviceId, string? mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
||||
private PlaylistItem GetPlaylistItem(BaseItem item, MediaSourceInfo[] mediaSources, DlnaDeviceProfile profile, string deviceId, string? mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex)
|
||||
=> item.MediaType switch
|
||||
{
|
||||
MediaType.Video => new PlaylistItem
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.PlayTo;
|
||||
@ -14,5 +15,5 @@ public class PlaylistItem
|
||||
|
||||
public StreamInfo StreamInfo { get; set; }
|
||||
|
||||
public DeviceProfile Profile { get; set; }
|
||||
public DlnaDeviceProfile Profile { get; set; }
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Session;
|
||||
@ -12,7 +13,7 @@ namespace Jellyfin.Plugin.Dlna.PlayTo;
|
||||
|
||||
public static class PlaylistItemFactory
|
||||
{
|
||||
public static PlaylistItem Create(Photo item, DeviceProfile profile)
|
||||
public static PlaylistItem Create(Photo item, DlnaDeviceProfile profile)
|
||||
{
|
||||
var playlistItem = new PlaylistItem
|
||||
{
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Profiles;
|
||||
|
||||
[System.Xml.Serialization.XmlRoot("Profile")]
|
||||
public class DefaultProfile : DeviceProfile
|
||||
public class DefaultProfile : DlnaDeviceProfile
|
||||
{
|
||||
public DefaultProfile()
|
||||
{
|
||||
|
@ -7,20 +7,20 @@ using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using Jellyfin.Plugin.Dlna.Common;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using Jellyfin.Plugin.Dlna.Model;
|
||||
|
||||
namespace Jellyfin.Plugin.Dlna.Server;
|
||||
|
||||
public class DescriptionXmlBuilder
|
||||
{
|
||||
private readonly DeviceProfile _profile;
|
||||
private readonly DlnaDeviceProfile _profile;
|
||||
|
||||
private readonly string _serverUdn;
|
||||
private readonly string _serverAddress;
|
||||
private readonly string _serverName;
|
||||
private readonly string _serverId;
|
||||
|
||||
public DescriptionXmlBuilder(DeviceProfile profile, string serverUdn, string serverAddress, string serverName, string serverId)
|
||||
public DescriptionXmlBuilder(DlnaDeviceProfile profile, string serverUdn, string serverAddress, string serverName, string serverId)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(serverUdn);
|
||||
ArgumentException.ThrowIfNullOrEmpty(serverAddress);
|
||||
|
@ -5,9 +5,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Common" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Extensions" Version="10.9.0-20231229.2" />
|
||||
<PackageReference Include="Jellyfin.Common" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Jellyfin.Extensions" Version="10.9.0-20240112.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Loading…
Reference in New Issue
Block a user