mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-26 12:05:04 +01:00
Normalize orgPn usage
This commit is contained in:
130
MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
Normal file
130
MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
public class ContentFeatureBuilder
|
||||
{
|
||||
private readonly DeviceProfile _profile;
|
||||
|
||||
public ContentFeatureBuilder(DeviceProfile profile)
|
||||
{
|
||||
_profile = profile;
|
||||
}
|
||||
|
||||
public string BuildAudioHeader(string container,
|
||||
string audioCodec,
|
||||
int? audioBitrate,
|
||||
int? audioSampleRate,
|
||||
int? audioChannels,
|
||||
bool isDirectStream,
|
||||
long? runtimeTicks,
|
||||
TranscodeSeekInfo transcodeSeekInfo)
|
||||
{
|
||||
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
|
||||
var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
|
||||
|
||||
// 0 = native, 1 = transcoded
|
||||
var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
|
||||
|
||||
var flagValue = DlnaFlags.StreamingTransferMode |
|
||||
DlnaFlags.BackgroundTransferMode |
|
||||
DlnaFlags.DlnaV15;
|
||||
|
||||
if (isDirectStream)
|
||||
{
|
||||
//flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
|
||||
}
|
||||
else if (runtimeTicks.HasValue)
|
||||
{
|
||||
//flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
|
||||
}
|
||||
|
||||
var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000",
|
||||
Enum.Format(typeof(DlnaFlags), flagValue, "x"));
|
||||
|
||||
var mediaProfile = _profile.GetAudioMediaProfile(container, audioCodec);
|
||||
|
||||
var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
|
||||
|
||||
if (string.IsNullOrEmpty(orgPn))
|
||||
{
|
||||
orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels);
|
||||
}
|
||||
|
||||
var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
|
||||
|
||||
return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
|
||||
}
|
||||
|
||||
public string BuildVideoHeader(string container,
|
||||
string videoCodec,
|
||||
string audioCodec,
|
||||
int? width,
|
||||
int? height,
|
||||
int? bitrate,
|
||||
TransportStreamTimestamp timestamp,
|
||||
bool isDirectStream,
|
||||
long? runtimeTicks,
|
||||
TranscodeSeekInfo transcodeSeekInfo)
|
||||
{
|
||||
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
|
||||
var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
|
||||
|
||||
// 0 = native, 1 = transcoded
|
||||
var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
|
||||
|
||||
var flagValue = DlnaFlags.StreamingTransferMode |
|
||||
DlnaFlags.BackgroundTransferMode |
|
||||
DlnaFlags.DlnaV15;
|
||||
|
||||
if (isDirectStream)
|
||||
{
|
||||
//flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
|
||||
}
|
||||
else if (runtimeTicks.HasValue)
|
||||
{
|
||||
//flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
|
||||
}
|
||||
|
||||
var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000",
|
||||
Enum.Format(typeof(DlnaFlags), flagValue, "x"));
|
||||
|
||||
var mediaProfile = _profile.GetVideoMediaProfile(container, audioCodec, videoCodec);
|
||||
var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
|
||||
|
||||
if (string.IsNullOrEmpty(orgPn))
|
||||
{
|
||||
orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, bitrate, timestamp);
|
||||
}
|
||||
|
||||
var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
|
||||
|
||||
return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
|
||||
}
|
||||
|
||||
private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels)
|
||||
{
|
||||
var format = new MediaFormatProfileResolver()
|
||||
.ResolveAudioFormat(container,
|
||||
audioBitrate,
|
||||
audioSampleRate,
|
||||
audioChannels);
|
||||
|
||||
return format.HasValue ? format.Value.ToString() : null;
|
||||
}
|
||||
|
||||
private string GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestamp)
|
||||
{
|
||||
var videoFormat = new MediaFormatProfileResolver()
|
||||
.ResolveVideoFormat(container,
|
||||
videoCodec,
|
||||
audioCodec,
|
||||
width,
|
||||
height,
|
||||
bitrate,
|
||||
timestamp);
|
||||
|
||||
return videoFormat.HasValue ? videoFormat.Value.ToString() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
});
|
||||
}
|
||||
|
||||
public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, MediaStream audioStream)
|
||||
public ResponseProfile GetAudioMediaProfile(string container, string audioCodec)
|
||||
{
|
||||
container = (container ?? string.Empty).TrimStart('.');
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
});
|
||||
}
|
||||
|
||||
public ResponseProfile GetVideoMediaProfile(string container, string audioCodec, string videoCodec, MediaStream audioStream, MediaStream videoStream)
|
||||
public ResponseProfile GetVideoMediaProfile(string container, string audioCodec, string videoCodec)
|
||||
{
|
||||
container = (container ?? string.Empty).TrimStart('.');
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
string.Equals(container, "m2ts", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
||||
var list = ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, bitrate, timestampType)
|
||||
var list = ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, timestampType)
|
||||
.ToList();
|
||||
|
||||
return list.Count > 0 ? list[0] : (MediaFormatProfile?)null;
|
||||
@@ -54,7 +54,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
return null;
|
||||
}
|
||||
|
||||
private IEnumerable<MediaFormatProfile> ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestampType)
|
||||
private IEnumerable<MediaFormatProfile> ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
|
||||
{
|
||||
var suffix = "";
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -56,6 +57,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
public MediaSourceInfo MediaSource { get; set; }
|
||||
|
||||
public TransportStreamTimestamp TargetTimestamp { get; set; }
|
||||
|
||||
public string MediaSourceId
|
||||
{
|
||||
get
|
||||
@@ -252,6 +255,68 @@ namespace MediaBrowser.Model.Dlna
|
||||
: stream == null ? null : stream.Channels;
|
||||
}
|
||||
}
|
||||
|
||||
public int? TotalOutputBitrate
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TargetAudioBitrate ?? 0) + (VideoBitrate ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int? TargetWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
var videoStream = TargetVideoStream;
|
||||
|
||||
if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
|
||||
{
|
||||
var size = new ImageSize
|
||||
{
|
||||
Width = videoStream.Width.Value,
|
||||
Height = videoStream.Height.Value
|
||||
};
|
||||
|
||||
var newSize = DrawingUtils.Resize(size,
|
||||
null,
|
||||
null,
|
||||
MaxWidth,
|
||||
MaxHeight);
|
||||
|
||||
return Convert.ToInt32(newSize.Width);
|
||||
}
|
||||
|
||||
return MaxWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public int? TargetHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
var videoStream = TargetVideoStream;
|
||||
|
||||
if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue)
|
||||
{
|
||||
var size = new ImageSize
|
||||
{
|
||||
Width = videoStream.Width.Value,
|
||||
Height = videoStream.Height.Value
|
||||
};
|
||||
|
||||
var newSize = DrawingUtils.Resize(size,
|
||||
null,
|
||||
null,
|
||||
MaxWidth,
|
||||
MaxHeight);
|
||||
|
||||
return Convert.ToInt32(newSize.Height);
|
||||
}
|
||||
|
||||
return MaxHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
<Compile Include="Configuration\ServerConfiguration.cs" />
|
||||
<Compile Include="Dlna\CodecProfile.cs" />
|
||||
<Compile Include="Dlna\ContainerProfile.cs" />
|
||||
<Compile Include="Dlna\ContentFeatureBuilder.cs" />
|
||||
<Compile Include="Dlna\DeviceIdentification.cs" />
|
||||
<Compile Include="Dlna\DeviceProfile.cs" />
|
||||
<Compile Include="Dlna\DeviceProfileInfo.cs" />
|
||||
|
||||
Reference in New Issue
Block a user