Merge pull request #1864 from MediaBrowser/dev

Dev
pull/702/head
Luke 9 years ago committed by GitHub
commit 9d62e402dd

@ -154,7 +154,7 @@ namespace MediaBrowser.Controller.Persistence
/// </summary> /// </summary>
/// <param name="query">The query.</param> /// <param name="query">The query.</param>
/// <returns>List&lt;BaseItem&gt;.</returns> /// <returns>List&lt;BaseItem&gt;.</returns>
IEnumerable<BaseItem> GetItemList(InternalItemsQuery query); List<BaseItem> GetItemList(InternalItemsQuery query);
/// <summary> /// <summary>
/// Updates the inherited values. /// Updates the inherited values.

@ -189,6 +189,15 @@ namespace MediaBrowser.Dlna.Profiles
} }
} }
}; };
SubtitleProfiles = new[]
{
new SubtitleProfile
{
Format = "srt",
Method = SubtitleDeliveryMethod.External
}
};
} }
} }
} }

@ -77,5 +77,7 @@
</CodecProfile> </CodecProfile>
</CodecProfiles> </CodecProfiles>
<ResponseProfiles /> <ResponseProfiles />
<SubtitleProfiles /> <SubtitleProfiles>
<SubtitleProfile format="srt" method="External" />
</SubtitleProfiles>
</Profile> </Profile>

@ -94,7 +94,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
// Add resolution params, if specified // Add resolution params, if specified
if (!hasGraphicalSubs) if (!hasGraphicalSubs)
{ {
args += GetOutputSizeParam(state, videoCodec); args += await GetOutputSizeParam(state, videoCodec).ConfigureAwait(false);
} }
var qualityParam = GetVideoQualityParam(state, videoCodec); var qualityParam = GetVideoQualityParam(state, videoCodec);

@ -1306,7 +1306,7 @@ namespace MediaBrowser.Server.Implementations.Dto
ItemIds = new[] { item.Id.ToString("N") } ItemIds = new[] { item.Id.ToString("N") }
}); });
dto.ArtistItems = artistItems.Items dto.AlbumArtists = artistItems.Items
.Select(i => .Select(i =>
{ {
var artist = i.Item1; var artist = i.Item1;

@ -1059,6 +1059,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (recordingStatus == RecordingStatus.Completed) if (recordingStatus == RecordingStatus.Completed)
{ {
timer.Status = RecordingStatus.Completed;
_timerProvider.AddOrUpdate(timer);
OnSuccessfulRecording(info.IsSeries, recordPath); OnSuccessfulRecording(info.IsSeries, recordPath);
_timerProvider.Delete(timer); _timerProvider.Delete(timer);
} }
@ -1067,7 +1070,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
const int retryIntervalSeconds = 60; const int retryIntervalSeconds = 60;
_logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds);
_timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds)); timer.Status = RecordingStatus.New;
timer.StartDate = DateTime.UtcNow.AddSeconds(retryIntervalSeconds);
_timerProvider.AddOrUpdate(timer);
} }
else else
{ {
@ -1119,7 +1124,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (regInfo.IsValid) if (regInfo.IsValid)
{ {
return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config); return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config, _httpClient);
} }
} }

