mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-01 04:34:26 -04:00
support sharing m3u tuner streams
This commit is contained in:
parent
2c6cbb33ee
commit
2f758676d0
@ -404,11 +404,11 @@
|
|||||||
<Compile Include="LiveTv\TunerHosts\BaseTunerHost.cs" />
|
<Compile Include="LiveTv\TunerHosts\BaseTunerHost.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunManager.cs" />
|
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunManager.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHost.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\HdHomerun\HdHomerunUdpStream.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\LiveStream.cs" />
|
<Compile Include="LiveTv\TunerHosts\LiveStream.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\M3uParser.cs" />
|
<Compile Include="LiveTv\TunerHosts\M3uParser.cs" />
|
||||||
<Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" />
|
<Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" />
|
||||||
|
<Compile Include="LiveTv\TunerHosts\SharedHttpStream.cs" />
|
||||||
<Compile Include="Localization\LocalizationManager.cs" />
|
<Compile Include="Localization\LocalizationManager.cs" />
|
||||||
<Compile Include="Localization\TextLocalizer.cs" />
|
<Compile Include="Localization\TextLocalizer.cs" />
|
||||||
<Compile Include="Logging\ConsoleLogger.cs" />
|
<Compile Include="Logging\ConsoleLogger.cs" />
|
||||||
|
@ -618,7 +618,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
}
|
}
|
||||||
mediaSource.Path = httpUrl;
|
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);
|
return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
|
||||||
|
@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
OriginalStreamId = originalStreamId;
|
OriginalStreamId = originalStreamId;
|
||||||
_channelCommands = channelCommands;
|
_channelCommands = channelCommands;
|
||||||
_numTuners = numTuners;
|
_numTuners = numTuners;
|
||||||
|
EnableStreamSharing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Open(CancellationToken openCancellationToken)
|
public override async Task Open(CancellationToken openCancellationToken)
|
||||||
|
@ -29,8 +29,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
public List<string> SharedStreamIds { get; private set; }
|
public List<string> SharedStreamIds { get; private set; }
|
||||||
protected readonly IEnvironmentInfo Environment;
|
protected readonly IEnvironmentInfo Environment;
|
||||||
protected readonly IFileSystem FileSystem;
|
protected readonly IFileSystem FileSystem;
|
||||||
|
protected readonly IServerApplicationPaths AppPaths;
|
||||||
|
|
||||||
protected readonly string TempFilePath;
|
protected string TempFilePath;
|
||||||
protected readonly ILogger Logger;
|
protected readonly ILogger Logger;
|
||||||
protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource();
|
protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
@ -44,7 +45,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
EnableStreamSharing = true;
|
EnableStreamSharing = true;
|
||||||
SharedStreamIds = new List<string>();
|
SharedStreamIds = new List<string>();
|
||||||
UniqueId = Guid.NewGuid().ToString("N");
|
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)
|
public virtual Task Open(CancellationToken openCancellationToken)
|
||||||
|
@ -79,8 +79,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
{
|
{
|
||||||
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
|
var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var liveStream = new LiveStream(sources.First(), _environment, FileSystem, Logger, Config.ApplicationPaths);
|
var mediaSource = sources.First();
|
||||||
return liveStream;
|
|
||||||
|
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)
|
public async Task Validate(TunerHostInfo info)
|
||||||
|
@ -15,19 +15,20 @@ using MediaBrowser.Model.System;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using MediaBrowser.Controller.IO;
|
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 IHttpClient _httpClient;
|
||||||
private readonly IServerApplicationHost _appHost;
|
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)
|
: base(mediaSource, environment, fileSystem, logger, appPaths)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
OriginalStreamId = originalStreamId;
|
OriginalStreamId = originalStreamId;
|
||||||
|
EnableStreamSharing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Open(CancellationToken openCancellationToken)
|
public override async Task Open(CancellationToken openCancellationToken)
|
||||||
@ -40,7 +41,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
|
|
||||||
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath));
|
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
|
var response = await _httpClient.SendAsync(new HttpRequestOptions
|
||||||
{
|
{
|
||||||
@ -51,11 +53,35 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
// Increase a little bit
|
// Increase a little bit
|
||||||
TimeoutMs = 30000,
|
TimeoutMs = 30000,
|
||||||
|
|
||||||
EnableHttpCompression = false
|
EnableHttpCompression = false,
|
||||||
|
|
||||||
|
LogResponse = true,
|
||||||
|
LogResponseHeaders = true
|
||||||
|
|
||||||
}, "GET").ConfigureAwait(false);
|
}, "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>();
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
||||||
@ -90,7 +116,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||||||
{
|
{
|
||||||
using (var stream = response.Content)
|
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))
|
using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
|
||||||
{
|
{
|
@ -335,7 +335,8 @@ namespace MediaBrowser.Api.Library
|
|||||||
Fields = request.Fields,
|
Fields = request.Fields,
|
||||||
Id = request.Id,
|
Id = request.Id,
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
UserId = request.UserId
|
UserId = request.UserId,
|
||||||
|
ImageTypeLimit = request.ImageTypeLimit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (item is MusicAlbum)
|
if (item is MusicAlbum)
|
||||||
@ -350,7 +351,8 @@ namespace MediaBrowser.Api.Library
|
|||||||
Id = request.Id,
|
Id = request.Id,
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
UserId = request.UserId,
|
UserId = request.UserId,
|
||||||
ExcludeArtistIds = request.ExcludeArtistIds
|
ExcludeArtistIds = request.ExcludeArtistIds,
|
||||||
|
ImageTypeLimit = request.ImageTypeLimit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (item is MusicArtist)
|
if (item is MusicArtist)
|
||||||
@ -364,7 +366,8 @@ namespace MediaBrowser.Api.Library
|
|||||||
Fields = request.Fields,
|
Fields = request.Fields,
|
||||||
Id = request.Id,
|
Id = request.Id,
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
UserId = request.UserId
|
UserId = request.UserId,
|
||||||
|
ImageTypeLimit = request.ImageTypeLimit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +384,8 @@ namespace MediaBrowser.Api.Library
|
|||||||
Fields = request.Fields,
|
Fields = request.Fields,
|
||||||
Id = request.Id,
|
Id = request.Id,
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
UserId = request.UserId
|
UserId = request.UserId,
|
||||||
|
ImageTypeLimit = request.ImageTypeLimit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +400,8 @@ namespace MediaBrowser.Api.Library
|
|||||||
Fields = request.Fields,
|
Fields = request.Fields,
|
||||||
Id = request.Id,
|
Id = request.Id,
|
||||||
Limit = request.Limit,
|
Limit = request.Limit,
|
||||||
UserId = request.UserId
|
UserId = request.UserId,
|
||||||
|
ImageTypeLimit = request.ImageTypeLimit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,8 @@ namespace MediaBrowser.Common.Net
|
|||||||
public bool LogRequest { get; set; }
|
public bool LogRequest { get; set; }
|
||||||
public bool LogRequestAsDebug { get; set; }
|
public bool LogRequestAsDebug { get; set; }
|
||||||
public bool LogErrors { get; set; }
|
public bool LogErrors { get; set; }
|
||||||
|
public bool LogResponse { get; set; }
|
||||||
|
public bool LogResponseHeaders { get; set; }
|
||||||
|
|
||||||
public bool LogErrorResponseBody { get; set; }
|
public bool LogErrorResponseBody { get; set; }
|
||||||
public bool EnableKeepAlive { get; set; }
|
public bool EnableKeepAlive { get; set; }
|
||||||
|
@ -1421,6 +1421,16 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
// Sweep through recursively and update status
|
// Sweep through recursively and update status
|
||||||
foreach (var item in itemsResult)
|
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);
|
item.MarkPlayed(user, datePlayed, resetPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("3.2.36.8")]
|
[assembly: AssemblyVersion("3.2.36.9")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user