mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-05-31 12:14:21 -04:00
restore changes
This commit is contained in:
parent
4e4bf3352d
commit
97d051e437
@ -8,7 +8,9 @@ using MediaBrowser.Controller.Drawing;
|
|||||||
using MediaBrowser.Controller.FileOrganization;
|
using MediaBrowser.Controller.FileOrganization;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Events;
|
using MediaBrowser.Model.Events;
|
||||||
@ -47,10 +49,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IProviderManager _providerManager;
|
private readonly IProviderManager _providerManager;
|
||||||
private readonly IFileOrganizationService _organizationService;
|
private readonly IFileOrganizationService _organizationService;
|
||||||
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
|
||||||
public static EmbyTV Current;
|
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;
|
Current = this;
|
||||||
|
|
||||||
@ -64,12 +67,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
_libraryMonitor = libraryMonitor;
|
_libraryMonitor = libraryMonitor;
|
||||||
_providerManager = providerManager;
|
_providerManager = providerManager;
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
|
_mediaEncoder = mediaEncoder;
|
||||||
_liveTvManager = (LiveTvManager)liveTvManager;
|
_liveTvManager = (LiveTvManager)liveTvManager;
|
||||||
_jsonSerializer = jsonSerializer;
|
_jsonSerializer = jsonSerializer;
|
||||||
|
|
||||||
_recordingProvider = new ItemDataProvider<RecordingInfo>(jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase));
|
_recordingProvider = new ItemDataProvider<RecordingInfo>(fileSystem, 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"));
|
_seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers"));
|
||||||
_timerProvider = new TimerManager(jsonSerializer, _logger, Path.Combine(DataPath, "timers"));
|
_timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"));
|
||||||
_timerProvider.TimerFired += _timerProvider_TimerFired;
|
_timerProvider.TimerFired += _timerProvider_TimerFired;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +130,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
|
{
|
||||||
|
var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
List<ChannelInfo> channels = null;
|
||||||
|
|
||||||
|
foreach (var timer in timers)
|
||||||
|
{
|
||||||
|
List<ProgramInfo> 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<ChannelInfo> _channelCache = null;
|
private List<ChannelInfo> _channelCache = null;
|
||||||
private async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken)
|
private async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(bool enableCache, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -235,7 +266,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Delete(remove.Path);
|
_fileSystem.DeleteFile(remove.Path);
|
||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
@ -364,33 +395,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerProvider.GetAll());
|
return Task.FromResult((IEnumerable<SeriesTimerInfo>)_seriesTimerProvider.GetAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress<double> progress)
|
|
||||||
{
|
|
||||||
var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
List<ChannelInfo> channels = null;
|
|
||||||
|
|
||||||
foreach (var timer in timers)
|
|
||||||
{
|
|
||||||
List<ProgramInfo> 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<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -469,6 +473,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
|
|
||||||
if (mediaSourceInfo != null)
|
if (mediaSourceInfo != null)
|
||||||
{
|
{
|
||||||
|
await AddMediaInfo(mediaSourceInfo, false, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
mediaSourceInfo.Id = Guid.NewGuid().ToString("N");
|
mediaSourceInfo.Id = Guid.NewGuid().ToString("N");
|
||||||
return mediaSourceInfo;
|
return mediaSourceInfo;
|
||||||
}
|
}
|
||||||
@ -499,6 +505,84 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
throw new NotImplementedException();
|
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<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -586,7 +670,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts";
|
var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts";
|
||||||
|
|
||||||
recordPath = Path.Combine(recordPath, recordingFileName);
|
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));
|
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);
|
_recordingProvider.Update(recording);
|
||||||
|
|
||||||
_logger.Info("Beginning recording.");
|
_logger.Info("Beginning recording.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
httpRequestOptions.BufferContent = false;
|
httpRequestOptions.BufferContent = false;
|
||||||
@ -640,7 +724,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
_logger.Info("Writing file to path: " + recordPath);
|
_logger.Info("Writing file to path: " + recordPath);
|
||||||
using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET"))
|
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);
|
await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken);
|
||||||
}
|
}
|
||||||
@ -801,7 +885,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
private void SaveEpgDataForChannel(string channelId, List<ProgramInfo> epgData)
|
private void SaveEpgDataForChannel(string channelId, List<ProgramInfo> epgData)
|
||||||
{
|
{
|
||||||
var path = GetChannelEpgCachePath(channelId);
|
var path = GetChannelEpgCachePath(channelId);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
lock (_epgLock)
|
lock (_epgLock)
|
||||||
{
|
{
|
||||||
_jsonSerializer.SerializeToFile(epgData, path);
|
_jsonSerializer.SerializeToFile(epgData, path);
|
||||||
@ -848,4 +932,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -362,8 +362,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
|||||||
|
|
||||||
private DateTime GetDate(string value)
|
private DateTime GetDate(string value)
|
||||||
{
|
{
|
||||||
return DateTime.ParseExact(value, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
|
var date = DateTime.ParseExact(value, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", CultureInfo.InvariantCulture);
|
||||||
CultureInfo.InvariantCulture);
|
|
||||||
|
if (date.Kind != DateTimeKind.Utc)
|
||||||
|
{
|
||||||
|
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
|
||||||
|
}
|
||||||
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetProgramLogo(string apiUrl, ScheduleDirect.ShowImages images)
|
private string GetProgramLogo(string apiUrl, ScheduleDirect.ShowImages images)
|
||||||
|
@ -580,7 +580,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
item.Name = channelInfo.Name;
|
item.Name = channelInfo.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
await item.RefreshMetadata(new MetadataRefreshOptions
|
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
|
||||||
{
|
{
|
||||||
ForceSave = isNew,
|
ForceSave = isNew,
|
||||||
ReplaceImages = replaceImages.Distinct().ToList()
|
ReplaceImages = replaceImages.Distinct().ToList()
|
||||||
@ -650,16 +650,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
{
|
{
|
||||||
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
else if (string.IsNullOrWhiteSpace(info.Etag))
|
||||||
|
{
|
||||||
|
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
else
|
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);
|
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions());
|
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem));
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -759,7 +766,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
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;
|
return item.Id;
|
||||||
}
|
}
|
||||||
@ -1163,6 +1170,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
foreach (var program in channelPrograms)
|
foreach (var program in channelPrograms)
|
||||||
{
|
{
|
||||||
var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
|
var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
programs.Add(programItem.Id);
|
programs.Add(programItem.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2352,4 +2360,4 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
//[assembly: AssemblyVersion("3.0.*")]
|
[assembly: AssemblyVersion("3.0.*")]
|
||||||
[assembly: AssemblyVersion("3.0.5724.5")]
|
//[assembly: AssemblyVersion("3.0.5724.5")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user