aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2016-10-17 12:32:57 -0400
committerGitHub <noreply@github.com>2016-10-17 12:32:57 -0400
commitfb9db5c3c36eca578369cb398c36efd6a15bbea9 (patch)
tree98e41f78dd5d7c474ce763157eb3503a165088ed
parentf8a248ffd805b810e90bc5ec0619e53f49ebcae5 (diff)
parentb0147c32f9122c6ce695d2919176ed8b50b94fda (diff)
Merge pull request #2240 from MediaBrowser/beta
Beta
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs8
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs16
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs95
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs4
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs6
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs5
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs1
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs2
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs3
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs15
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs52
-rw-r--r--MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs1
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs4
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs9
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs4
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs7
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj6
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs22
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
30 files changed, 228 insertions, 85 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 0e91c0b9e..eb80ae89e 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1735,6 +1735,13 @@ namespace MediaBrowser.Api.Playback
{
request.Tag = val;
}
+ else if (i == 29)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.EnableSplittingOnNonKeyFrames = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ }
+ }
}
}
@@ -2354,6 +2361,7 @@ namespace MediaBrowser.Api.Playback
{
state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest;
+ state.VideoRequest.EnableSplittingOnNonKeyFrames = transcodingProfile.EnableSplittingOnNonKeyFrames;
}
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 51455c141..270b068fd 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -885,14 +885,17 @@ namespace MediaBrowser.Api.Playback.Hls
}
var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty;
+ var enableSplittingOnNonKeyFrames = state.VideoRequest.EnableSplittingOnNonKeyFrames && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase);
+ enableSplittingOnNonKeyFrames = false;
- var enableGenericSegmenter = false;
+ // TODO: check libavformat version for 57 50.100 and use -hls_flags split_by_time
+ var hlsProtocolSupportsSplittingByTime = false;
- if (enableGenericSegmenter)
+ if (enableSplittingOnNonKeyFrames && !hlsProtocolSupportsSplittingByTime)
{
var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state);
- return string.Format("{0} {10} {1} -map_metadata -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
+ return string.Format("{0} {10} {1} -map_metadata -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -break_non_keyframes 1 -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
inputModifier,
GetInputArgument(state),
threads,
@@ -907,8 +910,10 @@ namespace MediaBrowser.Api.Playback.Hls
).Trim();
}
- // TODO: check libavformat version for 57 50.100 and use -hls_flags split_by_time
- return string.Format("{0}{11} {1} -map_metadata -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"",
+ var splitByTime = hlsProtocolSupportsSplittingByTime && enableSplittingOnNonKeyFrames;
+ var splitByTimeArg = splitByTime ? " -hls_flags split_by_time" : "";
+
+ return string.Format("{0}{12} {1} -map_metadata -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7}{8} -start_number {9} -hls_list_size {10} -y \"{11}\"",
inputModifier,
GetInputArgument(state),
threads,
@@ -917,6 +922,7 @@ namespace MediaBrowser.Api.Playback.Hls
timestampOffsetParam,
GetAudioArguments(state),
state.SegmentLength.ToString(UsCulture),
+ splitByTimeArg,
startNumberParam,
state.HlsListSize.ToString(UsCulture),
outputPath,
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index 8cdf846ed..5b936f718 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -194,6 +194,7 @@ namespace MediaBrowser.Api.Playback
public bool CopyTimestamps { get; set; }
public bool EnableSubtitlesInManifest { get; set; }
+ public bool EnableSplittingOnNonKeyFrames { get; set; }
public VideoStreamRequest()
{
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 7eb84fc80..3ebefa217 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1188,7 +1188,7 @@ namespace MediaBrowser.Controller.Entities
var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
- var tasks = newItems.Select(i => i.RefreshMetadata(options, cancellationToken));
+ var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, true, options, cancellationToken));
await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -1197,7 +1197,7 @@ namespace MediaBrowser.Controller.Entities
return itemsChanged;
}
- private static async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList();
@@ -1215,7 +1215,7 @@ namespace MediaBrowser.Controller.Entities
subOptions.ForceSave = true;
}
- return i.RefreshMetadata(subOptions, cancellationToken);
+ return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
});
await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -1228,7 +1228,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Refreshes the theme songs.
/// </summary>
- private static async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList();
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
@@ -1245,7 +1245,7 @@ namespace MediaBrowser.Controller.Entities
subOptions.ForceSave = true;
}
- return i.RefreshMetadata(subOptions, cancellationToken);
+ return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
});
await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -2203,14 +2203,85 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true);
}
- protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, string path, CancellationToken cancellationToken)
+ protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
- var newOptions = new MetadataRefreshOptions(options.DirectoryService)
+ var newOptions = new MetadataRefreshOptions(options);
+ newOptions.SearchResult = null;
+
+ var item = this;
+
+ if (copyTitleMetadata)
{
- ImageRefreshMode = options.ImageRefreshMode,
- MetadataRefreshMode = options.MetadataRefreshMode,
- ReplaceAllMetadata = options.ReplaceAllMetadata
- };
+ // Take some data from the main item, for querying purposes
+ if (!item.Genres.SequenceEqual(ownedItem.Genres, StringComparer.Ordinal))
+ {
+ newOptions.ForceSave = true;
+ ownedItem.Genres = item.Genres.ToList();
+ }
+ if (!item.Studios.SequenceEqual(ownedItem.Studios, StringComparer.Ordinal))
+ {
+ newOptions.ForceSave = true;
+ ownedItem.Studios = item.Studios.ToList();
+ }
+ if (!item.ProductionLocations.SequenceEqual(ownedItem.ProductionLocations, StringComparer.Ordinal))
+ {
+ newOptions.ForceSave = true;
+ ownedItem.ProductionLocations = item.ProductionLocations.ToList();
+ }
+ if (!item.Keywords.SequenceEqual(ownedItem.Keywords, StringComparer.Ordinal))
+ {
+ newOptions.ForceSave = true;
+ ownedItem.Keywords = item.Keywords.ToList();
+ }
+ if (item.CommunityRating != ownedItem.CommunityRating)
+ {
+ ownedItem.CommunityRating = item.CommunityRating;
+ newOptions.ForceSave = true;
+ }
+ if (item.CriticRating != ownedItem.CriticRating)
+ {
+ ownedItem.CriticRating = item.CriticRating;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.Overview, ownedItem.Overview, StringComparison.Ordinal))
+ {
+ ownedItem.Overview = item.Overview;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.ShortOverview, ownedItem.ShortOverview, StringComparison.Ordinal))
+ {
+ ownedItem.ShortOverview = item.ShortOverview;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.OfficialRating, ownedItem.OfficialRating, StringComparison.Ordinal))
+ {
+ ownedItem.OfficialRating = item.OfficialRating;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.CustomRating, ownedItem.CustomRating, StringComparison.Ordinal))
+ {
+ ownedItem.CustomRating = item.CustomRating;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.CriticRatingSummary, ownedItem.CriticRatingSummary, StringComparison.Ordinal))
+ {
+ ownedItem.CriticRatingSummary = item.CriticRatingSummary;
+ newOptions.ForceSave = true;
+ }
+ if (!string.Equals(item.OfficialRatingDescription, ownedItem.OfficialRatingDescription, StringComparison.Ordinal))
+ {
+ ownedItem.OfficialRatingDescription = item.OfficialRatingDescription;
+ newOptions.ForceSave = true;
+ }
+ }
+
+ return ownedItem.RefreshMetadata(newOptions, cancellationToken);
+ }
+
+ protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
+ {
+ var newOptions = new MetadataRefreshOptions(options);
+ newOptions.SearchResult = null;
var id = LibraryManager.GetNewItemId(path, typeof(Video));
@@ -2229,7 +2300,7 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true);
}
- return video.RefreshMetadata(newOptions, cancellationToken);
+ return RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken);
}
public string GetEtag(User user)
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index fec703b94..3fb118a9c 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -182,7 +182,7 @@ namespace MediaBrowser.Controller.Entities
case ItemFields.HomePageUrl:
case ItemFields.VoteCount:
case ItemFields.DisplayMediaType:
- case ItemFields.ServiceName:
+ //case ItemFields.ServiceName:
case ItemFields.Genres:
case ItemFields.Studios:
case ItemFields.Settings:
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 22cc0316a..dea42c463 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -103,7 +103,7 @@ namespace MediaBrowser.Controller.Entities.Movies
var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
- var tasks = newItems.Select(i => i.RefreshMetadata(options, cancellationToken));
+ var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, false, options, cancellationToken));
await Task.WhenAll(tasks).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 5aaff6fef..e87b726b2 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -427,7 +427,7 @@ namespace MediaBrowser.Controller.Entities
if (IsStacked)
{
var tasks = AdditionalParts
- .Select(i => RefreshMetadataForOwnedVideo(options, i, cancellationToken));
+ .Select(i => RefreshMetadataForOwnedVideo(options, true, i, cancellationToken));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
@@ -442,7 +442,7 @@ namespace MediaBrowser.Controller.Entities
RefreshLinkedAlternateVersions();
var tasks = LocalAlternateVersions
- .Select(i => RefreshMetadataForOwnedVideo(options, i, cancellationToken));
+ .Select(i => RefreshMetadataForOwnedVideo(options, false, i, cancellationToken));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
index e6fefbf72..de5ffcd58 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
@@ -113,7 +113,11 @@ namespace MediaBrowser.Controller.LiveTv
public override bool CanDelete()
{
- return Status == RecordingStatus.Completed;
+ if (string.Equals(ServiceName, "Emby", StringComparison.OrdinalIgnoreCase))
+ {
+ return Status == RecordingStatus.Completed;
+ }
+ return true;
}
public override bool IsAuthorizedToDelete(User user)
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
index c255630f5..2c0ced0e6 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
@@ -130,7 +130,11 @@ namespace MediaBrowser.Controller.LiveTv
public override bool CanDelete()
{
- return Status == RecordingStatus.Completed;
+ if (string.Equals(ServiceName, "Emby", StringComparison.OrdinalIgnoreCase))
+ {
+ return Status == RecordingStatus.Completed;
+ }
+ return true;
}
public override bool IsAuthorizedToDelete(User user)
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 24de4e77e..7acff8fc8 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -154,6 +154,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
};
+ _logger.Info("Running {0} {1}", path, arguments);
+
using (process)
{
process.Start();
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index fc1444e1b..340990373 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -610,6 +610,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (video.Protocol != MediaProtocol.File)
{
+ // If it's mpeg based, assume true
+ if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return true;
+ }
return false;
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 4b225d576..0c93df52b 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -478,6 +478,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
playlistItem.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest;
+ playlistItem.EnableSplittingOnNonKeyFrames = transcodingProfile.EnableSplittingOnNonKeyFrames;
if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels))
{
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index c9cb873e1..b8db8a10c 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -37,6 +37,7 @@ namespace MediaBrowser.Model.Dlna
public bool CopyTimestamps { get; set; }
public bool EnableSubtitlesInManifest { get; set; }
+ public bool EnableSplittingOnNonKeyFrames { get; set; }
public string[] AudioCodecs { get; set; }
public int? AudioStreamIndex { get; set; }
@@ -264,6 +265,7 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("EnableSubtitlesInManifest", item.EnableSubtitlesInManifest.ToString().ToLower()));
list.Add(new NameValuePair("Tag", item.MediaSource.ETag ?? string.Empty));
+ list.Add(new NameValuePair("EnableSplittingOnNonKeyFrames", item.EnableSplittingOnNonKeyFrames.ToString().ToLower()));
return list;
}
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index beb83b053..eeab99678 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -38,6 +38,9 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("enableSubtitlesInManifest")]
public bool EnableSubtitlesInManifest { get; set; }
+ [XmlAttribute("enableSplittingOnNonKeyFrames")]
+ public bool EnableSplittingOnNonKeyFrames { get; set; }
+
[XmlAttribute("maxAudioChannels")]
public string MaxAudioChannels { get; set; }
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 990de332e..6d3e2ce4c 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Extensions;
using System.Diagnostics;
@@ -47,7 +48,7 @@ namespace MediaBrowser.Model.Entities
{
if (!string.IsNullOrEmpty(Title))
{
- return Title;
+ return AddLanguageIfNeeded(Title);
}
if (Type == MediaStreamType.Audio)
@@ -115,6 +116,16 @@ namespace MediaBrowser.Model.Entities
}
}
+ private string AddLanguageIfNeeded(string title)
+ {
+ if (!string.IsNullOrEmpty(Language) && title.IndexOf(Language, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ title = StringHelper.FirstToUpper(Language) + " " + title;
+ }
+
+ return title;
+ }
+
public string NalLengthSize { get; set; }
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 1021d8823..3274231ee 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -122,43 +122,55 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn;
- if (info.Location != null && !_usnsHandled.Contains(identifier))
+ if (info.Location == null)
{
+ return;
+ }
+
+ lock (_usnsHandled)
+ {
+ if (_usnsHandled.Contains(identifier))
+ {
+ return;
+ }
_usnsHandled.Add(identifier);
+ }
- _logger.Debug("Calling Nat.Handle on " + identifier);
+ _logger.Debug("Calling Nat.Handle on " + identifier);
- IPAddress address;
- if (IPAddress.TryParse(info.Location.Host, out address))
- {
- // The Handle method doesn't need the port
- var endpoint = new IPEndPoint(address, info.Location.Port);
+ IPAddress address;
+ if (IPAddress.TryParse(info.Location.Host, out address))
+ {
+ // The Handle method doesn't need the port
+ var endpoint = new IPEndPoint(address, info.Location.Port);
- IPAddress localAddress = null;
+ IPAddress localAddress = null;
- try
- {
- var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ try
+ {
+ var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
- if (!IPAddress.TryParse(localAddressString, out localAddress))
- {
- return;
- }
- }
- catch
+ if (!IPAddress.TryParse(localAddressString, out localAddress))
{
return;
}
-
- NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp);
}
+ catch
+ {
+ return;
+ }
+
+ NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp);
}
}
private void ClearCreatedRules(object state)
{
_createdRules = new List<string>();
- _usnsHandled = new List<string>();
+ lock (_usnsHandled)
+ {
+ _usnsHandled.Clear();
+ }
}
void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
index 9b23d5be4..a1638f722 100644
--- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
+++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
@@ -66,10 +66,12 @@ namespace MediaBrowser.Server.Implementations.Intros
var candidates = new List<ItemWithTrailer>();
var trailerTypes = new List<TrailerType>();
+ var sourceTypes = new List<SourceType>();
if (config.EnableIntrosFromMoviesInLibrary)
{
trailerTypes.Add(TrailerType.LocalTrailer);
+ sourceTypes.Add(SourceType.Library);
}
if (IsSupporter)
@@ -77,18 +79,22 @@ namespace MediaBrowser.Server.Implementations.Intros
if (config.EnableIntrosFromUpcomingTrailers)
{
trailerTypes.Add(TrailerType.ComingSoonToTheaters);
+ sourceTypes.Clear();
}
if (config.EnableIntrosFromUpcomingDvdMovies)
{
trailerTypes.Add(TrailerType.ComingSoonToDvd);
+ sourceTypes.Clear();
}
if (config.EnableIntrosFromUpcomingStreamingMovies)
{
trailerTypes.Add(TrailerType.ComingSoonToStreaming);
+ sourceTypes.Clear();
}
if (config.EnableIntrosFromSimilarMovies)
{
trailerTypes.Add(TrailerType.Archive);
+ sourceTypes.Clear();
}
}
@@ -102,7 +108,8 @@ namespace MediaBrowser.Server.Implementations.Intros
IsPlayed = config.EnableIntrosForWatchedContent ? (bool?)null : false,
MaxParentalRating = config.EnableIntrosParentalControl ? ratingLevel : null,
BlockUnratedItems = config.EnableIntrosParentalControl ? new[] { UnratedItem.Trailer } : new UnratedItem[] { },
- Limit = config.TrailerLimit
+ Limit = config.TrailerLimit,
+ SourceTypes = sourceTypes.ToArray()
});
candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index e7bfe56f2..716d627a9 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -360,6 +360,7 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, bool enableAutoClose, CancellationToken cancellationToken)
{
+ enableAutoClose = false;
await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 1e480e265..3217cd67b 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -85,6 +85,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
{
+ if (args.Parent.IsRoot)
+ {
+ // For now, return null, but if we want to allow this in the future then add some additional checks to guard against a misplaced tvshow.nfo
+ return null;
+ }
+
return new Series
{
Path = args.Path,
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 86d77982c..9b69b84d3 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -741,7 +741,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
PostPaddingSeconds = Math.Max(config.PostPaddingSeconds, 0),
PrePaddingSeconds = Math.Max(config.PrePaddingSeconds, 0),
- RecordAnyChannel = true,
+ RecordAnyChannel = false,
RecordAnyTime = true,
RecordNewOnly = true,
@@ -764,7 +764,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
defaults.RecordNewOnly = !program.IsRepeat;
}
- defaults.SkipEpisodesInLibrary = true;
+ defaults.SkipEpisodesInLibrary = defaults.RecordNewOnly;
defaults.KeepUntil = KeepUntil.UntilDeleted;
return Task.FromResult(defaults);
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index bac9789b5..aa404b37c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1752,7 +1752,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, List<ItemFields> fields, User user = null)
{
- var recordingTuples = new List<Tuple<BaseItemDto, string, string, string>>();
+ var programTuples = new List<Tuple<BaseItemDto, string, string, string>>();
foreach (var tuple in tuples)
{
@@ -1812,18 +1812,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
}
- var service = GetService(program);
- var serviceName = service == null ? null : service.Name;
+ var serviceName = program.ServiceName;
if (fields.Contains(ItemFields.ServiceName))
{
dto.ServiceName = serviceName;
}
- recordingTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, program.ExternalId, program.ExternalSeriesIdLegacy));
+ programTuples.Add(new Tuple<BaseItemDto, string, string, string>(dto, serviceName, program.ExternalId, program.ExternalSeriesIdLegacy));
}
- await AddRecordingInfo(recordingTuples, CancellationToken.None).ConfigureAwait(false);
+ await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
}
public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index b03feefe4..cedaf7ad8 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -114,6 +114,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
protocol = MediaProtocol.Rtsp;
}
+ else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Udp;
+ }
var mediaSource = new MediaSourceInfo
{
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
index c07c448db..38eb9bdd1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -114,8 +114,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
channel.ImageUrl = FindProperty("tvg-logo", extInf, null);
channel.Number = FindProperty("channel-id", extInf, channel.Number);
channel.Number = FindProperty("tvg-id", extInf, channel.Number);
- channel.Name = FindProperty("tvg-name", extInf, channel.Name);
channel.Name = FindProperty("tvg-id", extInf, channel.Name);
+ channel.Name = FindProperty("tvg-name", extInf, channel.Name);
return channel;
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index 2235bfe0d..f33b18389 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -1188,7 +1188,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
public ItemImageInfo ItemImageInfoFromValueString(string value)
{
- var parts = value.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
+ var parts = value.Split(new[] { '*' }, StringSplitOptions.None);
var image = new ItemImageInfo();
@@ -1633,14 +1633,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
index++;
- if (query.HasField(ItemFields.ServiceName))
+ // TODO: Even if not needed by apps, the server needs it internally
+ // But get this excluded from contexts where it is not needed
+ if (!reader.IsDBNull(index))
{
- if (!reader.IsDBNull(index))
- {
- item.ServiceName = reader.GetString(index);
- }
- index++;
+ item.ServiceName = reader.GetString(index);
}
+ index++;
if (!reader.IsDBNull(index))
{
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index e898a6abd..9326c4f43 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -633,9 +633,12 @@ namespace MediaBrowser.Server.Implementations.Session
data.PlayCount++;
data.LastPlayedDate = DateTime.UtcNow;
- if (!(item is Video) && item.SupportsPlayedStatus)
+ if (item.SupportsPlayedStatus)
{
- data.Played = true;
+ if (!(item is Video))
+ {
+ data.Played = true;
+ }
}
else
{
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index b57416fab..36dd12651 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -164,6 +164,9 @@
<Content Include="dashboard-ui\components\guestinviter\guestinviter.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\components\iap.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\components\libraryoptionseditor\libraryoptionseditor.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -515,9 +518,6 @@
<Content Include="dashboard-ui\scripts\photos.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\registrationservices.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\scripts\reports.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 0b071fceb..ab71f321c 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -449,10 +449,9 @@ namespace MediaBrowser.XbmcMetadata.Savers
writer.WriteElementString("plot", overview);
}
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null)
+ if (item is Video)
{
- var outline = (hasShortOverview.ShortOverview ?? string.Empty)
+ var outline = (item.ShortOverview ?? string.Empty)
.StripHtml()
.Replace("&quot;", "'");
@@ -658,19 +657,14 @@ namespace MediaBrowser.XbmcMetadata.Savers
}
}
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null)
+ if (item.CriticRating.HasValue)
{
- if (hasCriticRating.CriticRating.HasValue)
- {
- writer.WriteElementString("criticrating", hasCriticRating.CriticRating.Value.ToString(UsCulture));
- }
+ writer.WriteElementString("criticrating", item.CriticRating.Value.ToString(UsCulture));
+ }
- if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary))
- {
- writer.WriteElementString("criticratingsummary", hasCriticRating.CriticRatingSummary);
- }
+ if (!string.IsNullOrEmpty(item.CriticRatingSummary))
+ {
+ writer.WriteElementString("criticratingsummary", item.CriticRatingSummary);
}
var hasDisplayOrder = item as IHasDisplayOrder;
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 1259a759b..31d946691 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.662</version>
+ <version>3.0.663</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.662" />
+ <dependency id="MediaBrowser.Common" version="3.0.663" />
<dependency id="NLog" version="4.3.8" />
<dependency id="SimpleInjector" version="3.2.2" />
</dependencies>
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 931db69fa..86524c2b6 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.662</version>
+ <version>3.0.663</version>
<title>MediaBrowser.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index b3d929f59..860a19436 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.662</version>
+ <version>3.0.663</version>
<title>Media Browser.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.662" />
+ <dependency id="MediaBrowser.Common" version="3.0.663" />
<dependency id="Interfaces.IO" version="1.0.0.5" />
</dependencies>
</metadata>