aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Dlna
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-03-22 15:37:15 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-03-22 15:37:15 -0400
commitbd7486b95249dabe6296c0c8d900baebda34adc8 (patch)
treee7d769098819203225af86db1db27f756955072c /MediaBrowser.Dlna
parent76fe96e3e334cb5423637d30841da3130eace4d3 (diff)
added media profiles
Diffstat (limited to 'MediaBrowser.Dlna')
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs218
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItem.cs2
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs95
-rw-r--r--MediaBrowser.Dlna/PlayTo/StreamHelper.cs24
4 files changed, 276 insertions, 63 deletions
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index 1ec193204c..d073c8316c 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -62,13 +62,11 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"mkv"},
- MimeType = "x-mkv",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"avi"},
- MimeType = "x-msvideo",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
@@ -76,6 +74,23 @@ namespace MediaBrowser.Dlna
Containers = new[]{"mp4"},
Type = DlnaProfileType.Video
}
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="mkv",
+ MimeType = "video/x-mkv",
+ Type = DlnaProfileType.Video
+ }
}
});
@@ -114,13 +129,11 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"mkv"},
- MimeType = "x-mkv",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"avi"},
- MimeType = "x-msvideo",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
@@ -128,6 +141,23 @@ namespace MediaBrowser.Dlna
Containers = new[]{"mp4"},
Type = DlnaProfileType.Video
}
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="mkv",
+ MimeType = "video/x-mkv",
+ Type = DlnaProfileType.Video
+ }
}
});
@@ -166,13 +196,11 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"mkv"},
- MimeType = "x-mkv",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"avi"},
- MimeType = "x-msvideo",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
@@ -180,6 +208,23 @@ namespace MediaBrowser.Dlna
Containers = new[]{"mp4"},
Type = DlnaProfileType.Video
}
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="mkv",
+ MimeType = "video/x-mkv",
+ Type = DlnaProfileType.Video
+ }
}
});
@@ -217,7 +262,6 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"avi"},
- MimeType = "avi",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
@@ -225,6 +269,16 @@ namespace MediaBrowser.Dlna
Containers = new[]{"mp4"},
Type = DlnaProfileType.Video
}
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/avi",
+ Type = DlnaProfileType.Video
+ }
}
});
@@ -263,7 +317,16 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"avi"},
- MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/x-msvideo",
Type = DlnaProfileType.Video
}
}
@@ -303,14 +366,29 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"avi"},
- Type = DlnaProfileType.Video,
- MimeType = "avi"
+ Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"asf"},
- Type = DlnaProfileType.Audio,
- MimeType = "x-ms-wmv"
+ Type = DlnaProfileType.Audio
+ }
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/avi",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="asf",
+ MimeType = "video/x-ms-wmv",
+ Type = DlnaProfileType.Audio
}
}
});
@@ -335,8 +413,7 @@ namespace MediaBrowser.Dlna
new TranscodingProfile
{
Container = "ts",
- Type = DlnaProfileType.Video,
- MimeType = "mpeg"
+ Type = DlnaProfileType.Video
}
},
@@ -350,20 +427,48 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"wma"},
- Type = DlnaProfileType.Audio,
- MimeType = "x-ms-wma"
+ Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Containers = new[]{"avi"},
- Type = DlnaProfileType.Video,
- MimeType = "avi"
+ Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"mp4"},
- Type = DlnaProfileType.Video,
- MimeType = "mp4"
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/avi",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="mp4",
+ MimeType = "video/mp4",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="ts",
+ MimeType = "video/mpeg",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="wma",
+ MimeType = "video/x-ms-wma",
+ Type = DlnaProfileType.Audio
}
}
});
@@ -450,13 +555,21 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"avi"},
- Type = DlnaProfileType.Video ,
- MimeType="divx"
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/divx",
+ Type = DlnaProfileType.Video
}
}
});
- //WDTV does not need any transcoding of the formats we support statically
list.Add(new DeviceProfile
{
Name = "Philips (2010-)",
@@ -479,20 +592,34 @@ namespace MediaBrowser.Dlna
new DirectPlayProfile
{
Containers = new[]{"avi"},
- Type = DlnaProfileType.Video,
- MimeType = "avi"
+ Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Containers = new[]{"mkv"},
- Type = DlnaProfileType.Video,
- MimeType = "x-matroska"
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ MediaProfiles = new[]
+ {
+ new MediaProfile
+ {
+ Container ="avi",
+ MimeType = "video/avi",
+ Type = DlnaProfileType.Video
+ },
+
+ new MediaProfile
+ {
+ Container ="mkv",
+ MimeType = "video/x-matroska",
+ Type = DlnaProfileType.Video
}
}
});
- //WDTV does not need any transcoding of the formats we support statically
list.Add(new DeviceProfile
{
Name = "WDTV Live",
@@ -500,7 +627,30 @@ namespace MediaBrowser.Dlna
Identification = new DeviceIdentification
{
- ModelName = "WD TV HD Live"
+ ModelName = "WD TV HD Live",
+
+ Headers = new List<HttpHeaderInfo>
+ {
+ new HttpHeaderInfo{ Name="User-Agent", Value="alphanetworks", Match= HeaderMatchType.Substring},
+ new HttpHeaderInfo{ Name="User-Agent", Value="ALPHA Networks", Match= HeaderMatchType.Substring}
+ }
+ },
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio,
+ AudioCodec = "mp3"
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video,
+ VideoCodec = "h264",
+ AudioCodec = "aac"
+ }
},
DirectPlayProfiles = new[]
@@ -521,7 +671,7 @@ namespace MediaBrowser.Dlna
list.Add(new DeviceProfile
{
- //Linksys DMA2100us does not need any transcoding of the formats we support statically
+ // Linksys DMA2100us does not need any transcoding of the formats we support statically
Name = "Linksys DMA2100",
ClientType = "DLNA",
@@ -547,10 +697,10 @@ namespace MediaBrowser.Dlna
});
list.Add(new DeviceProfile
- {
+ {
Name = "Denon AVR",
- ClientType = "DLNA",
-
+ ClientType = "DLNA",
+
Identification = new DeviceIdentification
{
FriendlyName = @"Denon:\[AVR:.*",
@@ -612,7 +762,7 @@ namespace MediaBrowser.Dlna
public DeviceProfile GetProfile(DeviceIdentification deviceInfo)
{
- return GetProfiles().FirstOrDefault(i => IsMatch(deviceInfo, i.Identification)) ??
+ return GetProfiles().FirstOrDefault(i => IsMatch(deviceInfo, i.Identification)) ??
GetDefaultProfile();
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
index 3524575631..1304f61b11 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Dlna.PlayTo
public DlnaProfileType MediaType { get; set; }
- public string FileFormat { get; set; }
+ public string Container { get; set; }
public string MimeType { get; set; }
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
index f657df17f4..817dfb86f1 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
@@ -42,8 +42,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (directPlay != null)
{
playlistItem.Transcode = false;
- playlistItem.FileFormat = Path.GetExtension(item.Path);
- playlistItem.MimeType = directPlay.MimeType;
+ playlistItem.Container = Path.GetExtension(item.Path);
return playlistItem;
}
@@ -55,10 +54,11 @@ namespace MediaBrowser.Dlna.PlayTo
{
playlistItem.Transcode = true;
- playlistItem.FileFormat = "." + transcodingProfile.Container.TrimStart('.');
- playlistItem.MimeType = transcodingProfile.MimeType;
+ playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.');
}
+ AttachMediaProfile(playlistItem, profile);
+
return playlistItem;
}
@@ -76,8 +76,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (directPlay != null)
{
playlistItem.Transcode = false;
- playlistItem.FileFormat = Path.GetExtension(item.Path);
- playlistItem.MimeType = directPlay.MimeType;
+ playlistItem.Container = Path.GetExtension(item.Path);
return playlistItem;
}
@@ -89,10 +88,11 @@ namespace MediaBrowser.Dlna.PlayTo
{
playlistItem.Transcode = true;
- playlistItem.FileFormat = "." + transcodingProfile.Container.TrimStart('.');
- playlistItem.MimeType = transcodingProfile.MimeType;
+ playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.');
}
+ AttachMediaProfile(playlistItem, profile);
+
return playlistItem;
}
@@ -119,8 +119,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (directPlay != null)
{
playlistItem.Transcode = false;
- playlistItem.FileFormat = Path.GetExtension(item.Path);
- playlistItem.MimeType = directPlay.MimeType;
+ playlistItem.Container = Path.GetExtension(item.Path);
return playlistItem;
}
@@ -131,25 +130,55 @@ namespace MediaBrowser.Dlna.PlayTo
if (transcodingProfile != null)
{
playlistItem.Transcode = true;
-
- playlistItem.FileFormat = "." + transcodingProfile.Container.TrimStart('.');
- playlistItem.MimeType = transcodingProfile.MimeType;
+ playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.');
}
+ AttachMediaProfile(playlistItem, profile);
+
return playlistItem;
}
+ private void AttachMediaProfile(PlaylistItem item, DeviceProfile profile)
+ {
+ var mediaProfile = GetMediaProfile(item, profile);
+
+ if (mediaProfile != null)
+ {
+ item.MimeType = (mediaProfile.MimeType ?? string.Empty).Split('/').LastOrDefault();
+
+ // TODO: Org_pn?
+ }
+ }
+
+ private MediaProfile GetMediaProfile(PlaylistItem item, DeviceProfile profile)
+ {
+ return profile.MediaProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type == item.MediaType)
+ {
+ if (string.Equals(item.Container.TrimStart('.'), i.Container.TrimStart('.'), StringComparison.OrdinalIgnoreCase))
+ {
+ // TODO: Enforce codecs
+ return true;
+ }
+ }
+
+ return false;
+ });
+ }
+
private bool IsSupported(DirectPlayProfile profile, Photo item)
{
var mediaPath = item.Path;
+ // Check container type
var mediaContainer = Path.GetExtension(mediaPath);
-
if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
+ // Check additional conditions
if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, null, null)))
{
return false;
@@ -162,13 +191,14 @@ namespace MediaBrowser.Dlna.PlayTo
{
var mediaPath = item.Path;
+ // Check container type
var mediaContainer = Path.GetExtension(mediaPath);
-
if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
+ // Check additional conditions
if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, null, audioStream)))
{
return false;
@@ -186,13 +216,34 @@ namespace MediaBrowser.Dlna.PlayTo
var mediaPath = item.Path;
+ // Check container type
var mediaContainer = Path.GetExtension(mediaPath);
-
if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
+ // Check video codec
+ if (profile.VideoCodecs.Length > 0)
+ {
+ var videoCodec = videoStream == null ? null : videoStream.Codec;
+ if (string.IsNullOrWhiteSpace(videoCodec) || !profile.VideoCodecs.Contains(videoCodec, StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ }
+
+ if (profile.AudioCodecs.Length > 0)
+ {
+ // Check audio codecs
+ var audioCodec = audioStream == null ? null : audioStream.Codec;
+ if (string.IsNullOrWhiteSpace(audioCodec) || !profile.AudioCodecs.Contains(audioCodec, StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ }
+
+ // Check additional conditions
if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, videoStream, audioStream)))
{
return false;
@@ -283,6 +334,8 @@ namespace MediaBrowser.Dlna.PlayTo
return videoStream == null ? null : videoStream.Height;
case ProfileConditionValue.VideoWidth:
return videoStream == null ? null : videoStream.Width;
+ case ProfileConditionValue.VideoLevel:
+ return videoStream == null ? null : ConvertToLong(videoStream.Level);
default:
throw new InvalidOperationException("Unexpected Property");
}
@@ -297,5 +350,15 @@ namespace MediaBrowser.Dlna.PlayTo
{
return val.HasValue ? Convert.ToInt64(val.Value) : (long?)null;
}
+
+ /// <summary>
+ /// Converts to long.
+ /// </summary>
+ /// <param name="val">The value.</param>
+ /// <returns>System.Nullable{System.Int64}.</returns>
+ private long? ConvertToLong(double? val)
+ {
+ return val.HasValue ? Convert.ToInt64(val.Value) : (long?)null;
+ }
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
index f5025fdd61..cb2b72a038 100644
--- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
+++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
@@ -24,39 +24,39 @@ namespace MediaBrowser.Dlna.PlayTo
var contentFeatures = string.Empty;
- if (string.Equals(item.FileFormat, "mp3", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(item.Container, "mp3", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MP3";
}
- else if (string.Equals(item.FileFormat, "wma", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "wma", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=WMABASE";
}
- else if (string.Equals(item.FileFormat, "wmw", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "wmw", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=WMVMED_BASE";
}
- else if (string.Equals(item.FileFormat, "asf", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "asf", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=WMVMED_BASE";
}
- else if (string.Equals(item.FileFormat, "avi", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "avi", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=AVI";
}
- else if (string.Equals(item.FileFormat, "mkv", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "mkv", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MATROSKA";
}
- else if (string.Equals(item.FileFormat, "mp4", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "mp4", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC";
}
- else if (string.Equals(item.FileFormat, "mpeg", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "mpeg", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
}
- else if (string.Equals(item.FileFormat, "ts", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(item.Container, "ts", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
}
@@ -85,7 +85,7 @@ namespace MediaBrowser.Dlna.PlayTo
internal static string GetAudioUrl(PlaylistItem item, string serverAddress)
{
if (!item.Transcode)
- return string.Format("{0}/audio/{1}/stream{2}?Static=True", serverAddress, item.ItemId, item.FileFormat);
+ return string.Format("{0}/audio/{1}/stream{2}?Static=True", serverAddress, item.ItemId, item.Container);
return string.Format("{0}/audio/{1}/stream.mp3?AudioCodec=Mp3", serverAddress, item.ItemId);
}
@@ -108,7 +108,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (!item.Transcode)
{
dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, null, null, null, null, null, null, null, null, null, null, item.MimeType);
- return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
+ return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand);
}
var videostream = streams.Where(m => m.Type == MediaStreamType.Video).OrderBy(m => m.IsDefault).FirstOrDefault();
var audiostream = streams.Where(m => m.Type == MediaStreamType.Audio).OrderBy(m => m.IsDefault).FirstOrDefault();
@@ -129,7 +129,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3", item.MimeType);
- return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
+ return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand);
}
/// <summary>