support duration on recording url

This commit is contained in:
Luke Pulverenti 2016-04-25 22:16:46 -04:00
parent 5401641e2b
commit 54e04dd027
6 changed files with 43 additions and 9 deletions

View File

@ -46,6 +46,8 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;List&lt;MediaSourceInfo&gt;&gt;.</returns>
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
string ApplyDuration(string streamPath, TimeSpan duration);
}
public interface IConfigurableTunerHost
{

View File

@ -42,10 +42,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_logger.Info("Copying recording stream to file {0}", targetFile);
var durationToken = new CancellationTokenSource(duration);
var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
if (!mediaSource.RunTimeTicks.HasValue)
{
var durationToken = new CancellationTokenSource(duration);
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
}
await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken).ConfigureAwait(false);
await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
}
}

View File

@ -591,7 +591,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
throw new ApplicationException("Tuner not found.");
}
private async Task<Tuple<MediaSourceInfo, SemaphoreSlim>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken)
private async Task<Tuple<MediaSourceInfo, ITunerHost, SemaphoreSlim>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken)
{
_logger.Info("Streaming Channel " + channelId);
@ -599,7 +599,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
try
{
return await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false);
var result = await hostInstance.GetChannelStream(channelId, streamId, cancellationToken).ConfigureAwait(false);
return new Tuple<MediaSourceInfo, ITunerHost, SemaphoreSlim>(result.Item1, hostInstance, result.Item2);
}
catch (Exception e)
{
@ -797,8 +799,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
// HDHR doesn't seem to release the tuner right away after first probing with ffmpeg
//await Task.Delay(3000, cancellationToken).ConfigureAwait(false);
var duration = recordingEndDate - DateTime.UtcNow;
var recorder = await GetRecorder().ConfigureAwait(false);
if (recorder is EncodedRecorder)
@ -816,6 +816,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
recording.DateLastUpdated = DateTime.UtcNow;
_recordingProvider.AddOrUpdate(recording);
var duration = recordingEndDate - DateTime.UtcNow;
_logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
_logger.Info("Writing file to path: " + recordPath);
@ -823,10 +825,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
Action onStarted = () =>
{
result.Item2.Release();
result.Item3.Release();
isResourceOpen = false;
};
var pathWithDuration = result.Item2.ApplyDuration(mediaStreamInfo.Path, duration);
// If it supports supplying duration via url
if (!string.Equals(pathWithDuration, mediaStreamInfo.Path, StringComparison.OrdinalIgnoreCase))
{
mediaStreamInfo.Path = pathWithDuration;
mediaStreamInfo.RunTimeTicks = duration.Ticks;
}
await recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken).ConfigureAwait(false);
recording.Status = RecordingStatus.Completed;
@ -836,7 +847,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
if (isResourceOpen)
{
result.Item2.Release();
result.Item3.Release();
}
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);

View File

@ -59,6 +59,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return id;
}
public string ApplyDuration(string streamPath, TimeSpan duration)
{
streamPath += streamPath.IndexOf('?') == -1 ? "?" : "&";
streamPath += "duration=" + Convert.ToInt32(duration.TotalSeconds).ToString(CultureInfo.InvariantCulture);
return streamPath;
}
private async Task<IEnumerable<Channels>> GetLineup(TunerHostInfo info, CancellationToken cancellationToken)
{
var options = new HttpRequestOptions

View File

@ -146,5 +146,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
return Task.FromResult(true);
}
public string ApplyDuration(string streamPath, TimeSpan duration)
{
return streamPath;
}
}
}

View File

@ -164,5 +164,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
return list;
}
public string ApplyDuration(string streamPath, TimeSpan duration)
{
return streamPath;
}
}
}