diff options
Diffstat (limited to 'Emby.Server.Implementations/LiveTv')
11 files changed, 126 insertions, 76 deletions
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 2e591711bc..5e0b4ff349 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -150,7 +150,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV foreach (var recordingFolder in recordingFolders) { var pathsToCreate = recordingFolder.Locations - .Where(i => !allExistingPaths.Contains(i, StringComparer.OrdinalIgnoreCase)) + .Where(i => !allExistingPaths.Any(p => _fileSystem.AreEqual(p, i))) .ToList(); if (pathsToCreate.Count == 0) @@ -1370,13 +1370,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV ActiveRecordingInfo removed; _activeRecordings.TryRemove(timer.Id, out removed); - if (recordingStatus != RecordingStatus.Completed && DateTime.UtcNow < timer.EndDate) + if (recordingStatus != RecordingStatus.Completed && DateTime.UtcNow < timer.EndDate && timer.RetryCount < 10) { const int retryIntervalSeconds = 60; _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds); timer.Status = RecordingStatus.New; timer.StartDate = DateTime.UtcNow.AddSeconds(retryIntervalSeconds); + timer.RetryCount++; _timerProvider.AddOrUpdate(timer); } else if (_fileSystem.FileExists(recordPath)) @@ -2106,13 +2107,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { return true; } - - if (!seriesTimer.Days.Contains(timer.StartDate.ToLocalTime().DayOfWeek)) - { - return true; - } } + //if (!seriesTimer.Days.Contains(timer.StartDate.ToLocalTime().DayOfWeek)) + //{ + // return true; + //} + if (seriesTimer.RecordNewOnly && timer.IsRepeat) { return true; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 5e55b893f3..beb08cc251 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -240,14 +240,49 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { try { - _logger.Info("Killing ffmpeg recording process for {0}", _targetPath); + _logger.Info("Stopping ffmpeg recording process for {0}", _targetPath); //process.Kill(); _process.StandardInput.WriteLine("q"); } catch (Exception ex) { - _logger.ErrorException("Error killing transcoding job for {0}", ex, _targetPath); + _logger.ErrorException("Error stopping recording transcoding job for {0}", ex, _targetPath); + } + + if (_hasExited) + { + return; + } + + try + { + _logger.Info("Calling recording process.WaitForExit for {0}", _targetPath); + + if (_process.WaitForExit(5000)) + { + return; + } + } + catch (Exception ex) + { + _logger.ErrorException("Error waiting for recording process to exit for {0}", ex, _targetPath); + } + + if (_hasExited) + { + return; + } + + try + { + _logger.Info("Killing ffmpeg recording process for {0}", _targetPath); + + _process.Kill(); + } + catch (Exception ex) + { + _logger.ErrorException("Error killing recording transcoding job for {0}", ex, _targetPath); } } } diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index e2446b16ff..46b9142328 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -182,7 +182,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings programsInfo.Add(GetProgram(channelNumber, schedule, programDict[schedule.programID])); } - _logger.Info("Finished with EPGData"); } } @@ -322,8 +321,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings using (var response = await Get(httpOptions, true, info).ConfigureAwait(false)) { var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response); - _logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect"); - _logger.Info("Mapping Stations to Channel"); + foreach (ScheduleDirect.Map map in root.map) { var channelNumber = map.logicalChannelNumber; @@ -353,7 +351,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings }); } } - _logger.Info("Added " + GetChannelPairCacheCount(listingsId) + " channels to the dictionary"); foreach (ChannelInfo channel in channels) { diff --git a/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs b/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs index a338ae23ae..0313e6fdec 100644 --- a/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs +++ b/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs @@ -96,15 +96,7 @@ namespace Emby.Server.Implementations.LiveTv } // Try to estimate this - if (!mediaSource.Bitrate.HasValue) - { - var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); - - if (total > 0) - { - mediaSource.Bitrate = total; - } - } + mediaSource.InferTotalBitrate(true); } } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 62a0738c72..ff76f6bef4 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -459,15 +459,7 @@ namespace Emby.Server.Implementations.LiveTv } // Set the total bitrate if not already supplied - if (!mediaSource.Bitrate.HasValue) - { - var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); - - if (total > 0) - { - mediaSource.Bitrate = total; - } - } + mediaSource.InferTotalBitrate(); if (!(service is EmbyTV.EmbyTV)) { @@ -1602,7 +1594,7 @@ namespace Emby.Server.Implementations.LiveTv Recursive = true, AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(), IsFolder = false, - ExcludeLocationTypes = new[] { LocationType.Virtual }, + IsVirtualItem = false, Limit = query.Limit, SortBy = new[] { ItemSortBy.DateCreated }, SortOrder = SortOrder.Descending, diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index e0a35686ec..dd95660c78 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -200,15 +200,7 @@ namespace Emby.Server.Implementations.LiveTv } // Try to estimate this - if (!mediaSource.Bitrate.HasValue) - { - var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); - - if (total > 0) - { - mediaSource.Bitrate = total; - } - } + mediaSource.InferTotalBitrate(); } public Task CloseMediaSource(string liveStreamId) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs index f2e48fbc0f..336469c500 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs @@ -104,7 +104,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Type = HdHomerunHost.DeviceType, Url = url, - DataVersion = 1, DeviceId = response.DeviceID }).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 77efe8585b..1c7c0828c3 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -61,10 +61,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var id = ChannelIdPrefix + i.GuideNumber; - if (info.DataVersion >= 1) - { - id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); - } + id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); return id; } @@ -103,7 +100,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun TunerHostId = info.Id, IsHD = i.HD == 1, AudioCodec = i.AudioCodec, - VideoCodec = i.VideoCodec + VideoCodec = i.VideoCodec, + ChannelType = ChannelType.TV }); } @@ -430,6 +428,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun IsInfiniteStream = true }; + mediaSource.InferTotalBitrate(); + return mediaSource; } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs index 4852270d5e..625e4457df 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs @@ -25,7 +25,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>(); private readonly MulticastStream _multicastStream; - public HdHomerunLiveStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost) : base(mediaSource) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 8027ce2dd7..601cb26661 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { - return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); + return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, !info.EnableTvgId, cancellationToken).ConfigureAwait(false); } public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) @@ -127,6 +127,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { protocol = MediaProtocol.Udp; } + else if (path.StartsWith("rtp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtmp; + } var mediaSource = new MediaSourceInfo { @@ -155,9 +159,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts ReadAtNativeFramerate = false, Id = channel.Path.GetMD5().ToString("N"), - IsInfiniteStream = true + IsInfiniteStream = true, + SupportsDirectStream = false, + IsRemote = true }; + mediaSource.InferTotalBitrate(); + return new List<MediaSourceInfo> { mediaSource }; } return new List<MediaSourceInfo>(); @@ -168,4 +176,4 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(true); } } -} +}
\ No newline at end of file diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index e0f0402813..5e191ada9f 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -14,6 +14,7 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.LiveTv.TunerHosts { @@ -32,14 +33,25 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts _appHost = appHost; } - public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken) + public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, bool enableStreamUrlAsIdentifier, CancellationToken cancellationToken) { var urlHash = url.GetMD5().ToString("N"); // Read the file and display it line by line. using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) { - return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId); + return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId, enableStreamUrlAsIdentifier); + } + } + + public List<M3UChannel> ParseString(string text, string channelIdPrefix, string tunerHostId) + { + var urlHash = "text".GetMD5().ToString("N"); + + // Read the file and display it line by line. + using (var reader = new StringReader(text)) + { + return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId, false); } } @@ -59,7 +71,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } const string ExtInfPrefix = "#EXTINF:"; - private List<M3UChannel> GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId) + private List<M3UChannel> GetChannels(TextReader reader, string urlHash, string channelIdPrefix, string tunerHostId, bool enableStreamUrlAsIdentifier) { var channels = new List<M3UChannel>(); string line; @@ -85,7 +97,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith("#", StringComparison.OrdinalIgnoreCase)) { var channel = GetChannelnfo(extInf, tunerHostId, line); - channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); + if (string.IsNullOrWhiteSpace(channel.Id) || enableStreamUrlAsIdentifier) + { + channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); + } + else + { + channel.Id = channelIdPrefix + urlHash + channel.Id.GetMD5().ToString("N"); + } + channel.Path = line; channels.Add(channel); extInf = ""; @@ -114,6 +134,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts channel.Name = GetChannelName(extInf, attributes); channel.Number = GetChannelNumber(extInf, attributes, mediaUrl); + if (attributes.TryGetValue("tvg-id", out value)) + { + channel.Id = value; + } + return channel; } @@ -122,18 +147,22 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; - var numberString = nameParts[0]; + string numberString = null; - //Check for channel number with the format from SatIp - int number; + // Check for channel number with the format from SatIp + // #EXTINF:0,84. VOX Schweiz + // #EXTINF:0,84.0 - VOX Schweiz if (!string.IsNullOrWhiteSpace(nameInExtInf)) { - var numberIndex = nameInExtInf.IndexOf('.'); + var numberIndex = nameInExtInf.IndexOf(' '); if (numberIndex > 0) { - if (int.TryParse(nameInExtInf.Substring(0, numberIndex), out number)) + var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); + + double number; + if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out number)) { - numberString = number.ToString(); + numberString = numberPart; } } } @@ -150,7 +179,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts string value; if (attributes.TryGetValue("tvg-id", out value)) { - numberString = value; + double doubleValue; + if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue)) + { + numberString = value; + } } } @@ -208,17 +241,21 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; - //Check for channel number with the format from SatIp - int number; + // Check for channel number with the format from SatIp + // #EXTINF:0,84. VOX Schweiz + // #EXTINF:0,84.0 - VOX Schweiz if (!string.IsNullOrWhiteSpace(nameInExtInf)) { - var numberIndex = nameInExtInf.IndexOf('.'); + var numberIndex = nameInExtInf.IndexOf(' '); if (numberIndex > 0) { - if (int.TryParse(nameInExtInf.Substring(0, numberIndex), out number)) + var numberPart = nameInExtInf.Substring(0, numberIndex).Trim(new[] { ' ', '.' }); + + double number; + if (double.TryParse(numberPart, NumberStyles.Any, CultureInfo.InvariantCulture, out number)) { //channel.Number = number.ToString(); - nameInExtInf = nameInExtInf.Substring(numberIndex + 1); + nameInExtInf = nameInExtInf.Substring(numberIndex + 1).Trim(new[] { ' ', '-' }); } } } @@ -250,20 +287,18 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); var matches = reg.Matches(line); - var minIndex = int.MaxValue; + + remaining = line; + foreach (Match match in matches) { - dict[match.Groups[1].Value] = match.Groups[2].Value; - minIndex = Math.Min(minIndex, match.Index); - } + var key = match.Groups[1].Value; + var value = match.Groups[2].Value; - if (minIndex > 0 && minIndex < line.Length) - { - line = line.Substring(0, minIndex); + dict[match.Groups[1].Value] = match.Groups[2].Value; + remaining = remaining.Replace(key + "=\"" + value + "\"", string.Empty, StringComparison.OrdinalIgnoreCase); } - remaining = line; - return dict; } } |
