expose more dlna profile settings in the web interface

This commit is contained in:
Luke Pulverenti 2014-04-20 21:36:12 -04:00
parent 247400717e
commit 3b4be92038
37 changed files with 239 additions and 57 deletions

View file

@ -110,7 +110,19 @@ namespace MediaBrowser.Api.UserLibrary
return items
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(name => LibraryManager.GetGenre(name));
.Select(name =>
{
try
{
return LibraryManager.GetGenre(name);
}
catch (Exception ex)
{
Logger.ErrorException("Error getting genre {0}", ex, name);
return null;
}
})
.Where(i => i != null);
}
}
}

View file

@ -49,7 +49,7 @@ namespace MediaBrowser.Dlna
_userDataManager = userDataManager;
_config = config;
//DumpProfiles();
DumpProfiles();
}
public IEnumerable<DeviceProfile> GetProfiles()

View file

@ -20,6 +20,11 @@ namespace MediaBrowser.Dlna.Profiles
ModelUrl = "http://mediabrowser3.com/";
ManufacturerUrl = "http://mediabrowser3.com/";
AlbumArtPn = "JPEG_SM";
MaxAlbumArtHeight = 512;
MaxAlbumArtWidth = 512;
TranscodingProfiles = new[]
{
new TranscodingProfile

View file

@ -1,6 +1,5 @@
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Model.Dlna;
using System.Xml.Serialization;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Dlna.Profiles
{

View file

@ -11,6 +11,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -16,6 +16,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -17,6 +17,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -15,6 +15,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>10</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -15,6 +15,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<XDlnaDoc>DMS-1.50</XDlnaDoc>
<SonyAggregationFlags>10</SonyAggregationFlags>
<ProtocolInfo>DLNA</ProtocolInfo>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>5</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -18,6 +18,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<XDlnaDoc>DMS-1.50</XDlnaDoc>
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>40</TimelineOffsetSeconds>

View file

@ -16,6 +16,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<XDlnaDoc>DMS-1.50</XDlnaDoc>
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>

View file

@ -17,6 +17,12 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<SupportedMediaTypes>Audio</SupportedMediaTypes>
<AlbumArtPn>JPEG_SM</AlbumArtPn>
<MaxAlbumArtWidth>512</MaxAlbumArtWidth>
<MaxAlbumArtHeight>512</MaxAlbumArtHeight>
<MaxIconWidth xsi:nil="true" />
<MaxIconHeight xsi:nil="true" />
<MaxBitrate xsi:nil="true" />
<ProtocolInfo>DLNA</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>

View file

@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
@ -265,7 +266,7 @@ namespace MediaBrowser.Dlna.Server
var children = GetChildrenSorted(folder, user, sortCriteria).ToList();
var totalCount = children.Count;
if (string.Equals(flag, "BrowseMetadata"))
{
Browse_AddFolder(result, folder, children.Count, filter);
@ -818,14 +819,14 @@ namespace MediaBrowser.Dlna.Server
}
}
if (item.Genres.Count > 0)
foreach (var genre in item.Genres)
{
AddValue(element, "upnp", "genre", item.Genres[0], NS_UPNP);
AddValue(element, "upnp", "genre", genre, NS_UPNP);
}
if (item.Studios.Count > 0)
foreach (var studio in item.Studios)
{
AddValue(element, "upnp", "publisher", item.Studios[0], NS_UPNP);
AddValue(element, "upnp", "publisher", studio, NS_UPNP);
}
if (filter.Contains("dc:title"))
@ -871,9 +872,9 @@ namespace MediaBrowser.Dlna.Server
if (audio != null)
{
if (audio.Artists.Count > 0)
foreach (var artist in audio.Artists)
{
AddValue(element, "upnp", "artist", audio.Artists[0], NS_UPNP);
AddValue(element, "upnp", "artist", artist, NS_UPNP);
}
if (!string.IsNullOrEmpty(audio.Album))
@ -930,20 +931,21 @@ namespace MediaBrowser.Dlna.Server
var result = element.OwnerDocument;
var curl = GetImageUrl(imageInfo);
var albumartUrlInfo = GetImageUrl(imageInfo, _profile.MaxAlbumArtWidth, _profile.MaxAlbumArtHeight);
var icon = result.CreateElement("upnp", "albumArtURI", NS_UPNP);
var profile = result.CreateAttribute("dlna", "profileID", NS_DLNA);
profile.InnerText = "JPEG_TN";
profile.InnerText = _profile.AlbumArtPn;
icon.SetAttributeNode(profile);
icon.InnerText = curl;
icon.InnerText = albumartUrlInfo.Url;
element.AppendChild(icon);
var iconUrlInfo = GetImageUrl(imageInfo, _profile.MaxIconWidth, _profile.MaxIconHeight);
icon = result.CreateElement("upnp", "icon", NS_UPNP);
profile = result.CreateAttribute("dlna", "profileID", NS_DLNA);
profile.InnerText = "JPEG_TN";
profile.InnerText = _profile.AlbumArtPn;
icon.SetAttributeNode(profile);
icon.InnerText = curl;
icon.InnerText = iconUrlInfo.Url;
element.AppendChild(icon);
if (!_profile.EnableAlbumArtInDidl)
@ -952,10 +954,11 @@ namespace MediaBrowser.Dlna.Server
}
var res = result.CreateElement(string.Empty, "res", NS_DIDL);
res.InnerText = curl;
int? width = imageInfo.Width;
int? height = imageInfo.Height;
res.InnerText = albumartUrlInfo.Url;
var width = albumartUrlInfo.Width;
var height = albumartUrlInfo.Height;
var mediaProfile = new MediaFormatProfileResolver().ResolveImageFormat("jpg", width, height);
@ -968,11 +971,6 @@ namespace MediaBrowser.Dlna.Server
{
res.SetAttribute("resolution", string.Format("{0}x{1}", width.Value, height.Value));
}
else
{
// TODO: Devices need to see something here?
res.SetAttribute("resolution", "200x200");
}
element.AppendChild(res);
}
@ -1052,13 +1050,57 @@ namespace MediaBrowser.Dlna.Server
internal int? Height;
}
private string GetImageUrl(ImageDownloadInfo info)
class ImageUrlInfo
{
return string.Format("{0}/Items/{1}/Images/{2}?tag={3}&format=jpg",
internal string Url;
internal int? Width;
internal int? Height;
}
private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int? maxWidth, int? maxHeight)
{
var url = string.Format("{0}/Items/{1}/Images/{2}?tag={3}&format=jpg",
_serverAddress,
info.ItemId,
info.Type,
info.ImageTag);
if (maxWidth.HasValue)
{
url += "&maxWidth=" + maxWidth.Value.ToString(_usCulture);
}
if (maxHeight.HasValue)
{
url += "&maxHeight=" + maxHeight.Value.ToString(_usCulture);
}
var width = info.Width;
var height = info.Height;
if (width.HasValue && height.HasValue)
{
if (maxWidth.HasValue || maxHeight.HasValue)
{
var newSize = DrawingUtils.Resize(new ImageSize
{
Height = height.Value,
Width = width.Value
}, maxWidth: maxWidth, maxHeight: maxHeight);
width = Convert.ToInt32(newSize.Width);
height = Convert.ToInt32(newSize.Height);
}
}
return new ImageUrlInfo
{
Url = url,
Width = width,
Height = height
};
}
}
}

