From 97d051e437ba4824b8c81bfd28f687574229b45c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 21 Sep 2015 12:26:05 -0400 Subject: [PATCH] restore changes --- .../LiveTv/EmbyTV/EmbyTV.cs | 158 ++++++++++++++---- .../LiveTv/Listings/SchedulesDirect.cs | 9 +- .../LiveTv/LiveTvManager.cs | 20 ++- SharedVersion.cs | 4 +- 4 files changed, 144 insertions(+), 47 deletions(-) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index b89d8a8d10..2b55945e62 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -8,7 +8,9 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; @@ -47,10 +49,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly IFileOrganizationService _organizationService; + private readonly IMediaEncoder _mediaEncoder; public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) { Current = this; @@ -64,12 +67,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _libraryMonitor = libraryMonitor; _providerManager = providerManager; _organizationService = organizationService; + _mediaEncoder = mediaEncoder; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; - _recordingProvider = new ItemDataProvider(jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)); - _seriesTimerProvider = new SeriesTimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers")); - _timerProvider = new TimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "timers")); + _recordingProvider = new ItemDataProvider(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase)); + _seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers")); + _timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers")); _timerProvider.TimerFired += _timerProvider_TimerFired; } @@ -126,6 +130,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return status; } + public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress progress) + { + var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); + + List channels = null; + + foreach (var timer in timers) + { + List epgData; + + if (timer.RecordAnyChannel) + { + if (channels == null) + { + channels = (await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false)).ToList(); + } + var channelIds = channels.Select(i => i.Id).ToList(); + epgData = GetEpgDataForChannels(channelIds); + } + else + { + epgData = GetEpgDataForChannel(timer.ChannelId); + } + await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false); + } + } + private List _channelCache = null; private async Task> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken) { @@ -235,7 +266,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV try { - File.Delete(remove.Path); + _fileSystem.DeleteFile(remove.Path); } catch (DirectoryNotFoundException) { @@ -364,33 +395,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return Task.FromResult((IEnumerable)_seriesTimerProvider.GetAll()); } - public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress progress) - { - var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); - - List channels = null; - - foreach (var timer in timers) - { - List epgData; - - if (timer.RecordAnyChannel) - { - if (channels == null) - { - channels = (await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false)).ToList(); - } - var channelIds = channels.Select(i => i.Id).ToList(); - epgData = GetEpgDataForChannels(channelIds); - } - else - { - epgData = GetEpgDataForChannel(timer.ChannelId); - } - await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false); - } - } - public async Task> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { try @@ -469,6 +473,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (mediaSourceInfo != null) { + await AddMediaInfo(mediaSourceInfo, false, cancellationToken).ConfigureAwait(false); + mediaSourceInfo.Id = Guid.NewGuid().ToString("N"); return mediaSourceInfo; } @@ -499,6 +505,84 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV throw new NotImplementedException(); } + private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) + { + var originalRuntime = mediaSource.RunTimeTicks; + + var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest + { + InputPath = mediaSource.Path, + Protocol = mediaSource.Protocol, + MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, + ExtractChapters = false + + }, cancellationToken).ConfigureAwait(false); + + mediaSource.Bitrate = info.Bitrate; + mediaSource.Container = info.Container; + mediaSource.Formats = info.Formats; + mediaSource.MediaStreams = info.MediaStreams; + mediaSource.RunTimeTicks = info.RunTimeTicks; + mediaSource.Size = info.Size; + mediaSource.Timestamp = info.Timestamp; + mediaSource.Video3DFormat = info.Video3DFormat; + mediaSource.VideoType = info.VideoType; + + mediaSource.DefaultSubtitleStreamIndex = null; + + // Null this out so that it will be treated like a live stream + if (!originalRuntime.HasValue) + { + mediaSource.RunTimeTicks = null; + } + + var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio); + + if (audioStream == null || audioStream.Index == -1) + { + mediaSource.DefaultAudioStreamIndex = null; + } + else + { + mediaSource.DefaultAudioStreamIndex = audioStream.Index; + } + + var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video); + if (videoStream != null) + { + if (!videoStream.BitRate.HasValue) + { + var width = videoStream.Width ?? 1920; + + if (width >= 1900) + { + videoStream.BitRate = 8000000; + } + + else if (width >= 1260) + { + videoStream.BitRate = 3000000; + } + + else if (width >= 700) + { + videoStream.BitRate = 1000000; + } + } + } + + // Try to estimate this + if (!mediaSource.Bitrate.HasValue) + { + var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); + + if (total > 0) + { + mediaSource.Bitrate = total; + } + } + } + public Task> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) { throw new NotImplementedException(); @@ -586,7 +670,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts"; recordPath = Path.Combine(recordPath, recordingFileName); - Directory.CreateDirectory(Path.GetDirectoryName(recordPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase)); @@ -630,7 +714,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _recordingProvider.Update(recording); _logger.Info("Beginning recording."); - + try { httpRequestOptions.BufferContent = false; @@ -640,7 +724,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger.Info("Writing file to path: " + recordPath); using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET")) { - using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) + using (var output = _fileSystem.GetFileStream(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken); } @@ -801,7 +885,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private void SaveEpgDataForChannel(string channelId, List epgData) { var path = GetChannelEpgCachePath(channelId); - Directory.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); lock (_epgLock) { _jsonSerializer.SerializeToFile(epgData, path); @@ -848,4 +932,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV }); } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 2efa911372..161bcbf481 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -362,8 +362,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings private DateTime GetDate(string value) { - return DateTime.ParseExact(value, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", - CultureInfo.InvariantCulture); + var date = DateTime.ParseExact(value, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", CultureInfo.InvariantCulture); + + if (date.Kind != DateTimeKind.Utc) + { + date = DateTime.SpecifyKind(date, DateTimeKind.Utc); + } + return date; } private string GetProgramLogo(string apiUrl, ScheduleDirect.ShowImages images) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 7a26bf87c6..fbafe7151d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -580,7 +580,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.Name = channelInfo.Name; } - await item.RefreshMetadata(new MetadataRefreshOptions + await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = isNew, ReplaceImages = replaceImages.Distinct().ToList() @@ -650,16 +650,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv { await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false); } + else if (string.IsNullOrWhiteSpace(info.Etag)) + { + await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); + } else { - if (string.IsNullOrWhiteSpace(info.Etag) || !string.Equals(info.Etag, item.Etag, StringComparison.OrdinalIgnoreCase)) + // Increment this whenver some internal change deems it necessary + var etag = info.Etag + "1"; + + if (!string.Equals(etag, item.Etag, StringComparison.OrdinalIgnoreCase)) { - item.Etag = info.Etag; + item.Etag = etag; await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } } - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)); return item; } @@ -759,7 +766,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); } - _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions()); + _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)); return item.Id; } @@ -1163,6 +1170,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var program in channelPrograms) { var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false); + programs.Add(programItem.Id); } } @@ -2352,4 +2360,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv }); } } -} +} \ No newline at end of file diff --git a/SharedVersion.cs b/SharedVersion.cs index 36ee8dbfac..5b09ef0841 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5724.5")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5724.5")]