Merge pull request #2250 from MediaBrowser/beta

Beta
This commit is contained in:
Luke
2016-10-20 15:27:40 -04:00
committed by GitHub
67 changed files with 357 additions and 939 deletions

View File

@@ -45,6 +45,11 @@ namespace MediaBrowser.Server.Implementations.IO
private void AddAffectedPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentNullException("path");
}
if (!_affectedPaths.Contains(path, StringComparer.Ordinal))
{
_affectedPaths.Add(path);
@@ -53,6 +58,11 @@ namespace MediaBrowser.Server.Implementations.IO
public void AddPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentNullException("path");
}
lock (_timerLock)
{
AddAffectedPath(path);

View File

@@ -2838,9 +2838,13 @@ namespace MediaBrowser.Server.Implementations.Library
private bool ValidateNetworkPath(string path)
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT || !path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
return Directory.Exists(path);
// We can't validate protocol-based paths, so just allow them
if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1)
{
return Directory.Exists(path);
}
}
// Without native support for unc, we cannot validate this when running under mono

View File

@@ -360,7 +360,6 @@ 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

View File

@@ -207,14 +207,18 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
// Find movies with their own folders
if (args.IsDirectory)
{
var files = args.FileSystemChildren
.Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
.ToList();
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{
return null;
return FindMovie<MusicVideo>(args.Path, args.Parent, files, args.DirectoryService, collectionType, false);
}
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
{
return null;
return FindMovie<Video>(args.Path, args.Parent, files, args.DirectoryService, collectionType, false);
}
if (string.IsNullOrEmpty(collectionType))
@@ -222,6 +226,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
// Owned items will be caught by the plain video resolver
if (args.Parent == null)
{
//return FindMovie<Video>(args.Path, args.Parent, files, args.DirectoryService, collectionType);
return null;
}
@@ -231,21 +236,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
{
var files = args.FileSystemChildren
.Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
.ToList();
return FindMovie<Movie>(args.Path, args.Parent, files, args.DirectoryService, collectionType);
return FindMovie<Movie>(args.Path, args.Parent, files, args.DirectoryService, collectionType, true);
}
}
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
{
var files = args.FileSystemChildren
.Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
.ToList();
return FindMovie<Movie>(args.Path, args.Parent, files, args.DirectoryService, collectionType);
return FindMovie<Movie>(args.Path, args.Parent, files, args.DirectoryService, collectionType, true);
}
return null;
@@ -360,13 +357,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
/// Finds a movie based on a child file system entries
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">The path.</param>
/// <param name="parent">The parent.</param>
/// <param name="fileSystemEntries">The file system entries.</param>
/// <param name="directoryService">The directory service.</param>
/// <param name="collectionType">Type of the collection.</param>
/// <returns>Movie.</returns>
private T FindMovie<T>(string path, Folder parent, List<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, string collectionType)
private T FindMovie<T>(string path, Folder parent, List<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool allowFilesAsFolders)
where T : Video, new()
{
var multiDiscFolders = new List<FileSystemMetadata>();
@@ -413,23 +405,27 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
}
var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
!string.Equals(collectionType, CollectionType.Photos) &&
!string.Equals(collectionType, CollectionType.MusicVideos);
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion);
if (result.Items.Count == 1)
if (allowFilesAsFolders)
{
var movie = (T)result.Items[0];
movie.IsInMixedFolder = false;
movie.Name = Path.GetFileName(movie.ContainingFolderPath);
return movie;
}
// TODO: Allow GetMultiDiscMovie in here
var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
!string.Equals(collectionType, CollectionType.Photos) &&
!string.Equals(collectionType, CollectionType.MusicVideos);
if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
{
return GetMultiDiscMovie<T>(multiDiscFolders, directoryService);
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, supportsMultiVersion);
if (result.Items.Count == 1)
{
var movie = (T)result.Items[0];
movie.IsInMixedFolder = false;
movie.Name = Path.GetFileName(movie.ContainingFolderPath);
return movie;
}
if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
{
return GetMultiDiscMovie<T>(multiDiscFolders, directoryService);
}
}
return null;

View File

@@ -1021,7 +1021,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var stream = new MediaSourceInfo
{
Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
Id = recordingId,
SupportsDirectPlay = false,
SupportsDirectStream = true,
@@ -1854,23 +1854,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
ParentIndexNumber = program.SeasonNumber.Value,
IndexNumber = program.EpisodeNumber.Value,
AncestorIds = seriesIds,
ExcludeLocationTypes = new[] { LocationType.Virtual }
});
if (result.TotalRecordCount > 0)
{
return true;
}
}
if (!string.IsNullOrWhiteSpace(program.EpisodeTitle))
{
var result = _libraryManager.GetItemsResult(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Episode).Name },
Name = program.EpisodeTitle,
AncestorIds = seriesIds,
ExcludeLocationTypes = new[] { LocationType.Virtual }
IsVirtualItem = false
});
if (result.TotalRecordCount > 0)

View File