View file

@ -59,7 +59,7 @@ namespace MediaBrowser.Dlna.Server
{
builder.Append("<UDN>uuid:" + SecurityElement.Escape(_serverUdn) + "</UDN>");
builder.Append("<dlna:X_DLNACAP>" + SecurityElement.Escape(_profile.XDlnaCap ?? string.Empty) + "</dlna:X_DLNACAP>");
if (!string.IsNullOrWhiteSpace(_profile.XDlnaDoc))
{
builder.Append("<dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" +
@ -82,6 +82,11 @@ namespace MediaBrowser.Dlna.Server
builder.Append("<sec:ProductCap>DCM10,getMediaInfo.sec</sec:ProductCap>");
builder.Append("<sec:X_ProductCap>DCM10,getMediaInfo.sec</sec:X_ProductCap>");
if (!string.IsNullOrWhiteSpace(_profile.SonyAggregationFlags))
{
builder.Append("<av:aggregationFlags xmlns:av=\"urn:schemas-sony-com:av\">" + SecurityElement.Escape(_profile.SonyAggregationFlags) + "</av:aggregationFlags>");
}
}
private void AppendIconList(StringBuilder builder)

View file

@ -923,14 +923,6 @@ namespace MediaBrowser.Model.ApiClient
/// <exception cref="ArgumentNullException">options</exception>
string GetVideoStreamUrl(VideoStreamOptions options);
/// <summary>
/// Formulates a url for streaming audio using the HLS protocol
/// </summary>
/// <param name="options">The options.</param>
/// <returns>System.String.</returns>
/// <exception cref="ArgumentNullException">options</exception>
string GetHlsAudioStreamUrl(StreamOptions options);
/// <summary>
/// Formulates a url for streaming video using the HLS protocol
/// </summary>

View file

@ -17,7 +17,7 @@ namespace MediaBrowser.Model.Configuration
EnableServer = true;
BlastAliveMessages = true;
ClientDiscoveryIntervalSeconds = 60;
BlastAliveMessageIntervalSeconds = 60;
BlastAliveMessageIntervalSeconds = 30;
}
}
}

