aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/LiveTv
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-12-05 13:37:55 -0500
committerGitHub <noreply@github.com>2017-12-05 13:37:55 -0500
commitc32d8656382a0eacb301692e0084377fc433ae9b (patch)
tree121dd382bf71a9b5c96e00771c0ba18a7d28ab87 /Emby.Server.Implementations/LiveTv
parente7ffdf3fbdae7d4ec76a0a4e0e37792b079c56e5 (diff)
parentb3fbdde04305a0406b5322ec6947f8a30ddc12af (diff)
Merge pull request #3055 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Server.Implementations/LiveTv')
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs35
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs70
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs8
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs8
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs21
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs25
7 files changed, 137 insertions, 32 deletions
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 9992c71ecf..35d2d3c0ab 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1512,6 +1512,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
+ DeleteFileIfEmpty(recordPath);
+
TriggerRefresh(recordPath);
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);
@@ -1542,6 +1544,23 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
+ private void DeleteFileIfEmpty(string path)
+ {
+ var file = _fileSystem.GetFileInfo(path);
+
+ if (file.Exists && file.Length == 0)
+ {
+ try
+ {
+ _fileSystem.DeleteFile(path);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error deleting 0-byte failed recording file {0}", ex, path);
+ }
+ }
+ }
+
private void TriggerRefresh(string path)
{
_logger.Info("Triggering refresh on {0}", path);
@@ -1897,7 +1916,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
imageSaveFilenameWithoutExtension = "logo";
break;
case ImageType.Thumb:
- imageSaveFilenameWithoutExtension = "landscape";
+ if (program.IsSeries)
+ {
+ imageSaveFilenameWithoutExtension = Path.GetFileNameWithoutExtension(recordingPath) + "-thumb";
+ }
+ else
+ {
+ imageSaveFilenameWithoutExtension = "landscape";
+ }
+
break;
case ImageType.Backdrop:
imageSaveFilenameWithoutExtension = "fanart";
@@ -1921,9 +1948,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private async Task SaveRecordingImages(string recordingPath, LiveTvProgram program)
{
- var image = program.GetImageInfo(ImageType.Primary, 0);
+ var image = program.IsSeries ?
+ (program.GetImageInfo(ImageType.Thumb, 0) ?? program.GetImageInfo(ImageType.Primary, 0)) :
+ (program.GetImageInfo(ImageType.Primary, 0) ?? program.GetImageInfo(ImageType.Thumb, 0));
- if (image != null && program.IsMovie)
+ if (image != null)
{
try
{
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index 95ec1dee0d..7c251e3039 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -105,31 +105,64 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase))
{
- using (var stream = _fileSystem.OpenRead(file))
+ try
{
- var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
- _fileSystem.CreateDirectory(tempFolder);
-
- try
- {
- _zipClient.ExtractAllFromGz(stream, tempFolder, true);
- }
- catch
- {
- // If the extraction fails just return the original file, it could be a gz
- return file;
- }
+ var tempFolder = ExtractGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from gz file {0}", ex, file);
+ }
- return _fileSystem.GetFiles(tempFolder, true)
- .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
- .Select(i => i.FullName)
- .FirstOrDefault();
+ try
+ {
+ var tempFolder = ExtractFirstFileFromGz(file);
+ return FindXmlFile(tempFolder);
+ }
+ catch (Exception ex)
+ {
+ //_logger.ErrorException("Error extracting from zip file {0}", ex, file);
}
}
return file;
}
+ private string ExtractFirstFileFromGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractFirstFileFromGz(stream, tempFolder, "data.xml");
+
+ return tempFolder;
+ }
+ }
+
+ private string ExtractGz(string file)
+ {
+ using (var stream = _fileSystem.OpenRead(file))
+ {
+ var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
+ _fileSystem.CreateDirectory(tempFolder);
+
+ _zipClient.ExtractAllFromGz(stream, tempFolder, true);
+
+ return tempFolder;
+ }
+ }
+
+ private string FindXmlFile(string directory)
+ {
+ return _fileSystem.GetFiles(directory, true)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.FullName)
+ .FirstOrDefault();
+ }
+
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(channelId))
@@ -149,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
_logger.Debug("Getting xmltv programs for channel {0}", channelId);
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
@@ -251,6 +285,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
@@ -262,6 +297,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
+ _logger.Debug("Opening XmlTvReader for {0}", path);
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 7e72d1b1a1..211e0de4be 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -125,7 +125,7 @@ namespace Emby.Server.Implementations.LiveTv
public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders)
{
_services = services.ToArray();
- _tunerHosts.AddRange(tunerHosts);
+ _tunerHosts.AddRange(tunerHosts.Where(i => i.IsSupported));
_listingProviders.AddRange(listingProviders);
foreach (var service in _services)
@@ -947,6 +947,7 @@ namespace Emby.Server.Implementations.LiveTv
IsKids = query.IsKids,
IsNews = query.IsNews,
Genres = query.Genres,
+ GenreIds = query.GenreIds,
StartIndex = query.StartIndex,
Limit = query.Limit,
OrderBy = query.OrderBy,
@@ -1020,7 +1021,8 @@ namespace Emby.Server.Implementations.LiveTv
EnableTotalRecordCount = query.EnableTotalRecordCount,
OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { topFolder.Id.ToString("N") },
- DtoOptions = options
+ DtoOptions = options,
+ GenreIds = query.GenreIds
};
if (query.Limit.HasValue)
@@ -1421,7 +1423,7 @@ namespace Emby.Server.Implementations.LiveTv
if (newPrograms.Count > 0)
{
- _libraryManager.CreateItems(newPrograms, cancellationToken);
+ _libraryManager.CreateItems(newPrograms, null, cancellationToken);
}
// TODO: Do this in bulk
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index ed8b3074b0..29b7c41ef2 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv
}
var list = sources.ToList();
- var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
foreach (var source in list)
{
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index e0fd32aeef..45e96c36d8 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
@@ -39,6 +39,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
FileSystem = fileSystem;
}
+ public virtual bool IsSupported
+ {
+ get
+ {
+ return true;
+ }
+ }
+
protected abstract Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken);
public abstract string Type { get; }
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index c96d1f3592..04c5303f11 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -17,6 +17,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
+using System.IO;
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
@@ -75,6 +76,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list);
}
+ private string[] _disallowedSharedStreamExtensions = new string[]
+ {
+ ".mkv",
+ ".mp4",
+ ".m3u8",
+ ".mpd"
+ };
+
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
{
var tunerCount = info.TunerCount;
@@ -95,7 +104,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
{
- return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+ var extension = Path.GetExtension(mediaSource.Path) ?? string.Empty;
+
+ if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+ {
+ return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+ }
}
return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths);
@@ -152,6 +166,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
isRemote = !_networkManager.IsInLocalNetwork(uri.Host);
}
+ var supportsDirectPlay = !info.EnableStreamLooping && info.TunerCount == 0;
+
var mediaSource = new MediaSourceInfo
{
Path = path,
@@ -183,7 +199,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
IsInfiniteStream = true,
IsRemote = isRemote,
- IgnoreDts = true
+ IgnoreDts = true,
+ SupportsDirectPlay = supportsDirectPlay
};
mediaSource.InferTotalBitrate();
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index cc2cb3e5ee..af7491e862 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -71,7 +71,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
}
else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 ||
- contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1)
+ contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 ||
+ contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1)
{
requiresRemux = true;
}
@@ -88,6 +89,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
SetTempFilePath(extension);
var taskCompletionSource = new TaskCompletionSource<bool>();
+
+ var now = DateTime.UtcNow;
+
StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
//OpenedMediaSource.Protocol = MediaProtocol.File;
@@ -97,11 +101,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
OpenedMediaSource.Protocol = MediaProtocol.Http;
- if (OpenedMediaSource.SupportsProbing)
- {
- await Task.Delay(3000).ConfigureAwait(false);
- }
-
//OpenedMediaSource.Path = TempFilePath;
//OpenedMediaSource.Protocol = MediaProtocol.File;
@@ -111,6 +110,20 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.SupportsDirectStream = true;
//OpenedMediaSource.SupportsTranscoding = true;
await taskCompletionSource.Task.ConfigureAwait(false);
+
+ if (OpenedMediaSource.SupportsProbing)
+ {
+ var elapsed = (DateTime.UtcNow - now).TotalMilliseconds;
+
+ var delay = Convert.ToInt32(3000 - elapsed);
+
+ if (delay > 0)
+ {
+ Logger.Info("Delaying shared stream by {0}ms to allow the buffer to build.", delay);
+
+ await Task.Delay(delay).ConfigureAwait(false);
+ }
+ }
}
protected override void CloseInternal()