aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2017-07-03 13:16:01 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2017-07-03 13:16:01 -0400
commit6ea8e7868df95cea54216a5dbf927b3b4069bde5 (patch)
treec9e920a547ea696b7dce06cf21cf3398a653bde4
parentc4a271534e603224ece366dcfa976012d5750fbe (diff)
add live stream params
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs47
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs5
-rw-r--r--MediaBrowser.Api/Playback/MediaInfoService.cs2
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs29
-rw-r--r--MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs4
-rw-r--r--MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs4
-rw-r--r--MediaBrowser.Model/Session/TranscodingInfo.cs3
-rw-r--r--MediaBrowser.Providers/Music/ArtistMetadataService.cs21
-rw-r--r--MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs32
10 files changed, 110 insertions, 39 deletions
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index e4bc2962b..c1360c887 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -371,7 +371,7 @@ namespace Emby.Server.Implementations.Library
var tuple = GetProvider(request.OpenToken);
var provider = tuple.Item1;
- var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, request.AllowMediaProbe, cancellationToken).ConfigureAwait(false);
+ var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, request.EnableMediaProbe, cancellationToken).ConfigureAwait(false);
var mediaSource = mediaSourceTuple.Item1;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 24afc03da..bf11b7d3a 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.LiveTv
}
private DateTime _lastRecordingRefreshTime;
- private async Task RefreshRecordings(CancellationToken cancellationToken)
+ private async Task RefreshRecordings(Guid internalLiveTvFolderId, CancellationToken cancellationToken)
{
const int cacheMinutes = 2;
@@ -1542,10 +1542,8 @@ namespace Emby.Server.Implementations.LiveTv
});
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
- var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
- var parentFolderId = folder.Id;
- var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, parentFolderId, cancellationToken));
+ var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, internalLiveTvFolderId, cancellationToken));
var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
@@ -1559,7 +1557,7 @@ namespace Emby.Server.Implementations.LiveTv
}
}
- private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user)
+ private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, Guid internalLiveTvFolderId, User user)
{
if (user == null)
{
@@ -1571,21 +1569,31 @@ namespace Emby.Server.Implementations.LiveTv
return new QueryResult<BaseItem>();
}
- var folders = EmbyTV.EmbyTV.Current.GetRecordingFolders()
+ var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders()
.SelectMany(i => i.Locations)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(i => _libraryManager.FindByPath(i, true))
.Where(i => i != null)
.Where(i => i.IsVisibleStandalone(user))
+ .Select(i => i.Id)
.ToList();
- if (folders.Count == 0)
+ var excludeItemTypes = new List<string>();
+
+ if (!query.IsInProgress.HasValue)
+ {
+ folderIds.Add(internalLiveTvFolderId);
+
+ excludeItemTypes.Add(typeof(LiveTvChannel).Name);
+ excludeItemTypes.Add(typeof(LiveTvProgram).Name);
+ }
+
+ if (folderIds.Count == 0)
{
return new QueryResult<BaseItem>();
}
var includeItemTypes = new List<string>();
- var excludeItemTypes = new List<string>();
var genres = new List<string>();
if (query.IsMovie.HasValue)
@@ -1631,7 +1639,7 @@ namespace Emby.Server.Implementations.LiveTv
{
MediaTypes = new[] { MediaType.Video },
Recursive = true,
- AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
+ AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(),
IsFolder = false,
IsVirtualItem = false,
Limit = query.Limit,
@@ -1714,12 +1722,24 @@ namespace Emby.Server.Implementations.LiveTv
return new QueryResult<BaseItem>();
}
- if (_services.Count == 1 && !(query.IsInProgress ?? false) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value))
+ var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
+
+ if (_services.Count == 1 && (!query.IsInProgress.HasValue || !query.IsInProgress.Value) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value))
{
- return GetEmbyRecordings(query, options, user);
+ if (!query.IsInProgress.HasValue)
+ {
+ await RefreshRecordings(folder.Id, cancellationToken).ConfigureAwait(false);
+ }
+
+ return GetEmbyRecordings(query, options, folder.Id, user);
}
- await RefreshRecordings(cancellationToken).ConfigureAwait(false);
+ return await GetInternalRecordingsFromServices(query, user, options, folder.Id, cancellationToken).ConfigureAwait(false);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetInternalRecordingsFromServices(RecordingQuery query, User user, DtoOptions options, Guid internalLiveTvFolderId, CancellationToken cancellationToken)
+ {
+ await RefreshRecordings(internalLiveTvFolderId, cancellationToken).ConfigureAwait(false);
var internalQuery = new InternalItemsQuery(user)
{
@@ -2620,7 +2640,8 @@ namespace Emby.Server.Implementations.LiveTv
}, new DtoOptions(), cancellationToken).ConfigureAwait(false);
- var recordings = recordingResult.Items.OfType<ILiveTvRecording>().ToList();
+ var embyServiceName = EmbyTV.EmbyTV.Current.Name;
+ var recordings = recordingResult.Items.Where(i => !string.Equals(i.ServiceName, embyServiceName, StringComparison.OrdinalIgnoreCase)).OfType<ILiveTvRecording>().ToList();
var groups = new List<BaseItemDto>();
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index c6282bbad..664735dfe 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -848,6 +848,11 @@ namespace MediaBrowser.Api.Playback.Hls
{
return string.Empty;
}
+ // No known video stream
+ if (state.VideoStream == null)
+ {
+ return string.Empty;
+ }
var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index ae7271844..536236f5f 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -199,7 +199,7 @@ namespace MediaBrowser.Api.Playback
SubtitleStreamIndex = request.SubtitleStreamIndex,
UserId = request.UserId,
OpenToken = mediaSource.OpenToken,
- AllowMediaProbe = request.AllowMediaProbe
+ EnableMediaProbe = request.EnableMediaProbe
}).ConfigureAwait(false);
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index de6cbf4bb..3536b17b2 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -635,8 +635,10 @@ namespace MediaBrowser.Model.Dlna
MediaStream videoStream = item.VideoStream;
// TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
- bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay));
- bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream));
+ var directPlayEligibilityResult = IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay);
+ var directStreamEligibilityResult = IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream);
+ bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || directPlayEligibilityResult.Item1);
+ bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || directStreamEligibilityResult.Item1);
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
options.Profile.Name ?? "Unknown Profile",
@@ -669,6 +671,16 @@ namespace MediaBrowser.Model.Dlna
transcodeReasons.AddRange(directPlayInfo.Item2);
}
+ if (directPlayEligibilityResult.Item2.HasValue)
+ {
+ transcodeReasons.Add(directPlayEligibilityResult.Item2.Value);
+ }
+
+ if (directStreamEligibilityResult.Item2.HasValue)
+ {
+ transcodeReasons.Add(directStreamEligibilityResult.Item2.Value);
+ }
+
// Can't direct play, find the transcoding profile
TranscodingProfile transcodingProfile = null;
foreach (TranscodingProfile i in options.Profile.TranscodingProfiles)
@@ -1136,7 +1148,7 @@ namespace MediaBrowser.Model.Dlna
mediaSource.Path ?? "Unknown path");
}
- private bool IsEligibleForDirectPlay(MediaSourceInfo item,
+ private Tuple<bool, TranscodeReason?> IsEligibleForDirectPlay(MediaSourceInfo item,
long? maxBitrate,
MediaStream subtitleStream,
VideoOptions options,
@@ -1149,11 +1161,18 @@ namespace MediaBrowser.Model.Dlna
if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
{
_logger.Info("Not eligible for {0} due to unsupported subtitles", playMethod);
- return false;
+ return new Tuple<bool, TranscodeReason?>(false, TranscodeReason.SubtitleCodecNotSupported);
}
}
- return IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod);
+ var result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod);
+
+ if (result)
+ {
+ return new Tuple<bool, TranscodeReason?>(result, null);
+ }
+
+ return new Tuple<bool, TranscodeReason?>(result, TranscodeReason.ContainerBitrateExceedsLimit);
}
public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer)
diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
index 303340030..dedbb428d 100644
--- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
+++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
@@ -17,13 +17,13 @@ namespace MediaBrowser.Model.MediaInfo
public bool EnableDirectPlay { get; set; }
public bool EnableDirectStream { get; set; }
- public bool AllowMediaProbe { get; set; }
+ public bool EnableMediaProbe { get; set; }
public LiveStreamRequest()
{
EnableDirectPlay = true;
EnableDirectStream = true;
- AllowMediaProbe = true;
+ EnableMediaProbe = true;
}
public LiveStreamRequest(AudioOptions options)
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
index afffe9b14..df39f0556 100644
--- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
@@ -30,7 +30,7 @@ namespace MediaBrowser.Model.MediaInfo
public bool AllowVideoStreamCopy { get; set; }
public bool AllowAudioStreamCopy { get; set; }
public bool AutoOpenLiveStream { get; set; }
- public bool AllowMediaProbe { get; set; }
+ public bool EnableMediaProbe { get; set; }
public PlaybackInfoRequest()
{
@@ -39,7 +39,7 @@ namespace MediaBrowser.Model.MediaInfo
EnableTranscoding = true;
AllowVideoStreamCopy = true;
AllowAudioStreamCopy = true;
- AllowMediaProbe = true;
+ EnableMediaProbe = true;
}
}
}
diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs
index f1cbacd90..f58e605b2 100644
--- a/MediaBrowser.Model/Session/TranscodingInfo.cs
+++ b/MediaBrowser.Model/Session/TranscodingInfo.cs
@@ -48,6 +48,7 @@ namespace MediaBrowser.Model.Session
VideoFramerateNotSupported = 17,
VideoLevelNotSupported = 18,
VideoProfileNotSupported = 19,
- AudioBitDepthNotSupported = 20
+ AudioBitDepthNotSupported = 20,
+ SubtitleCodecNotSupported = 21
}
} \ No newline at end of file
diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs
index d4e580871..98fe766e0 100644
--- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs
+++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs
@@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Music
if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
{
- if (!item.IsLocked)
+ if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres))
{
var taggedItems = item.IsAccessedByName ?
item.GetTaggedItems(new Controller.Entities.InternalItemsQuery()
@@ -31,22 +31,19 @@ namespace MediaBrowser.Providers.Music
}) :
item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList();
- if (!item.LockedFields.Contains(MetadataFields.Genres))
- {
- var currentList = item.Genres.ToList();
+ var currentList = item.Genres.ToList();
- item.Genres = taggedItems.SelectMany(i => i.Genres)
- .DistinctNames()
- .ToList();
+ item.Genres = taggedItems.SelectMany(i => i.Genres)
+ .DistinctNames()
+ .ToList();
- if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase))
- {
- updateType = updateType | ItemUpdateType.MetadataEdit;
- }
+ if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase))
+ {
+ updateType = updateType | ItemUpdateType.MetadataEdit;
}
}
}
-
+
return updateType;
}
diff --git a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
index 235fd8c8a..c4ea106fb 100644
--- a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
+++ b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Configuration;
+using System;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Providers;
@@ -6,7 +7,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System.Collections.Generic;
-
+using System.Linq;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
@@ -33,6 +34,33 @@ namespace MediaBrowser.Providers.Playlists
}
}
+ protected override ItemUpdateType BeforeSave(Playlist item, bool isFullRefresh, ItemUpdateType currentUpdateType)
+ {
+ var updateType = base.BeforeSave(item, isFullRefresh, currentUpdateType);
+
+ if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
+ {
+ if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres))
+ {
+ var items = item.GetLinkedChildren()
+ .ToList();
+
+ var currentList = item.Genres.ToList();
+
+ item.Genres = items.SelectMany(i => i.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase))
+ {
+ updateType = updateType | ItemUpdateType.MetadataEdit;
+ }
+ }
+ }
+
+ return updateType;
+ }
+
public PlaylistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
{
}