Add opt-in FFmpeg continuity slates with per-viewer localization
This commit is contained in:
@@ -36,6 +36,8 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
private readonly LiveStreamProbe _streamProbe;
|
||||
private readonly LiveStreamRelay _streamRelay;
|
||||
private readonly ILibraryManager _library;
|
||||
private readonly PlaybackFeedback _feedback;
|
||||
private readonly ContinuityStreams _continuity;
|
||||
|
||||
private string tvBouquetSRef;
|
||||
private List<ChannelInfo> tvChannelInfos = new List<ChannelInfo>();
|
||||
@@ -46,13 +48,15 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
|
||||
public static LiveTvService Instance { get; private set; }
|
||||
|
||||
public LiveTvService(ILogger<LiveTvService> logger, IHttpClientFactory httpClientFactory, InternetEpg internetEpg, LiveStreamProbe streamProbe, LiveStreamRelay streamRelay, ILibraryManager library)
|
||||
public LiveTvService(ILogger<LiveTvService> logger, IHttpClientFactory httpClientFactory, InternetEpg internetEpg, LiveStreamProbe streamProbe, LiveStreamRelay streamRelay, ILibraryManager library, PlaybackFeedback feedback = null, ContinuityStreams continuity = null)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_streamProbe = streamProbe;
|
||||
_streamRelay = streamRelay;
|
||||
_library = library;
|
||||
_feedback = feedback;
|
||||
_continuity = continuity;
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
@@ -1143,7 +1147,15 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
public async Task<MediaSourceInfo> GetChannelStream(string channelOid, string mediaSourceId, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("[Enigma2] Start GetChannelStream");
|
||||
|
||||
PlaybackFeedback.Attempt feedback = null;
|
||||
if (_feedback != null)
|
||||
{
|
||||
try { feedback = await _feedback.Begin(channelOid, cancellationToken).ConfigureAwait(false); }
|
||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { throw; }
|
||||
catch { /* Feedback is optional and must not affect playback. */ }
|
||||
}
|
||||
try
|
||||
{
|
||||
var requestedReference = channelOid;
|
||||
IEnumerable<ChannelInfo> currentChannels = Array.Empty<ChannelInfo>();
|
||||
using (var lookupDeadline = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
|
||||
@@ -1214,14 +1226,23 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
|
||||
var streamUrl = string.Format("{0}/{1}{2}", baseUrl, channelOid, trancodingUrl);
|
||||
streamUrl = _streamRelay.Register(streamUrl);
|
||||
// Background recordings keep the original source: never record an
|
||||
// endless status slate or guess a viewer language for a timer.
|
||||
if (Plugin.Instance.Configuration.EnableContinuitySlates && _continuity != null && feedback != null)
|
||||
{
|
||||
feedback.Report("waiting_for_stream");
|
||||
return await _continuity.Open(streamUrl, feedback.Language, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
var fields = channelOid.Split(':');
|
||||
var programme = !Plugin.Instance.Configuration.TranscodedStream && fields.Length > 3 && int.TryParse(fields[3], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var sid) ? sid : (int?)null;
|
||||
var streams = await _streamProbe.Get(streamUrl, cancellationToken, programme).ConfigureAwait(false);
|
||||
var probe = _streamProbe.Get(streamUrl, cancellationToken, programme);
|
||||
var streams = await (_feedback == null ? probe : _feedback.AwaitStream(probe, feedback, cancellationToken)).ConfigureAwait(false);
|
||||
|
||||
// A live TS may enumerate its EPG/data PID before AV on the next open.
|
||||
// Jellyfin maps positions in MediaStreams rather than MPEG-TS PID values.
|
||||
// Its supported unknown-index path selects AV automatically and omits data.
|
||||
streams = streams.Select(s => LiveStreamProbe.ParseLiveMetadata(s)).ToList();
|
||||
feedback?.Report("ready");
|
||||
|
||||
return new MediaSourceInfo
|
||||
{
|
||||
@@ -1235,7 +1256,11 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
SupportsDirectPlay = false,
|
||||
MediaStreams = streams
|
||||
};
|
||||
throw new ResourceNotFoundException(string.Format("Could not stream channel {0}", channelOid));
|
||||
}
|
||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
||||
{ feedback?.Report("cancelled"); throw; }
|
||||
catch
|
||||
{ feedback?.Report("failed"); throw; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1628,6 +1653,7 @@ namespace Jellyfin.Plugin.Enigma2
|
||||
|
||||
public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
|
||||
{
|
||||
_continuity?.Close(id);
|
||||
await Task.Factory.StartNew<string>(() =>
|
||||
{
|
||||
_logger.LogDebug("[Enigma2] LiveTvService.CloseLiveStream: closed stream for subscriptionId: {id}", id);
|
||||
|
||||
Reference in New Issue
Block a user