@ -8,7 +8,9 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommonIO; using CommonIO;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
@ -22,8 +24,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IApplicationPaths _appPaths; private readonly IServerApplicationPaths _appPaths;
private readonly LiveTvOptions _liveTvOptions; private readonly LiveTvOptions _liveTvOptions;
private bool _hasExited; private bool _hasExited;
private Stream _logFileStream; private Stream _logFileStream;
@ -32,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>(); private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
public EncodedRecorder(ILogger logger, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IApplicationPaths appPaths, IJsonSerializer json, LiveTvOptions liveTvOptions) public EncodedRecorder(ILogger logger, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IServerApplicationPaths appPaths, IJsonSerializer json, LiveTvOptions liveTvOptions, IHttpClient httpClient)
{ {
_logger = logger; _logger = logger;
_fileSystem = fileSystem; _fileSystem = fileSystem;
@ -40,6 +43,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_appPaths = appPaths; _appPaths = appPaths;
_json = json; _json = json;
_liveTvOptions = liveTvOptions; _liveTvOptions = liveTvOptions;
_httpClient = httpClient;
} }
public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile) public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile)
@ -49,6 +53,42 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
{ {
var tempfile = Path.Combine(_appPaths.TranscodingTempPath, Guid.NewGuid().ToString("N") + ".ts");
try
{
await RecordInternal(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken)
.ConfigureAwait(false);
}
finally
{
File.Delete(tempfile);
}
}
public async Task RecordInternal(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
{
var httpRequestOptions = new HttpRequestOptions()
{
Url = mediaSource.Path
};
httpRequestOptions.BufferContent = false;
using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false))
{
_logger.Info("Opened recording stream from tuner provider");
Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
using (var output = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read))
{
//onStarted();
_logger.Info("Copying recording stream to file {0}", tempFile);
var bufferMs = 5000;
if (mediaSource.RunTimeTicks.HasValue) if (mediaSource.RunTimeTicks.HasValue)
{ {
// The media source already has a fixed duration // The media source already has a fixed duration
@ -59,10 +99,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
else else
{ {
// The media source if infinite so we need to handle stopping ourselves // The media source if infinite so we need to handle stopping ourselves
var durationToken = new CancellationTokenSource(duration); var durationToken = new CancellationTokenSource(duration.Add(TimeSpan.FromMilliseconds(bufferMs)));
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
} }
var tempFileTask = response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, cancellationToken);
// Give the temp file a little time to build up
await Task.Delay(bufferMs, cancellationToken).ConfigureAwait(false);
await RecordFromFile(mediaSource, tempFile, targetFile, onStarted, cancellationToken)
.ConfigureAwait(false);
await tempFileTask.ConfigureAwait(false);
}
}
_logger.Info("Recording completed to file {0}", targetFile);
}
private async Task RecordFromFile(MediaSourceInfo mediaSource, string inputFile, string targetFile, Action onStarted, CancellationToken cancellationToken)
{
_targetPath = targetFile; _targetPath = targetFile;
_fileSystem.CreateDirectory(Path.GetDirectoryName(targetFile)); _fileSystem.CreateDirectory(Path.GetDirectoryName(targetFile));
@ -79,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
RedirectStandardInput = true, RedirectStandardInput = true,
FileName = _mediaEncoder.EncoderPath, FileName = _mediaEncoder.EncoderPath,
Arguments = GetCommandLineArgs(mediaSource, targetFile, duration), Arguments = GetCommandLineArgs(mediaSource, inputFile, targetFile),
WindowStyle = ProcessWindowStyle.Hidden, WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false ErrorDialog = false
@ -119,7 +176,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
await _taskCompletionSource.Task.ConfigureAwait(false); await _taskCompletionSource.Task.ConfigureAwait(false);
} }
private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration) private string GetCommandLineArgs(MediaSourceInfo mediaSource, string inputTempFile, string targetFile)
{ {
string videoArgs; string videoArgs;
if (EncodeVideo(mediaSource)) if (EncodeVideo(mediaSource))
@ -135,14 +192,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
videoArgs = "-codec:v:0 copy"; videoArgs = "-codec:v:0 copy";
} }
var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -re -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -re -i \"{0}\" -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\"";
if (mediaSource.ReadAtNativeFramerate) if (mediaSource.ReadAtNativeFramerate)
{ {
commandLineArgs = "-re " + commandLineArgs; commandLineArgs = "-re " + commandLineArgs;
} }
commandLineArgs = string.Format(commandLineArgs, mediaSource.Path, targetFile, videoArgs, GetAudioArgs(mediaSource), _mediaEncoder.GetTimeParameter(duration.Ticks)); commandLineArgs = string.Format(commandLineArgs, inputTempFile, targetFile, videoArgs, GetAudioArgs(mediaSource));
return commandLineArgs; return commandLineArgs;
} }

@ -10,6 +10,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using CommonIO; using CommonIO;
using MediaBrowser.Controller.Power; using MediaBrowser.Controller.Power;
using MediaBrowser.Model.LiveTv;
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{ {
@ -85,6 +86,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private void AddTimer(TimerInfo item) private void AddTimer(TimerInfo item)
{ {
if (item.Status == RecordingStatus.Completed)
{
return;
}
var startDate = RecordingHelper.GetStartTime(item); var startDate = RecordingHelper.GetStartTime(item);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
@ -117,15 +123,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
} }
} }
public void StartTimer(TimerInfo item, TimeSpan length) public void StartTimer(TimerInfo item, TimeSpan dueTime)
{ {
StopTimer(item); StopTimer(item);
var timer = new Timer(TimerCallback, item.Id, length, TimeSpan.Zero); var timer = new Timer(TimerCallback, item.Id, dueTime, TimeSpan.Zero);
if (_timers.TryAdd(item.Id, timer)) if (_timers.TryAdd(item.Id, timer))
{ {
_logger.Info("Creating recording timer for {0}, {1}. Timer will fire in {2} minutes", item.Id, item.Name, length.TotalMinutes.ToString(CultureInfo.InvariantCulture)); _logger.Info("Creating recording timer for {0}, {1}. Timer will fire in {2} minutes", item.Id, item.Name, dueTime.TotalMinutes.ToString(CultureInfo.InvariantCulture));
} }
else else
{ {

@ -1742,7 +1742,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
return " from TypedBaseItems A"; return " from TypedBaseItems A";
} }
public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query) public List<BaseItem> GetItemList(InternalItemsQuery query)
{ {
if (query == null) if (query == null)
{ {
@ -1842,6 +1842,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed(); CheckDisposed();
if (!query.EnableTotalRecordCount || (!query.Limit.HasValue && (query.StartIndex ?? 0) == 0))
{
var list = GetItemList(query);
return new QueryResult<BaseItem>
{
Items = list.ToArray(),
TotalRecordCount = list.Count
};
}
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
using (var cmd = _connection.CreateCommand()) using (var cmd = _connection.CreateCommand())
@ -2196,6 +2206,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
CheckDisposed(); CheckDisposed();
if (!query.EnableTotalRecordCount || (!query.Limit.HasValue && (query.StartIndex ?? 0) == 0))
{
var list = GetItemIdsList(query);
return new QueryResult<Guid>
{
Items = list.ToArray(),
TotalRecordCount = list.Count
};
}
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
using (var cmd = _connection.CreateCommand()) using (var cmd = _connection.CreateCommand())

Loading…
Cancel
Save