View file

@ -41,6 +41,16 @@ namespace MediaBrowser.Model.Dlna
public string SupportedMediaTypes { get; set; }
public string UserId { get; set; }
public string AlbumArtPn { get; set; }
public int? MaxAlbumArtWidth { get; set; }
public int? MaxAlbumArtHeight { get; set; }
public int? MaxIconWidth { get; set; }
public int? MaxIconHeight { get; set; }
public int? MaxBitrate { get; set; }
/// <summary>
/// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.

View file

@ -85,10 +85,12 @@ namespace MediaBrowser.Model.Dlna
RunTimeTicks = item.RunTimeTicks
};
var maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate;
var audioStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
// Honor the max bitrate setting
if (IsAudioEligibleForDirectPlay(item, options))
if (IsAudioEligibleForDirectPlay(item, maxBitrateSetting))
{
var directPlay = options.Profile.DirectPlayProfiles
.FirstOrDefault(i => i.Type == playlistItem.MediaType && IsAudioDirectPlaySupported(i, item, audioStream));
@ -119,6 +121,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.Container = transcodingProfile.Container;
playlistItem.AudioCodec = transcodingProfile.AudioCodec;
playlistItem.Protocol = transcodingProfile.Protocol;
var audioTranscodingConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec))
@ -136,11 +139,11 @@ namespace MediaBrowser.Model.Dlna
}
// Honor requested max bitrate
if (options.MaxBitrate.HasValue)
if (maxBitrateSetting.HasValue)
{
var currentValue = playlistItem.AudioBitrate ?? options.MaxBitrate.Value;
var currentValue = playlistItem.AudioBitrate ?? maxBitrateSetting.Value;
playlistItem.AudioBitrate = Math.Min(options.MaxBitrate.Value, currentValue);
playlistItem.AudioBitrate = Math.Min(maxBitrateSetting.Value, currentValue);
}
}
@ -160,7 +163,9 @@ namespace MediaBrowser.Model.Dlna
var audioStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
var videoStream = item.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
if (IsEligibleForDirectPlay(item, options))
var maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate;
if (IsEligibleForDirectPlay(item, options, maxBitrateSetting))
{
// See if it can be direct played
var directPlay = options.Profile.DirectPlayProfiles
@ -201,6 +206,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault();
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
playlistItem.Protocol = transcodingProfile.Protocol;
var videoTranscodingConditions = options.Profile.CodecProfiles
.Where(i => i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec))
@ -233,9 +239,9 @@ namespace MediaBrowser.Model.Dlna
}
// Honor max rate
if (options.MaxBitrate.HasValue)
if (maxBitrateSetting.HasValue)
{
var videoBitrate = options.MaxBitrate.Value;
var videoBitrate = maxBitrateSetting.Value;
if (playlistItem.AudioBitrate.HasValue)
{
@ -251,7 +257,7 @@ namespace MediaBrowser.Model.Dlna
return playlistItem;
}
private bool IsEligibleForDirectPlay(MediaSourceInfo item, VideoOptions options)
private bool IsEligibleForDirectPlay(MediaSourceInfo item, VideoOptions options, int? maxBitrate)
{
if (options.SubtitleStreamIndex.HasValue)
{
@ -264,13 +270,13 @@ namespace MediaBrowser.Model.Dlna
return false;
}
return IsAudioEligibleForDirectPlay(item, options);
return IsAudioEligibleForDirectPlay(item, maxBitrate);
}
private bool IsAudioEligibleForDirectPlay(MediaSourceInfo item, AudioOptions options)
private bool IsAudioEligibleForDirectPlay(MediaSourceInfo item, int? maxBitrate)
{
// Honor the max bitrate setting
return !options.MaxBitrate.HasValue || (item.Bitrate.HasValue && item.Bitrate.Value <= options.MaxBitrate.Value);
return !maxBitrate.HasValue || (item.Bitrate.HasValue && item.Bitrate.Value <= maxBitrate.Value);
}
private void ValidateInput(VideoOptions options)

View file

@ -20,6 +20,8 @@ namespace MediaBrowser.Model.Dlna
public string Container { get; set; }
public string Protocol { get; set; }
public long StartPositionTicks { get; set; }
public string VideoCodec { get; set; }
@ -84,6 +86,12 @@ namespace MediaBrowser.Model.Dlna
{
return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand);
}
if (string.Equals(Protocol, "hls", StringComparison.OrdinalIgnoreCase))
{
return string.Format("{0}/videos/{1}/stream.m3u8?{2}", baseUrl, ItemId, dlnaCommand);
}
return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand);
}

