support sharing m3u tuner streams

This commit is contained in:
Luke Pulverenti 2017-11-14 02:41:21 -05:00
parent 2c6cbb33ee
commit 2f758676d0
10 changed files with 78 additions and 19 deletions

View file

@ -404,11 +404,11 @@
<Compile Include="LiveTv\TunerHosts\BaseTunerHost.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunManager.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHost.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHttpStream.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunUdpStream.cs" />
<Compile Include="LiveTv\TunerHosts\LiveStream.cs" />
<Compile Include="LiveTv\TunerHosts\M3uParser.cs" />
<Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" />
<Compile Include="LiveTv\TunerHosts\SharedHttpStream.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
<Compile Include="Localization\TextLocalizer.cs" />
<Compile Include="Logging\ConsoleLogger.cs" />

View file

@ -618,7 +618,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
mediaSource.Path = httpUrl;
return new HdHomerunHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
}
return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);

View file

@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
OriginalStreamId = originalStreamId;
_channelCommands = channelCommands;
_numTuners = numTuners;
EnableStreamSharing = true;
}
public override async Task Open(CancellationToken openCancellationToken)

View file

@ -29,8 +29,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public List<string> SharedStreamIds { get; private set; }
protected readonly IEnvironmentInfo Environment;
protected readonly IFileSystem FileSystem;
protected readonly IServerApplicationPaths AppPaths;
protected readonly string TempFilePath;
protected string TempFilePath;
protected readonly ILogger Logger;
protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource();
@ -44,7 +45,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
EnableStreamSharing = true;
SharedStreamIds = new List<string>();
UniqueId = Guid.NewGuid().ToString("N");
TempFilePath = Path.Combine(appPaths.GetTranscodingTempPath(), UniqueId + ".ts");
AppPaths = appPaths;
SetTempFilePath("ts");
}
protected void SetTempFilePath(string extension)
{
TempFilePath = Path.Combine(AppPaths.GetTranscodingTempPath(), UniqueId + "." + extension);
}
public virtual Task Open(CancellationToken openCancellationToken)

View file

@ -79,8 +79,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
var liveStream = new LiveStream(sources.First(), _environment, FileSystem, Logger, Config.ApplicationPaths);
return liveStream;
var mediaSource = sources.First();
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
{
return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
}
return new LiveStream(mediaSource, _environment, FileSystem, Logger, Config.ApplicationPaths);
}
public async Task Validate(TunerHostInfo info)

View file

@ -15,19 +15,20 @@ using MediaBrowser.Model.System;
using System.Globalization;
using MediaBrowser.Controller.IO;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
namespace Emby.Server.Implementations.LiveTv.TunerHosts
{
public class HdHomerunHttpStream : LiveStream, IDirectStreamProvider
public class SharedHttpStream : LiveStream, IDirectStreamProvider
{
private readonly IHttpClient _httpClient;
private readonly IServerApplicationHost _appHost;
public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
public SharedHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
: base(mediaSource, environment, fileSystem, logger, appPaths)
{
_httpClient = httpClient;
_appHost = appHost;
OriginalStreamId = originalStreamId;
EnableStreamSharing = true;
}
public override async Task Open(CancellationToken openCancellationToken)
@ -40,7 +41,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath));
Logger.Info("Opening HDHR Live stream from {0}", url);
var typeName = GetType().Name;
Logger.Info("Opening " + typeName + " Live stream from {0}", url);
var response = await _httpClient.SendAsync(new HttpRequestOptions
{
@ -51,11 +53,35 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// Increase a little bit
TimeoutMs = 30000,
EnableHttpCompression = false
EnableHttpCompression = false,
LogResponse = true,
LogResponseHeaders = true
}, "GET").ConfigureAwait(false);
Logger.Info("Opened HDHR stream from {0}", url);
var extension = "ts";
var requiresRemux = false;
var contentType = response.ContentType ?? string.Empty;
if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("matroska", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 ||
contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1)
{
requiresRemux = true;
}
// Close the stream without any sharing features
if (requiresRemux)
{
using (response)
{
return;
}
}
SetTempFilePath(extension);
var taskCompletionSource = new TaskCompletionSource<bool>();
StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
@ -90,7 +116,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
using (var stream = response.Content)
{
Logger.Info("Beginning HdHomerunHttpStream stream to file");
Logger.Info("Beginning {0} stream to {1}", GetType().Name, TempFilePath);
using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
{

View file

@ -335,7 +335,8 @@ namespace MediaBrowser.Api.Library
Fields = request.Fields,
Id = request.Id,
Limit = request.Limit,
UserId = request.UserId
UserId = request.UserId,
ImageTypeLimit = request.ImageTypeLimit
});
}
if (item is MusicAlbum)
@ -350,7 +351,8 @@ namespace MediaBrowser.Api.Library
Id = request.Id,
Limit = request.Limit,
UserId = request.UserId,
ExcludeArtistIds = request.ExcludeArtistIds
ExcludeArtistIds = request.ExcludeArtistIds,
ImageTypeLimit = request.ImageTypeLimit
});
}
if (item is MusicArtist)
@ -364,7 +366,8 @@ namespace MediaBrowser.Api.Library
Fields = request.Fields,
Id = request.Id,
Limit = request.Limit,
UserId = request.UserId
UserId = request.UserId,
ImageTypeLimit = request.ImageTypeLimit
});
}
@ -381,7 +384,8 @@ namespace MediaBrowser.Api.Library
Fields = request.Fields,
Id = request.Id,
Limit = request.Limit,
UserId = request.UserId
UserId = request.UserId,
ImageTypeLimit = request.ImageTypeLimit
});
}
@ -396,7 +400,8 @@ namespace MediaBrowser.Api.Library
Fields = request.Fields,
Id = request.Id,
Limit = request.Limit,
UserId = request.UserId
UserId = request.UserId,
ImageTypeLimit = request.ImageTypeLimit
});
}

View file

@ -93,6 +93,8 @@ namespace MediaBrowser.Common.Net
public bool LogRequest { get; set; }
public bool LogRequestAsDebug { get; set; }
public bool LogErrors { get; set; }
public bool LogResponse { get; set; }
public bool LogResponseHeaders { get; set; }
public bool LogErrorResponseBody { get; set; }
public bool EnableKeepAlive { get; set; }

View file

@ -1421,6 +1421,16 @@ namespace MediaBrowser.Controller.Entities
// Sweep through recursively and update status
foreach (var item in itemsResult)
{
if (item.IsVirtualItem)
{
// The querying doesn't support virtual unaired
var episode = item as Episode;
if (episode != null && episode.IsUnaired)
{
continue;
}
}
item.MarkPlayed(user, datePlayed, resetPosition);
}
}

View file

@ -1,3 +1,3 @@
using System.Reflection;
[assembly: AssemblyVersion("3.2.36.8")]
[assembly: AssemblyVersion("3.2.36.9")]