diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index c1a4fa765a..383d0881e9 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -74,6 +74,8 @@ namespace MediaBrowser.Controller.Providers
/// The cancellation token.
private void Fetch(MetadataResult item, string metadataFile, XmlReaderSettings settings, Encoding encoding, CancellationToken cancellationToken)
{
+ item.ResetPeople();
+
using (var streamReader = new StreamReader(metadataFile, encoding))
{
// Use XmlReader for best performance
@@ -492,7 +494,7 @@ namespace MediaBrowser.Controller.Providers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
break;
}
@@ -504,7 +506,7 @@ namespace MediaBrowser.Controller.Providers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
break;
}
@@ -529,7 +531,7 @@ namespace MediaBrowser.Controller.Providers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
}
break;
@@ -543,7 +545,7 @@ namespace MediaBrowser.Controller.Providers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
break;
}
@@ -1156,7 +1158,7 @@ namespace MediaBrowser.Controller.Providers
{
continue;
}
- PeopleHelper.AddPerson(item.People, person);
+ item.AddPerson(person);
}
}
break;
diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs
index a18dd83e83..68cdf4d725 100644
--- a/MediaBrowser.Controller/Providers/MetadataResult.cs
+++ b/MediaBrowser.Controller/Providers/MetadataResult.cs
@@ -10,9 +10,26 @@ namespace MediaBrowser.Controller.Providers
public bool HasMetadata { get; set; }
public T Item { get; set; }
- public MetadataResult()
+ public void AddPerson(PersonInfo p)
{
- People = new List();
+ if (People == null)
+ {
+ People = new List();
+ }
+
+ PeopleHelper.AddPerson(People, p);
+ }
+
+ ///
+ /// Not only does this clear, but initializes the list so that services can differentiate between a null list and zero people
+ ///
+ public void ResetPeople()
+ {
+ if (People == null)
+ {
+ People = new List();
+ }
+ People.Clear();
}
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index c3d1ec0809..9aa6485f10 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -194,6 +194,15 @@ namespace MediaBrowser.Providers.Manager
return updateType;
}
+ protected async Task SaveItem(MetadataResult result, ItemUpdateType reason, CancellationToken cancellationToken)
+ {
+ if (result.Item.SupportsPeople && result.People != null)
+ {
+ await LibraryManager.UpdatePeople(result.Item as BaseItem, result.People.ToList());
+ }
+ await result.Item.UpdateToRepository(reason, cancellationToken).ConfigureAwait(false);
+ }
+
private readonly Task _cachedTask = Task.FromResult(true);
protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
@@ -328,15 +337,6 @@ namespace MediaBrowser.Providers.Manager
return providers;
}
- protected async Task SaveItem(MetadataResult result, ItemUpdateType reason, CancellationToken cancellationToken)
- {
- if (result.Item.SupportsPeople)
- {
- await LibraryManager.UpdatePeople(result.Item as BaseItem, result.People);
- }
- await result.Item.UpdateToRepository(reason, cancellationToken).ConfigureAwait(false);
- }
-
public bool CanRefresh(IHasMetadata item)
{
return item is TItemType;
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index a0a0493d54..fa4840f103 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -105,9 +105,9 @@ namespace MediaBrowser.Providers.Manager
if (!lockedFields.Contains(MetadataFields.Cast))
{
- if (replaceData || targetResult.People.Count == 0)
+ if (replaceData || targetResult.People == null || targetResult.People.Count == 0)
{
- targetResult.People = sourceResult.People;
+ targetResult.People = sourceResult.People ?? new List();
}
}
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 6854ff12bf..5b5afc6c73 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -231,13 +231,15 @@ namespace MediaBrowser.Providers.Movies
movie.AddGenre(genre);
}
+ resultItem.ResetPeople();
+
//Actors, Directors, Writers - all in People
//actors come from cast
if (movieData.casts != null && movieData.casts.cast != null)
{
foreach (var actor in movieData.casts.cast.OrderBy(a => a.order))
{
- PeopleHelper.AddPerson(resultItem.People, new PersonInfo { Name = actor.name.Trim(), Role = actor.character, Type = PersonType.Actor, SortOrder = actor.order });
+ resultItem.AddPerson(new PersonInfo { Name = actor.name.Trim(), Role = actor.character, Type = PersonType.Actor, SortOrder = actor.order });
}
}
@@ -246,7 +248,7 @@ namespace MediaBrowser.Providers.Movies
{
foreach (var person in movieData.casts.crew)
{
- PeopleHelper.AddPerson(resultItem.People, new PersonInfo { Name = person.name.Trim(), Role = person.job, Type = person.department });
+ resultItem.AddPerson(new PersonInfo { Name = person.name.Trim(), Role = person.job, Type = person.department });
}
}
diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
index f36de88c95..1702a50448 100644
--- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
@@ -330,6 +330,8 @@ namespace MediaBrowser.Providers.TV
{
reader.MoveToContent();
+ result.ResetPeople();
+
// Loop through each element
while (reader.Read())
{
@@ -603,7 +605,7 @@ namespace MediaBrowser.Providers.TV
.Where(i => !string.IsNullOrWhiteSpace(i))
.Select(str => new PersonInfo { Type = personType, Name = str.Trim() }))
{
- PeopleHelper.AddPerson(result.People, person);
+ result.AddPerson(person);
}
}
@@ -632,7 +634,7 @@ namespace MediaBrowser.Providers.TV
{
if (!string.IsNullOrWhiteSpace(person.Name))
{
- PeopleHelper.AddPerson(result.People, person);
+ result.AddPerson(person);
}
}
}
diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
index 4c93bd57c8..3298fbc76f 100644
--- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
@@ -180,6 +180,8 @@ namespace MediaBrowser.Providers.TV
cancellationToken.ThrowIfCancellationRequested();
+ result.ResetPeople();
+
FetchActors(result, actorsXmlPath);
}
@@ -721,7 +723,7 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrWhiteSpace(personInfo.Name))
{
- PeopleHelper.AddPerson(result.People, personInfo);
+ result.AddPerson(personInfo);
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index d9f1541c8c..50303a89a5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -73,14 +73,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
- public async Task> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
+ private async Task GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken)
{
string model = null;
using (var stream = await _httpClient.Get(new HttpRequestOptions()
{
Url = string.Format("{0}/", GetApiUrl(info, false)),
- CancellationToken = cancellationToken
+ CancellationToken = cancellationToken,
+ CacheLength = TimeSpan.FromDays(1),
+ CacheMode = CacheMode.Unconditional
}))
{
using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8))
@@ -95,6 +97,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
+ return null;
+ }
+
+ public async Task> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
+ {
+ string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
+
using (var stream = await _httpClient.Get(new HttpRequestOptions()
{
Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
@@ -198,9 +207,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private MediaSourceInfo GetMediaSource(TunerHostInfo info, string channelId, string profile)
{
+ int? width = null;
+ int? height = null;
+ bool isInterlaced = true;
+ var videoCodec = "mpeg2video";
+ int? videoBitrate = null;
+
+ if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 1280;
+ height = 720;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 2000000;
+ }
+ else if (string.Equals(profile, "heavy", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 1920;
+ height = 1080;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 8000000;
+ }
+ else if (string.Equals(profile, "internet720", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 1280;
+ height = 720;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 5000000;
+ }
+ else if (string.Equals(profile, "internet540", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 1280;
+ height = 720;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 2500000;
+ }
+ else if (string.Equals(profile, "internet480", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 848;
+ height = 480;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 2000000;
+ }
+ else if (string.Equals(profile, "internet360", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 640;
+ height = 360;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 1500000;
+ }
+ else if (string.Equals(profile, "internet240", StringComparison.OrdinalIgnoreCase))
+ {
+ width = 432;
+ height = 240;
+ isInterlaced = false;
+ videoCodec = "h264";
+ videoBitrate = 1000000;
+ }
+
+ var url = GetApiUrl(info, true) + "/auto/v" + channelId;
+
+ if (!string.IsNullOrWhiteSpace(profile))
+ {
+ url += "?transcode=" + profile;
+ }
+
var mediaSource = new MediaSourceInfo
{
- Path = GetApiUrl(info, true) + "/auto/v" + channelId,
+ Path = url,
Protocol = MediaProtocol.Http,
MediaStreams = new List
{
@@ -209,14 +288,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Type = MediaStreamType.Video,
// Set the index to -1 because we don't know the exact index of the video stream within the container
Index = -1,
- IsInterlaced = true
+ IsInterlaced = isInterlaced,
+ Codec = videoCodec,
+ Width = width,
+ Height = height,
+ BitRate = videoBitrate
+
},
new MediaStream
{
Type = MediaStreamType.Audio,
// Set the index to -1 because we don't know the exact index of the audio stream within the container
- Index = -1
-
+ Index = -1,
+ Codec = "ac3",
+ BitRate = 128000
}
},
RequiresOpening = false,
@@ -227,13 +312,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return mediaSource;
}
- public Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
+ public async Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
{
var list = new List();
list.Add(GetMediaSource(info, channelId, null));
- return Task.FromResult(list);
+ try
+ {
+ string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
+ model = model ?? string.Empty;
+
+ if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ list.Add(GetMediaSource(info, channelId, "heavy"));
+ list.Add(GetMediaSource(info, channelId, "internet480"));
+ list.Add(GetMediaSource(info, channelId, "internet360"));
+ list.Add(GetMediaSource(info, channelId, "internet240"));
+ list.Add(GetMediaSource(info, channelId, "mobile"));
+ }
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ return list;
}
public async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index ad514492d7..d66d7ff19a 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -84,6 +84,8 @@ namespace MediaBrowser.XbmcMetadata.Parsers
/// The cancellation token.
private void Fetch(LocalMetadataResult item, string metadataFile, XmlReaderSettings settings, CancellationToken cancellationToken)
{
+ item.ResetPeople();
+
if (!SupportsUrlAfterClosingXmlTag)
{
using (var streamReader = BaseNfoSaver.GetStreamReader(metadataFile))
@@ -574,7 +576,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
break;
}
@@ -593,7 +595,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
}
break;
@@ -607,7 +609,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
{
continue;
}
- PeopleHelper.AddPerson(itemResult.People, p);
+ itemResult.AddPerson(p);
}
break;
}
@@ -618,7 +620,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
{
var person = GetPersonFromXmlNode(subtree);
- PeopleHelper.AddPerson(itemResult.People, person);
+ itemResult.AddPerson(person);
}
break;
}