View file

@ -1 +1 @@
{"SettingsSaved":"\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b1\u03bd","AddUser":"\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7","Users":"\u039f\u03b9 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2","Delete":"\u0394\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03c4\u03b5","Administrator":"\u03c4\u03bf \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae\u03c2","Password":"\u03c4\u03bf\u03bd \u03ba\u03ce\u03b4\u03b9\u03ba\u03b1\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2","DeleteImage":"\u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1","DeleteImageConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7\u03bd \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1;","FileReadCancelled":"\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b9\u03b1\u03b2\u03ac\u03b6\u03b5\u03c4\u03b1\u03b9 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03ba\u03c5\u03c1\u03c9\u03b8\u03b5\u03af","FileNotFound":"\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5","FileReadError":"\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b1\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5","DeleteUser":"\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7","DeleteUserConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5","PasswordResetHeader":"\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2","PasswordResetComplete":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03ad\u03c7\u03b5\u03b9 \u03b3\u03af\u03bd\u03b5\u03b9 \u03b5\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac","PasswordResetConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b1\u03bd\u03b1\u03c6\u03ad\u03c1\u03b5\u03c4\u03b5 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2;","PasswordSaved":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5","PasswordMatchError":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03ba\u03b1\u03b9 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03b5\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03af\u03c9\u03c3\u03b7\u03c2 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c4\u03b1\u03b9\u03c1\u03b9\u03ac\u03b6\u03bf\u03c5\u03bd","OptionOff":"\u03c3\u03b2\u03b7\u03c3\u03c4\u03cc\u03c2","OptionOn":"On","OptionRelease":"\u0397 \u03b5\u03c0\u03af\u03c3\u03b7\u03bc\u03b7 \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7","OptionBeta":"\u03b2\u03ae\u03c4\u03b1","OptionDev":"\u03b1\u03bd\u03ac\u03c0\u03c4\u03c5\u03be\u03b7 (\u03b1\u03c3\u03c4\u03b1\u03b8\u03ae\u03c2)","UninstallPluginHeader":"Uninstall Plugin","UninstallPluginConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03c3\u03b5\u03c4\u03b5;","NoPluginConfigurationMessage":"This plugin has nothing to configure.","NoPluginsInstalledMessage":"You have no plugins installed.","BrowsePluginCatalogMessage":"Browse our plugin catalog to view available plugins."}
{"SettingsSaved":"\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b1\u03bd","AddUser":"\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7","Users":"\u039f\u03b9 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2","Delete":"\u0394\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03c4\u03b5","Administrator":"\u03c4\u03bf \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae\u03c2","Password":"\u03c4\u03bf\u03bd \u03ba\u03ce\u03b4\u03b9\u03ba\u03b1\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2","DeleteImage":"\u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1","DeleteImageConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7\u03bd \u03b5\u03b9\u03ba\u03cc\u03bd\u03b1;","FileReadCancelled":"\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b9\u03b1\u03b2\u03ac\u03b6\u03b5\u03c4\u03b1\u03b9 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03ba\u03c5\u03c1\u03c9\u03b8\u03b5\u03af","FileNotFound":"\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5","FileReadError":"\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b1\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5","DeleteUser":"\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7","DeleteUserConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5","PasswordResetHeader":"\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2","PasswordResetComplete":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03ad\u03c7\u03b5\u03b9 \u03b3\u03af\u03bd\u03b5\u03b9 \u03b5\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac","PasswordResetConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b1\u03bd\u03b1\u03c6\u03ad\u03c1\u03b5\u03c4\u03b5 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2;","PasswordSaved":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5","PasswordMatchError":"\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03ba\u03b1\u03b9 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03b5\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03af\u03c9\u03c3\u03b7\u03c2 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c4\u03b1\u03b9\u03c1\u03b9\u03ac\u03b6\u03bf\u03c5\u03bd","OptionOff":"\u03c3\u03b2\u03b7\u03c3\u03c4\u03cc\u03c2","OptionOn":"On","OptionRelease":"\u0397 \u03b5\u03c0\u03af\u03c3\u03b7\u03bc\u03b7 \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7","OptionBeta":"\u03b2\u03ae\u03c4\u03b1","OptionDev":"\u03b1\u03bd\u03ac\u03c0\u03c4\u03c5\u03be\u03b7 (\u03b1\u03c3\u03c4\u03b1\u03b8\u03ae\u03c2)","UninstallPluginHeader":"\u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b7\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf plugin","UninstallPluginConfirmation":"\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03c3\u03b5\u03c4\u03b5;","NoPluginConfigurationMessage":"\u0391\u03c5\u03c4\u03cc \u03c4\u03bf plugin \u03ad\u03c7\u03b5\u03b9 \u03c4\u03af\u03c0\u03bf\u03c4\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03ce\u03c3\u03b5\u03c4\u03b5","NoPluginsInstalledMessage":"\u0388\u03c7\u03b5\u03c4\u03b5 \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03c3\u03b5\u03b9 \u03ba\u03b1\u03bd\u03ad\u03bd\u03b1 plugins ","BrowsePluginCatalogMessage":"\u03a0\u03bb\u03bf\u03b7\u03b3\u03b7\u03b8\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03bf\u03bd \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf plugin \u03bc\u03b1\u03c2 \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b5\u03af\u03c4\u03b5 \u03c4\u03b1 \u03b4\u03b9\u03b1\u03b8\u03ad\u03c3\u03b9\u03bc\u03b1 plugins"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -59,6 +59,7 @@
"LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons",
"LabelUnairedMissingEpisodesWithinSeasons": "Display unaired episodes within seasons",
"HeaderVideoPlaybackSettings": "Video Playback Settings",
"HeaderPlaybackSettings": "Playback Settings",
"LabelAudioLanguagePreference": "Audio language preference:",
"LabelSubtitleLanguagePreference": "Subtitle language preference:",
"LabelDisplayForcedSubtitlesOnly": "Display only forced subtitles",
@ -418,7 +419,7 @@
"HeaderCustomDlnaProfiles": "Custom Profiles",
"HeaderSystemDlnaProfiles": "System Profiles",
"CustomDlnaProfilesHelp": "Create a custom profile to target a new device or override a system profile.",
"SystemDlnaProfilesHelp": "System profiles are read-only. To override a system profile, create a custom profile targeting the same device.",
"SystemDlnaProfilesHelp": "System profiles are read-only. Changes to a system profile will be saved to a new custom profile.",
"TitleDashboard": "Dashboard",
"TabHome": "Home",
"TabInfo": "Info",
@ -542,5 +543,5 @@
"LabelBlastMessageInterval": "Alive message interval (seconds)",
"LabelBlastMessageIntervalHelp": "Determines the duration in seconds between server alive messages.",
"LabelDefaultUser": "Default user:",
"LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden using a device profile."
"LabelDefaultUserHelp": "Determines which user library should be displayed on connected devices. This can be overridden for each device using profiles."
}

File diff suppressed because one or more lines are too long