commit
e3595b3454
|
@ -371,7 +371,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
var tuple = GetProvider(request.OpenToken);
|
var tuple = GetProvider(request.OpenToken);
|
||||||
var provider = tuple.Item1;
|
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;
|
var mediaSource = mediaSourceTuple.Item1;
|
||||||
|
|
||||||
|
|
|
@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime _lastRecordingRefreshTime;
|
private DateTime _lastRecordingRefreshTime;
|
||||||
private async Task RefreshRecordings(CancellationToken cancellationToken)
|
private async Task RefreshRecordings(Guid internalLiveTvFolderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
const int cacheMinutes = 2;
|
const int cacheMinutes = 2;
|
||||||
|
|
||||||
|
@ -1542,10 +1542,8 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
});
|
});
|
||||||
|
|
||||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
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);
|
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)
|
if (user == null)
|
||||||
{
|
{
|
||||||
|
@ -1571,21 +1569,31 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return new QueryResult<BaseItem>();
|
return new QueryResult<BaseItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var folders = EmbyTV.EmbyTV.Current.GetRecordingFolders()
|
var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders()
|
||||||
.SelectMany(i => i.Locations)
|
.SelectMany(i => i.Locations)
|
||||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
.Select(i => _libraryManager.FindByPath(i, true))
|
.Select(i => _libraryManager.FindByPath(i, true))
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.Where(i => i.IsVisibleStandalone(user))
|
.Where(i => i.IsVisibleStandalone(user))
|
||||||
|
.Select(i => i.Id)
|
||||||
.ToList();
|
.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>();
|
return new QueryResult<BaseItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var includeItemTypes = new List<string>();
|
var includeItemTypes = new List<string>();
|
||||||
var excludeItemTypes = new List<string>();
|
|
||||||
var genres = new List<string>();
|
var genres = new List<string>();
|
||||||
|
|
||||||
if (query.IsMovie.HasValue)
|
if (query.IsMovie.HasValue)
|
||||||
|
@ -1631,7 +1639,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
MediaTypes = new[] { MediaType.Video },
|
MediaTypes = new[] { MediaType.Video },
|
||||||
Recursive = true,
|
Recursive = true,
|
||||||
AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
|
AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(),
|
||||||
IsFolder = false,
|
IsFolder = false,
|
||||||
IsVirtualItem = false,
|
IsVirtualItem = false,
|
||||||
Limit = query.Limit,
|
Limit = query.Limit,
|
||||||
|
@ -1714,12 +1722,24 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
return new QueryResult<BaseItem>();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
await RefreshRecordings(cancellationToken).ConfigureAwait(false);
|
return GetEmbyRecordings(query, options, folder.Id, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
var internalQuery = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
|
@ -2620,7 +2640,8 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
}, new DtoOptions(), cancellationToken).ConfigureAwait(false);
|
}, 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>();
|
var groups = new List<BaseItemDto>();
|
||||||
|
|
||||||
|
|
|
@ -848,6 +848,11 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
// No known video stream
|
||||||
|
if (state.VideoStream == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
|
var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
SubtitleStreamIndex = request.SubtitleStreamIndex,
|
SubtitleStreamIndex = request.SubtitleStreamIndex,
|
||||||
UserId = request.UserId,
|
UserId = request.UserId,
|
||||||
OpenToken = mediaSource.OpenToken,
|
OpenToken = mediaSource.OpenToken,
|
||||||
AllowMediaProbe = request.AllowMediaProbe
|
EnableMediaProbe = request.EnableMediaProbe
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -635,8 +635,10 @@ namespace MediaBrowser.Model.Dlna
|
||||||
MediaStream videoStream = item.VideoStream;
|
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
|
// 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));
|
var directPlayEligibilityResult = 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 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}",
|
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
||||||
options.Profile.Name ?? "Unknown Profile",
|
options.Profile.Name ?? "Unknown Profile",
|
||||||
|
@ -669,6 +671,16 @@ namespace MediaBrowser.Model.Dlna
|
||||||
transcodeReasons.AddRange(directPlayInfo.Item2);
|
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
|
// Can't direct play, find the transcoding profile
|
||||||
TranscodingProfile transcodingProfile = null;
|
TranscodingProfile transcodingProfile = null;
|
||||||
foreach (TranscodingProfile i in options.Profile.TranscodingProfiles)
|
foreach (TranscodingProfile i in options.Profile.TranscodingProfiles)
|
||||||
|
@ -1136,7 +1148,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
mediaSource.Path ?? "Unknown path");
|
mediaSource.Path ?? "Unknown path");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsEligibleForDirectPlay(MediaSourceInfo item,
|
private Tuple<bool, TranscodeReason?> IsEligibleForDirectPlay(MediaSourceInfo item,
|
||||||
long? maxBitrate,
|
long? maxBitrate,
|
||||||
MediaStream subtitleStream,
|
MediaStream subtitleStream,
|
||||||
VideoOptions options,
|
VideoOptions options,
|
||||||
|
@ -1149,11 +1161,18 @@ namespace MediaBrowser.Model.Dlna
|
||||||
if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
|
if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
|
||||||
{
|
{
|
||||||
_logger.Info("Not eligible for {0} due to unsupported subtitles", playMethod);
|
_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)
|
public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer)
|
||||||
|
|
|
@ -17,13 +17,13 @@ namespace MediaBrowser.Model.MediaInfo
|
||||||
|
|
||||||
public bool EnableDirectPlay { get; set; }
|
public bool EnableDirectPlay { get; set; }
|
||||||
public bool EnableDirectStream { get; set; }
|
public bool EnableDirectStream { get; set; }
|
||||||
public bool AllowMediaProbe { get; set; }
|
public bool EnableMediaProbe { get; set; }
|
||||||
|
|
||||||
public LiveStreamRequest()
|
public LiveStreamRequest()
|
||||||
{
|
{
|
||||||
EnableDirectPlay = true;
|
EnableDirectPlay = true;
|
||||||
EnableDirectStream = true;
|
EnableDirectStream = true;
|
||||||
AllowMediaProbe = true;
|
EnableMediaProbe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveStreamRequest(AudioOptions options)
|
public LiveStreamRequest(AudioOptions options)
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace MediaBrowser.Model.MediaInfo
|
||||||
public bool AllowVideoStreamCopy { get; set; }
|
public bool AllowVideoStreamCopy { get; set; }
|
||||||
public bool AllowAudioStreamCopy { get; set; }
|
public bool AllowAudioStreamCopy { get; set; }
|
||||||
public bool AutoOpenLiveStream { get; set; }
|
public bool AutoOpenLiveStream { get; set; }
|
||||||
public bool AllowMediaProbe { get; set; }
|
public bool EnableMediaProbe { get; set; }
|
||||||
|
|
||||||
public PlaybackInfoRequest()
|
public PlaybackInfoRequest()
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace MediaBrowser.Model.MediaInfo
|
||||||
EnableTranscoding = true;
|
EnableTranscoding = true;
|
||||||
AllowVideoStreamCopy = true;
|
AllowVideoStreamCopy = true;
|
||||||
AllowAudioStreamCopy = true;
|
AllowAudioStreamCopy = true;
|
||||||
AllowMediaProbe = true;
|
EnableMediaProbe = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace MediaBrowser.Model.Session
|
||||||
VideoFramerateNotSupported = 17,
|
VideoFramerateNotSupported = 17,
|
||||||
VideoLevelNotSupported = 18,
|
VideoLevelNotSupported = 18,
|
||||||
VideoProfileNotSupported = 19,
|
VideoProfileNotSupported = 19,
|
||||||
AudioBitDepthNotSupported = 20
|
AudioBitDepthNotSupported = 20,
|
||||||
|
SubtitleCodecNotSupported = 21
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
|
if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
|
||||||
{
|
{
|
||||||
if (!item.IsLocked)
|
if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres))
|
||||||
{
|
{
|
||||||
var taggedItems = item.IsAccessedByName ?
|
var taggedItems = item.IsAccessedByName ?
|
||||||
item.GetTaggedItems(new Controller.Entities.InternalItemsQuery()
|
item.GetTaggedItems(new Controller.Entities.InternalItemsQuery()
|
||||||
|
@ -31,8 +31,6 @@ namespace MediaBrowser.Providers.Music
|
||||||
}) :
|
}) :
|
||||||
item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList();
|
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)
|
item.Genres = taggedItems.SelectMany(i => i.Genres)
|
||||||
|
@ -45,7 +43,6 @@ namespace MediaBrowser.Providers.Music
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return updateType;
|
return updateType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using System;
|
||||||
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
|
@ -6,7 +7,7 @@ using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Model.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)
|
public PlaylistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("3.2.22.2")]
|
[assembly: AssemblyVersion("3.2.22.3")]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user