@@ -52,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var format = _liveTvOptions.RecordingEncodingFormat;
if (string.Equals(format, "mkv", StringComparison.OrdinalIgnoreCase))
if (string.Equals(format, "mkv", StringComparison.OrdinalIgnoreCase) || _liveTvOptions.EnableOriginalVideoWithEncodedRecordings)
{
return "mkv";
}
@@ -204,6 +204,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private bool EncodeVideo(MediaSourceInfo mediaSource)
{
if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings)
{
return false;
}
var mediaStreams = mediaSource.MediaStreams ?? new List<MediaStream>();
return !mediaStreams.Any(i => i.Type == MediaStreamType.Video && string.Equals(i.Codec, "h264", StringComparison.OrdinalIgnoreCase) && !i.IsInterlaced);
}

View File

@@ -72,7 +72,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
dto.ProgramInfo = _dtoService.GetBaseItemDto(program, new DtoOptions());
dto.ProgramInfo.TimerId = dto.Id;
if (info.Status != RecordingStatus.Cancelled && info.Status != RecordingStatus.Error)
{
dto.ProgramInfo.TimerId = dto.Id;
dto.ProgramInfo.Status = info.Status.ToString();
}
dto.ProgramInfo.SeriesTimerId = dto.SeriesTimerId;
}

View File

@@ -877,6 +877,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
SortOrder = query.SortOrder ?? SortOrder.Ascending,
EnableTotalRecordCount = query.EnableTotalRecordCount,
TopParentIds = new[] { topFolder.Id.ToString("N") },
Name = query.Name,
DtoOptions = options
};
@@ -1946,7 +1947,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
else
{
timers = timers.Where(i => !(i.Item1.Status == RecordingStatus.New));
timers = timers.Where(i => i.Item1.Status != RecordingStatus.New);
}
}
@@ -2304,7 +2305,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
info.RecordAnyChannel = true;
info.RecordAnyTime = true;
info.Days = new List<DayOfWeek>
{

View File

@@ -140,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
try
{
if (stream.MediaStreams.Any(i => i.Index != -1))
if (!stream.SupportsProbing || stream.MediaStreams.Any(i => i.Index != -1))
{
await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false);
}

View File

@@ -60,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
OpenedMediaSource.Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
OpenedMediaSource.Protocol = MediaProtocol.Http;
OpenedMediaSource.SupportsDirectPlay = false;
OpenedMediaSource.SupportsDirectStream = true;

View File

@@ -13,6 +13,7 @@ using System.Threading;
using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
@@ -24,12 +25,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_fileSystem = fileSystem;
_httpClient = httpClient;
_appHost = appHost;
}
public override string Type
@@ -46,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
{
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
}
public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
@@ -75,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
public async Task Validate(TunerHostInfo info)
{
using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
{
}

View File

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Logging;
@@ -18,12 +19,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient)
public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
{
_logger = logger;
_fileSystem = fileSystem;
_httpClient = httpClient;
_appHost = appHost;
}
public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
@@ -41,7 +44,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
return _httpClient.Get(url, cancellationToken);
return _httpClient.Get(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
// Some data providers will require a user agent
UserAgent = _appHost.FriendlyName + "/" + _appHost.ApplicationVersion
});
}
return Task.FromResult(_fileSystem.OpenRead(url));
}
@@ -111,15 +120,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
channel.Number = "0";
}
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-id", extInf, channel.Name);
channel.Name = FindProperty("tvg-name", extInf, channel.Name);
channel.ImageUrl = FindProperty("tvg-logo", extInf);
var name = FindProperty("tvg-name", extInf);
if (string.IsNullOrWhiteSpace(name))
{
name = FindProperty("tvg-id", extInf);
}
channel.Name = name;
var numberString = FindProperty("tvg-id", extInf);
if (string.IsNullOrWhiteSpace(numberString))
{
numberString = FindProperty("channel-id", extInf);
}
if (!string.IsNullOrWhiteSpace(numberString))
{
channel.Number = numberString;
}
return channel;
}
private string FindProperty(string property, string properties, string defaultResult = "")
private string FindProperty(string property, string properties)
{
var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
var matches = reg.Matches(properties);
@@ -130,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return match.Groups[2].Value;
}
}
return defaultResult;
return null;
}
}

View File

@@ -8,6 +8,7 @@ using CommonIO;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
@@ -25,12 +26,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_fileSystem = fileSystem;
_httpClient = httpClient;
_appHost = appHost;
}
private const string ChannelIdPrefix = "sat_";
@@ -39,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
if (!string.IsNullOrWhiteSpace(tuner.M3UUrl))
{
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
}
var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false);

View File

@@ -144,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.Photos
return ItemUpdateType.None;
}
await ProviderManager.SaveImage(item, outputPath, "image/png", imageType, null, Guid.NewGuid().ToString("N"), cancellationToken).ConfigureAwait(false);
await ProviderManager.SaveImage(item, outputPath, "image/png", imageType, null, false, cancellationToken).ConfigureAwait(false);
return ItemUpdateType.ImageUpdate;
}

View File

@@ -22,9 +22,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
private float GetValue(BaseItem x)
{
var hasCriticRating = x as IHasCriticRating;
return hasCriticRating == null ? 0 : hasCriticRating.CriticRating ?? 0;
return x.CriticRating ?? 0;
}
/// <summary>