diff options
| author | Luke <luke.pulverenti@gmail.com> | 2016-06-20 18:41:49 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-06-20 18:41:49 -0400 |
| commit | 9d62e402ddb2cba14d9fd56c4ad8baae24ac58db (patch) | |
| tree | 0cd42195ff7bd0d33b22604953d81fc57c3784c2 | |
| parent | 88e12d1b4ff433c036ece07271475b23866aab4b (diff) | |
| parent | 2d6954f5206cf1c07660108018ff3432dd1c9f05 (diff) | |
Merge pull request #1864 from MediaBrowser/dev
Dev
9 files changed, 125 insertions, 26 deletions
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 2ef8b70f0..78138999c 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -154,7 +154,7 @@ namespace MediaBrowser.Controller.Persistence /// </summary> /// <param name="query">The query.</param> /// <returns>List<BaseItem>.</returns> - IEnumerable<BaseItem> GetItemList(InternalItemsQuery query); + List<BaseItem> GetItemList(InternalItemsQuery query); /// <summary> /// Updates the inherited values. diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs index 4ecfd3c5b..202ea76fb 100644 --- a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs @@ -189,6 +189,15 @@ namespace MediaBrowser.Dlna.Profiles } } }; + + SubtitleProfiles = new[] + { + new SubtitleProfile + { + Format = "srt", + Method = SubtitleDeliveryMethod.External + } + }; } } } diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml index 2c6d10e99..1147aa299 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml @@ -77,5 +77,7 @@ </CodecProfile> </CodecProfiles> <ResponseProfiles /> - <SubtitleProfiles /> + <SubtitleProfiles> + <SubtitleProfile format="srt" method="External" /> + </SubtitleProfiles> </Profile>
\ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs index 07711301d..82a966821 100644 --- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // Add resolution params, if specified if (!hasGraphicalSubs) { - args += GetOutputSizeParam(state, videoCodec); + args += await GetOutputSizeParam(state, videoCodec).ConfigureAwait(false); } var qualityParam = GetVideoQualityParam(state, videoCodec); diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index a4cf90e5b..f21dd27ff 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1306,7 +1306,7 @@ namespace MediaBrowser.Server.Implementations.Dto ItemIds = new[] { item.Id.ToString("N") } }); - dto.ArtistItems = artistItems.Items + dto.AlbumArtists = artistItems.Items .Select(i => { var artist = i.Item1; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1b43ff7c1..29c1d1c9a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1059,6 +1059,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (recordingStatus == RecordingStatus.Completed) { + timer.Status = RecordingStatus.Completed; + _timerProvider.AddOrUpdate(timer); + OnSuccessfulRecording(info.IsSeries, recordPath); _timerProvider.Delete(timer); } @@ -1067,7 +1070,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV const int retryIntervalSeconds = 60; _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 { @@ -1119,7 +1124,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (regInfo.IsValid) { - return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config); + return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config, _httpClient); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 13158d346..6704dc139 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -8,7 +8,9 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -22,8 +24,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { private readonly ILogger _logger; private readonly IFileSystem _fileSystem; + private readonly IHttpClient _httpClient; private readonly IMediaEncoder _mediaEncoder; - private readonly IApplicationPaths _appPaths; + private readonly IServerApplicationPaths _appPaths; private readonly LiveTvOptions _liveTvOptions; private bool _hasExited; private Stream _logFileStream; @@ -32,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly IJsonSerializer _json; 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; _fileSystem = fileSystem; @@ -40,6 +43,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _appPaths = appPaths; _json = json; _liveTvOptions = liveTvOptions; + _httpClient = httpClient; } public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile) @@ -49,20 +53,73 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { - if (mediaSource.RunTimeTicks.HasValue) + var tempfile = Path.Combine(_appPaths.TranscodingTempPath, Guid.NewGuid().ToString("N") + ".ts"); + + try { - // The media source already has a fixed duration - // But add another stop 1 minute later just in case the recording gets stuck for any reason - var durationToken = new CancellationTokenSource(duration.Add(TimeSpan.FromMinutes(1))); - cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + await RecordInternal(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken) + .ConfigureAwait(false); } - else + finally + { + File.Delete(tempfile); + } + } + + public async Task RecordInternal(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) + { + var httpRequestOptions = new HttpRequestOptions() { - // The media source if infinite so we need to handle stopping ourselves - var durationToken = new CancellationTokenSource(duration); - cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + 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) + { + // The media source already has a fixed duration + // But add another stop 1 minute later just in case the recording gets stuck for any reason + var durationToken = new CancellationTokenSource(duration.Add(TimeSpan.FromMinutes(1))); + cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + } + else + { + // The media source if infinite so we need to handle stopping ourselves + var durationToken = new CancellationTokenSource(duration.Add(TimeSpan.FromMilliseconds(bufferMs))); + 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; _fileSystem.CreateDirectory(Path.GetDirectoryName(targetFile)); @@ -79,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV RedirectStandardInput = true, FileName = _mediaEncoder.EncoderPath, - Arguments = GetCommandLineArgs(mediaSource, targetFile, duration), + Arguments = GetCommandLineArgs(mediaSource, inputFile, targetFile), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -119,7 +176,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV 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; if (EncodeVideo(mediaSource)) @@ -135,14 +192,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV 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) { 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; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 5d462f106..bcad80447 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using CommonIO; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { @@ -85,6 +86,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void AddTimer(TimerInfo item) { + if (item.Status == RecordingStatus.Completed) + { + return; + } + var startDate = RecordingHelper.GetStartTime(item); 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); - 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)) { - _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 { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 006cb2edf..e98bb49d6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1742,7 +1742,7 @@ namespace MediaBrowser.Server.Implementations.Persistence return " from TypedBaseItems A"; } - public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query) + public List<BaseItem> GetItemList(InternalItemsQuery query) { if (query == null) { @@ -1842,6 +1842,16 @@ namespace MediaBrowser.Server.Implementations.Persistence 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; using (var cmd = _connection.CreateCommand()) @@ -2196,6 +2206,16 @@ namespace MediaBrowser.Server.Implementations.Persistence 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; using (var cmd = _connection.CreateCommand()) |
