mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 03:26:07 +02:00
support more dlna resource properties
This commit is contained in:
parent
b7b6f64f00
commit
5170042eb5
11 changed files with 271 additions and 99 deletions
|
@ -380,7 +380,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
if (isVc1)
|
if (isVc1)
|
||||||
{
|
{
|
||||||
profileScore ++;
|
profileScore++;
|
||||||
// Max of 2
|
// Max of 2
|
||||||
profileScore = Math.Min(profileScore, 2);
|
profileScore = Math.Min(profileScore, 2);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5)
|
if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5)
|
||||||
{
|
{
|
||||||
volParam = ",volume=2.000000";
|
volParam = ",volume=" + ServerConfigurationManager.Configuration.DownMixAudioBoost.ToString(UsCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -516,7 +516,15 @@ namespace MediaBrowser.Dlna
|
||||||
|
|
||||||
var serverAddress = device.Descriptor.ToString().Substring(0, device.Descriptor.ToString().IndexOf("/dlna", StringComparison.OrdinalIgnoreCase));
|
var serverAddress = device.Descriptor.ToString().Substring(0, device.Descriptor.ToString().IndexOf("/dlna", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
return new ControlHandler(_logger, _userManager, _libraryManager, profile, serverAddress, _dtoService, _imageProcessor, _userDataManager)
|
return new ControlHandler(
|
||||||
|
_logger,
|
||||||
|
_userManager,
|
||||||
|
_libraryManager,
|
||||||
|
profile,
|
||||||
|
serverAddress,
|
||||||
|
_dtoService,
|
||||||
|
_imageProcessor,
|
||||||
|
_userDataManager)
|
||||||
.ProcessControlRequest(request);
|
.ProcessControlRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ namespace MediaBrowser.Dlna.Server
|
||||||
sparams.Add(e.LocalName, e.InnerText.Trim());
|
sparams.Add(e.LocalName, e.InnerText.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var deviceId = "fgd";
|
||||||
|
|
||||||
var env = new XmlDocument();
|
var env = new XmlDocument();
|
||||||
env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", "yes"));
|
env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", "yes"));
|
||||||
var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV);
|
var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV);
|
||||||
|
@ -116,7 +118,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
result = HandleGetSystemUpdateID();
|
result = HandleGetSystemUpdateID();
|
||||||
break;
|
break;
|
||||||
case "Browse":
|
case "Browse":
|
||||||
result = HandleBrowse(sparams, user);
|
result = HandleBrowse(sparams, user, deviceId);
|
||||||
break;
|
break;
|
||||||
case "X_GetFeatureList":
|
case "X_GetFeatureList":
|
||||||
result = HandleXGetFeatureList();
|
result = HandleXGetFeatureList();
|
||||||
|
@ -235,7 +237,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<KeyValuePair<string, string>> HandleBrowse(Headers sparams, User user)
|
private IEnumerable<KeyValuePair<string, string>> HandleBrowse(Headers sparams, User user, string deviceId)
|
||||||
{
|
{
|
||||||
var id = sparams["ObjectID"];
|
var id = sparams["ObjectID"];
|
||||||
var flag = sparams["BrowseFlag"];
|
var flag = sparams["BrowseFlag"];
|
||||||
|
@ -298,7 +300,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Browse_AddItem(result, i, user);
|
Browse_AddItem(result, i, user, deviceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,7 +368,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Browse_AddItem(XmlDocument result, BaseItem item, User user)
|
private void Browse_AddItem(XmlDocument result, BaseItem item, User user, string deviceId)
|
||||||
{
|
{
|
||||||
var element = result.CreateElement(string.Empty, "item", NS_DIDL);
|
var element = result.CreateElement(string.Empty, "item", NS_DIDL);
|
||||||
element.SetAttribute("restricted", "1");
|
element.SetAttribute("restricted", "1");
|
||||||
|
@ -389,13 +391,13 @@ namespace MediaBrowser.Dlna.Server
|
||||||
var audio = item as Audio;
|
var audio = item as Audio;
|
||||||
if (audio != null)
|
if (audio != null)
|
||||||
{
|
{
|
||||||
AddAudioResource(element, audio);
|
AddAudioResource(element, audio, deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var video = item as Video;
|
var video = item as Video;
|
||||||
if (video != null)
|
if (video != null)
|
||||||
{
|
{
|
||||||
AddVideoResource(element, video);
|
AddVideoResource(element, video, deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCover(item, element);
|
AddCover(item, element);
|
||||||
|
@ -403,12 +405,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
result.DocumentElement.AppendChild(element);
|
result.DocumentElement.AppendChild(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDeviceId()
|
private void AddVideoResource(XmlElement container, Video video, string deviceId)
|
||||||
{
|
|
||||||
return "erer";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddVideoResource(XmlElement container, Video video)
|
|
||||||
{
|
{
|
||||||
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
||||||
|
|
||||||
|
@ -421,7 +418,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
ItemId = video.Id.ToString("N"),
|
ItemId = video.Id.ToString("N"),
|
||||||
MediaSources = sources,
|
MediaSources = sources,
|
||||||
Profile = _profile,
|
Profile = _profile,
|
||||||
DeviceId = GetDeviceId(),
|
DeviceId = deviceId,
|
||||||
MaxBitrate = maxBitrateSetting
|
MaxBitrate = maxBitrateSetting
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -435,17 +432,21 @@ namespace MediaBrowser.Dlna.Server
|
||||||
res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
|
res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streamInfo.IsDirectStream && mediaSource.Size.HasValue)
|
if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength)
|
||||||
{
|
{
|
||||||
res.SetAttribute("size", mediaSource.Size.Value.ToString(_usCulture));
|
var size = streamInfo.TargetSize;
|
||||||
|
|
||||||
|
if (size.HasValue)
|
||||||
|
{
|
||||||
|
res.SetAttribute("size", size.Value.ToString(_usCulture));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video && !string.Equals(i.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase));
|
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video && !string.Equals(i.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase));
|
||||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
|
||||||
|
|
||||||
var targetAudioBitrate = streamInfo.AudioBitrate ?? (audioStream == null ? null : audioStream.BitRate);
|
var targetAudioBitrate = streamInfo.TargetAudioBitrate;
|
||||||
var targetSampleRate = audioStream == null ? null : audioStream.SampleRate;
|
var targetSampleRate = streamInfo.TargetAudioSampleRate;
|
||||||
var targetChannels = streamInfo.MaxAudioChannels ?? (audioStream == null ? null : audioStream.Channels);
|
var targetChannels = streamInfo.TargetAudioChannels;
|
||||||
|
|
||||||
var targetWidth = streamInfo.MaxWidth ?? (videoStream == null ? null : videoStream.Width);
|
var targetWidth = streamInfo.MaxWidth ?? (videoStream == null ? null : videoStream.Width);
|
||||||
var targetHeight = streamInfo.MaxHeight ?? (videoStream == null ? null : videoStream.Height);
|
var targetHeight = streamInfo.MaxHeight ?? (videoStream == null ? null : videoStream.Height);
|
||||||
|
@ -454,9 +455,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
? (videoStream == null ? null : videoStream.Codec)
|
? (videoStream == null ? null : videoStream.Codec)
|
||||||
: streamInfo.VideoCodec;
|
: streamInfo.VideoCodec;
|
||||||
|
|
||||||
var targetAudioCodec = streamInfo.IsDirectStream
|
var targetAudioCodec = streamInfo.TargetAudioCodec;
|
||||||
? (audioStream == null ? null : audioStream.Codec)
|
|
||||||
: streamInfo.AudioCodec;
|
|
||||||
|
|
||||||
var targetBitrate = maxBitrateSetting ?? mediaSource.Bitrate;
|
var targetBitrate = maxBitrateSetting ?? mediaSource.Bitrate;
|
||||||
|
|
||||||
|
@ -506,7 +505,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
container.AppendChild(res);
|
container.AppendChild(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAudioResource(XmlElement container, Audio audio)
|
private void AddAudioResource(XmlElement container, Audio audio, string deviceId)
|
||||||
{
|
{
|
||||||
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
|
||||||
|
|
||||||
|
@ -517,7 +516,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
ItemId = audio.Id.ToString("N"),
|
ItemId = audio.Id.ToString("N"),
|
||||||
MediaSources = sources,
|
MediaSources = sources,
|
||||||
Profile = _profile,
|
Profile = _profile,
|
||||||
DeviceId = GetDeviceId()
|
DeviceId = deviceId
|
||||||
});
|
});
|
||||||
|
|
||||||
var url = streamInfo.ToDlnaUrl(_serverAddress);
|
var url = streamInfo.ToDlnaUrl(_serverAddress);
|
||||||
|
@ -530,16 +529,19 @@ namespace MediaBrowser.Dlna.Server
|
||||||
res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
|
res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streamInfo.IsDirectStream && mediaSource.Size.HasValue)
|
if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength)
|
||||||
{
|
{
|
||||||
res.SetAttribute("size", mediaSource.Size.Value.ToString(_usCulture));
|
var size = streamInfo.TargetSize;
|
||||||
|
|
||||||
|
if (size.HasValue)
|
||||||
|
{
|
||||||
|
res.SetAttribute("size", size.Value.ToString(_usCulture));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
|
var targetAudioBitrate = streamInfo.TargetAudioBitrate;
|
||||||
|
var targetSampleRate = streamInfo.TargetAudioSampleRate;
|
||||||
var targetAudioBitrate = streamInfo.AudioBitrate ?? (audioStream == null ? null : audioStream.BitRate);
|
var targetChannels = streamInfo.TargetAudioChannels;
|
||||||
var targetSampleRate = audioStream == null ? null : audioStream.SampleRate;
|
|
||||||
var targetChannels = streamInfo.MaxAudioChannels ?? (audioStream == null ? null : audioStream.Channels);
|
|
||||||
|
|
||||||
if (targetChannels.HasValue)
|
if (targetChannels.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MediaBrowser.Dlna.Server
|
||||||
|
|
||||||
private void AppendDeviceProperties(StringBuilder builder)
|
private void AppendDeviceProperties(StringBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Append("<UDN>" + SecurityElement.Escape(_serverUdn) + "</UDN>");
|
builder.Append("<UDN>uuid:" + SecurityElement.Escape(_serverUdn) + "</UDN>");
|
||||||
builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>");
|
builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(_profile.XDlnaDoc))
|
if (!string.IsNullOrWhiteSpace(_profile.XDlnaDoc))
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using System.Linq;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common;
|
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace MediaBrowser.Dlna.Server
|
namespace MediaBrowser.Dlna.Server
|
||||||
|
|
|
@ -222,6 +222,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
public DlnaOptions DlnaOptions { get; set; }
|
public DlnaOptions DlnaOptions { get; set; }
|
||||||
|
|
||||||
|
public double DownMixAudioBoost { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -242,6 +244,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
EnablePeoplePrefixSubFolders = true;
|
EnablePeoplePrefixSubFolders = true;
|
||||||
|
|
||||||
EnableUPnP = true;
|
EnableUPnP = true;
|
||||||
|
DownMixAudioBoost = 2;
|
||||||
|
|
||||||
MinResumePct = 5;
|
MinResumePct = 5;
|
||||||
MaxResumePct = 90;
|
MaxResumePct = 90;
|
||||||
|
|
|
@ -35,17 +35,23 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
private MediaFormatProfile ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestampType)
|
private MediaFormatProfile ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestampType)
|
||||||
{
|
{
|
||||||
// String suffix = "";
|
var suffix = "";
|
||||||
// if (isNoTimestamp(timestampType))
|
|
||||||
// suffix = "_ISO";
|
|
||||||
// else if (timestampType == TransportStreamTimestamp.VALID) {
|
|
||||||
// suffix = "_T";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// String resolution = "S";
|
switch (timestampType)
|
||||||
// if ((width.intValue() > 720) || (height.intValue() > 576)) {
|
{
|
||||||
// resolution = "H";
|
case TransportStreamTimestamp.NONE:
|
||||||
// }
|
suffix = "_ISO";
|
||||||
|
break;
|
||||||
|
case TransportStreamTimestamp.VALID:
|
||||||
|
suffix = "_T";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String resolution = "S";
|
||||||
|
if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576))
|
||||||
|
{
|
||||||
|
resolution = "H";
|
||||||
|
}
|
||||||
|
|
||||||
// if (videoCodec == VideoCodec.MPEG2)
|
// if (videoCodec == VideoCodec.MPEG2)
|
||||||
// {
|
// {
|
||||||
|
@ -55,44 +61,50 @@ namespace MediaBrowser.Model.Dlna
|
||||||
// profiles.add(MediaFormatProfile.MPEG_TS_JP_T);
|
// profiles.add(MediaFormatProfile.MPEG_TS_JP_T);
|
||||||
// }
|
// }
|
||||||
// return profiles;
|
// return profiles;
|
||||||
// }if (videoCodec == VideoCodec.H264)
|
|
||||||
// {
|
|
||||||
// if (audioCodec == AudioCodec.LPCM)
|
|
||||||
// return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_50_LPCM_T);
|
|
||||||
// if (audioCodec == AudioCodec.DTS) {
|
|
||||||
// if (isNoTimestamp(timestampType)) {
|
|
||||||
// return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_DTS_ISO);
|
|
||||||
// }
|
// }
|
||||||
// return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_DTS_T);
|
if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
|
||||||
// }
|
{
|
||||||
// if (audioCodec == AudioCodec.MP2) {
|
if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return MediaFormatProfile.AVC_TS_HD_50_LPCM_T;
|
||||||
|
|
||||||
|
if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (timestampType == TransportStreamTimestamp.NONE)
|
||||||
|
{
|
||||||
|
return MediaFormatProfile.AVC_TS_HD_DTS_ISO;
|
||||||
|
}
|
||||||
|
return MediaFormatProfile.AVC_TS_HD_DTS_T;
|
||||||
|
}
|
||||||
|
//if (audioCodec == AudioCodec.MP2) {
|
||||||
// if (isNoTimestamp(timestampType)) {
|
// if (isNoTimestamp(timestampType)) {
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_ISO", cast(Object[])[ resolution ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_ISO", cast(Object[])[ resolution ])));
|
||||||
// }
|
// }
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_T", cast(Object[])[ resolution ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_T", cast(Object[])[ resolution ])));
|
||||||
// }
|
//}
|
||||||
|
|
||||||
// if (audioCodec == AudioCodec.AAC)
|
//if (audioCodec == AudioCodec.AAC)
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AAC_MULT5%s", cast(Object[])[ resolution, suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AAC_MULT5%s", cast(Object[])[ resolution, suffix ])));
|
||||||
// if (audioCodec == AudioCodec.MP3)
|
//if (audioCodec == AudioCodec.MP3)
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_MPEG1_L3%s", cast(Object[])[ resolution, suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_MPEG1_L3%s", cast(Object[])[ resolution, suffix ])));
|
||||||
// if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) {
|
//if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) {
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AC3%s", cast(Object[])[ resolution, suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AC3%s", cast(Object[])[ resolution, suffix ])));
|
||||||
// }
|
//}
|
||||||
// }
|
}
|
||||||
// else if (videoCodec == VideoCodec.VC1) {
|
else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
|
||||||
// if ((audioCodec is null) || (audioCodec == AudioCodec.AC3))
|
{
|
||||||
// {
|
if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
|
||||||
// if ((width.intValue() > 720) || (height.intValue() > 576)) {
|
{
|
||||||
// return Collections.singletonList(MediaFormatProfile.VC1_TS_AP_L2_AC3_ISO);
|
if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576))
|
||||||
// }
|
{
|
||||||
// return Collections.singletonList(MediaFormatProfile.VC1_TS_AP_L1_AC3_ISO);
|
return MediaFormatProfile.VC1_TS_AP_L2_AC3_ISO;
|
||||||
// }
|
}
|
||||||
|
return MediaFormatProfile.VC1_TS_AP_L1_AC3_ISO;
|
||||||
|
}
|
||||||
// if (audioCodec == AudioCodec.DTS) {
|
// if (audioCodec == AudioCodec.DTS) {
|
||||||
// suffix = suffix.equals("_ISO") ? suffix : "_T";
|
// suffix = suffix.equals("_ISO") ? suffix : "_T";
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("VC1_TS_HD_DTS%s", cast(Object[])[ suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("VC1_TS_HD_DTS%s", cast(Object[])[ suffix ])));
|
||||||
// }
|
// }
|
||||||
// } else if ((videoCodec == VideoCodec.MPEG4) || (videoCodec == VideoCodec.MSMPEG4)) {
|
//} else if ((videoCodec == VideoCodec.MPEG4) || (videoCodec == VideoCodec.MSMPEG4)) {
|
||||||
// if (audioCodec == AudioCodec.AAC)
|
// if (audioCodec == AudioCodec.AAC)
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AAC%s", cast(Object[])[ suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AAC%s", cast(Object[])[ suffix ])));
|
||||||
// if (audioCodec == AudioCodec.MP3)
|
// if (audioCodec == AudioCodec.MP3)
|
||||||
|
@ -102,7 +114,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
// if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) {
|
// if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) {
|
||||||
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AC3%s", cast(Object[])[ suffix ])));
|
// return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AC3%s", cast(Object[])[ suffix ])));
|
||||||
// }
|
// }
|
||||||
// }
|
}
|
||||||
|
|
||||||
throw new ArgumentException("Mpeg video file does not match any supported DLNA profile");
|
throw new ArgumentException("Mpeg video file does not match any supported DLNA profile");
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
ItemId = options.ItemId,
|
ItemId = options.ItemId,
|
||||||
MediaType = DlnaProfileType.Audio,
|
MediaType = DlnaProfileType.Audio,
|
||||||
MediaSourceId = item.Id,
|
MediaSource = item,
|
||||||
RunTimeTicks = item.RunTimeTicks
|
RunTimeTicks = item.RunTimeTicks
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
playlistItem.IsDirectStream = false;
|
playlistItem.IsDirectStream = false;
|
||||||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
|
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||||
playlistItem.Container = transcodingProfile.Container;
|
playlistItem.Container = transcodingProfile.Container;
|
||||||
playlistItem.AudioCodec = transcodingProfile.AudioCodec;
|
playlistItem.AudioCodec = transcodingProfile.AudioCodec;
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
ItemId = options.ItemId,
|
ItemId = options.ItemId,
|
||||||
MediaType = DlnaProfileType.Video,
|
MediaType = DlnaProfileType.Video,
|
||||||
MediaSourceId = item.Id,
|
MediaSource = item,
|
||||||
RunTimeTicks = item.RunTimeTicks
|
RunTimeTicks = item.RunTimeTicks
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -196,6 +197,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
playlistItem.IsDirectStream = false;
|
playlistItem.IsDirectStream = false;
|
||||||
playlistItem.Container = transcodingProfile.Container;
|
playlistItem.Container = transcodingProfile.Container;
|
||||||
|
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||||
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault();
|
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault();
|
||||||
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Dlna
|
namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
|
@ -12,8 +14,6 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
public string ItemId { get; set; }
|
public string ItemId { get; set; }
|
||||||
|
|
||||||
public string MediaSourceId { get; set; }
|
|
||||||
|
|
||||||
public bool IsDirectStream { get; set; }
|
public bool IsDirectStream { get; set; }
|
||||||
|
|
||||||
public DlnaProfileType MediaType { get; set; }
|
public DlnaProfileType MediaType { get; set; }
|
||||||
|
@ -50,6 +50,18 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
|
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
|
||||||
|
|
||||||
|
public bool EstimateContentLength { get; set; }
|
||||||
|
|
||||||
|
public MediaSourceInfo MediaSource { get; set; }
|
||||||
|
|
||||||
|
public string MediaSourceId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return MediaSource == null ? null : MediaSource.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string ToUrl(string baseUrl)
|
public string ToUrl(string baseUrl)
|
||||||
{
|
{
|
||||||
return ToDlnaUrl(baseUrl);
|
return ToDlnaUrl(baseUrl);
|
||||||
|
@ -102,6 +114,136 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return string.Format("Params={0}", string.Join(";", list.ToArray()));
|
return string.Format("Params={0}", string.Join(";", list.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the audio stream that will be used
|
||||||
|
/// </summary>
|
||||||
|
public MediaStream TargetAudioStream
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (MediaSource != null)
|
||||||
|
{
|
||||||
|
var audioStreams = MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio);
|
||||||
|
|
||||||
|
if (AudioStreamIndex.HasValue)
|
||||||
|
{
|
||||||
|
return audioStreams.FirstOrDefault(i => i.Index == AudioStreamIndex.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return audioStreams.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the video stream that will be used
|
||||||
|
/// </summary>
|
||||||
|
public MediaStream TargetVideoStream
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (MediaSource != null)
|
||||||
|
{
|
||||||
|
return MediaSource.MediaStreams
|
||||||
|
.FirstOrDefault(i => i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predicts the audio sample rate that will be in the output stream
|
||||||
|
/// </summary>
|
||||||
|
public int? TargetAudioSampleRate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var stream = TargetAudioStream;
|
||||||
|
return stream == null ? null : stream.SampleRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predicts the audio bitrate that will be in the output stream
|
||||||
|
/// </summary>
|
||||||
|
public int? TargetAudioBitrate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var stream = TargetAudioStream;
|
||||||
|
return AudioBitrate.HasValue && !IsDirectStream
|
||||||
|
? AudioBitrate
|
||||||
|
: stream == null ? null : stream.BitRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predicts the audio channels that will be in the output stream
|
||||||
|
/// </summary>
|
||||||
|
public int? TargetAudioChannels
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var stream = TargetAudioStream;
|
||||||
|
|
||||||
|
return MaxAudioChannels.HasValue && !IsDirectStream
|
||||||
|
? (stream.Channels.HasValue ? Math.Min(MaxAudioChannels.Value, stream.Channels.Value) : MaxAudioChannels.Value)
|
||||||
|
: stream == null ? null : stream.Channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predicts the audio codec that will be in the output stream
|
||||||
|
/// </summary>
|
||||||
|
public string TargetAudioCodec
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var stream = TargetAudioStream;
|
||||||
|
|
||||||
|
return IsDirectStream
|
||||||
|
? (stream == null ? null : stream.Codec)
|
||||||
|
: AudioCodec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predicts the audio channels that will be in the output stream
|
||||||
|
/// </summary>
|
||||||
|
public long? TargetSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsDirectStream)
|
||||||
|
{
|
||||||
|
return MediaSource.Bitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RunTimeTicks.HasValue)
|
||||||
|
{
|
||||||
|
var totalBitrate = 0;
|
||||||
|
|
||||||
|
if (AudioBitrate.HasValue)
|
||||||
|
{
|
||||||
|
totalBitrate += AudioBitrate.Value;
|
||||||
|
}
|
||||||
|
if (VideoBitrate.HasValue)
|
||||||
|
{
|
||||||
|
totalBitrate += VideoBitrate.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(RunTimeTicks.Value).TotalSeconds);
|
||||||
|
}
|
||||||
|
var stream = TargetAudioStream;
|
||||||
|
|
||||||
|
return MaxAudioChannels.HasValue && !IsDirectStream
|
||||||
|
? (stream.Channels.HasValue ? Math.Min(MaxAudioChannels.Value, stream.Channels.Value) : MaxAudioChannels.Value)
|
||||||
|
: stream == null ? null : stream.Channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -356,6 +356,7 @@ namespace MediaBrowser.Server.Implementations.Localization
|
||||||
new LocalizatonOption{ Name="Greek", Value="el"},
|
new LocalizatonOption{ Name="Greek", Value="el"},
|
||||||
new LocalizatonOption{ Name="Hebrew", Value="he"},
|
new LocalizatonOption{ Name="Hebrew", Value="he"},
|
||||||
new LocalizatonOption{ Name="Italian", Value="it"},
|
new LocalizatonOption{ Name="Italian", Value="it"},
|
||||||
|
new LocalizatonOption{ Name="Kazakh", Value="kk"},
|
||||||
new LocalizatonOption{ Name="Norwegian Bokmål", Value="nb"},
|
new LocalizatonOption{ Name="Norwegian Bokmål", Value="nb"},
|
||||||
new LocalizatonOption{ Name="Portuguese (Brazil)", Value="pt-BR"},
|
new LocalizatonOption{ Name="Portuguese (Brazil)", Value="pt-BR"},
|
||||||
new LocalizatonOption{ Name="Portuguese (Portugal)", Value="pt-PT"},
|
new LocalizatonOption{ Name="Portuguese (Portugal)", Value="pt-PT"},
|
||||||
|
|
|
@ -515,5 +515,7 @@
|
||||||
"ServerUpToDate": "Media Browser Server is up to date",
|
"ServerUpToDate": "Media Browser Server is up to date",
|
||||||
"ErrorConnectingToMediaBrowserRepository": "There was an error connecting to the remote Media Browser repository.",
|
"ErrorConnectingToMediaBrowserRepository": "There was an error connecting to the remote Media Browser repository.",
|
||||||
"LabelComponentsUpdated": "The following components have been installed or updated:",
|
"LabelComponentsUpdated": "The following components have been installed or updated:",
|
||||||
"MessagePleaseRestartServerToFinishUpdating": "Please restart the server to finish applying updates."
|
"MessagePleaseRestartServerToFinishUpdating": "Please restart the server to finish applying updates.",
|
||||||
|
"LabelDownMixAudioScale": "Down mix audio boost scale:",
|
||||||
|
"LabelDownMixAudioScaleHelp": "Boost audio when downmixing. Set to 1 to preserve original volume value."
|
||||||
}
|
}
|
Loading…
Reference in a new issue