Merge pull request #2182 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-09-20 15:44:09 -04:00 committed by GitHub
commit d61258f290
11 changed files with 176 additions and 34 deletions

View File

@ -1453,7 +1453,8 @@ namespace MediaBrowser.Api.Playback
// Make sure we don't request a bitrate higher than the source // Make sure we don't request a bitrate higher than the source
var currentBitrate = audioStream == null ? request.AudioBitRate.Value : audioStream.BitRate ?? request.AudioBitRate.Value; var currentBitrate = audioStream == null ? request.AudioBitRate.Value : audioStream.BitRate ?? request.AudioBitRate.Value;
return request.AudioBitRate.Value; // Don't encode any higher than this
return Math.Min(384000, request.AudioBitRate.Value);
//return Math.Min(currentBitrate, request.AudioBitRate.Value); //return Math.Min(currentBitrate, request.AudioBitRate.Value);
} }

View File

@ -113,6 +113,8 @@ namespace MediaBrowser.Api.Playback.Hls
args += GetGraphicalSubtitleParam(state, codec); args += GetGraphicalSubtitleParam(state, codec);
} }
args += " -flags -global_header";
return args; return args;
} }

View File

@ -1,10 +1,16 @@
using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.LiveTv;
using System; using System;
using System.Collections.Generic;
namespace MediaBrowser.Controller.LiveTv namespace MediaBrowser.Controller.LiveTv
{ {
public class TimerInfo public class TimerInfo
{ {
public TimerInfo()
{
Genres = new List<string>();
}
/// <summary> /// <summary>
/// Id of the recording. /// Id of the recording.
/// </summary> /// </summary>
@ -15,7 +21,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary> /// </summary>
/// <value>The series timer identifier.</value> /// <value>The series timer identifier.</value>
public string SeriesTimerId { get; set; } public string SeriesTimerId { get; set; }
/// <summary> /// <summary>
/// ChannelId of the recording. /// ChannelId of the recording.
/// </summary> /// </summary>
@ -26,7 +32,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary> /// </summary>
/// <value>The program identifier.</value> /// <value>The program identifier.</value>
public string ProgramId { get; set; } public string ProgramId { get; set; }
/// <summary> /// <summary>
/// Name of the recording. /// Name of the recording.
/// </summary> /// </summary>
@ -76,7 +82,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary> /// </summary>
/// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value>
public bool IsPostPaddingRequired { get; set; } public bool IsPostPaddingRequired { get; set; }
/// <summary> /// <summary>
/// Gets or sets the priority. /// Gets or sets the priority.
/// </summary> /// </summary>
@ -98,5 +104,10 @@ namespace MediaBrowser.Controller.LiveTv
public string EpisodeTitle { get; set; } public string EpisodeTitle { get; set; }
public DateTime? OriginalAirDate { get; set; } public DateTime? OriginalAirDate { get; set; }
public bool IsProgramSeries { get; set; } public bool IsProgramSeries { get; set; }
public string HomePageUrl { get; set; }
public float? CommunityRating { get; set; }
public string ShortOverview { get; set; }
public string OfficialRating { get; set; }
public List<string> Genres { get; set; }
} }
} }

View File

@ -393,6 +393,20 @@ namespace MediaBrowser.MediaEncoding.Probing
}; };
} }
private string NormalizeSubtitleCodec(string codec)
{
if ((codec ?? string.Empty).IndexOf("PGS", StringComparison.OrdinalIgnoreCase) != -1)
{
codec = "PGSSUB";
}
else if ((codec ?? string.Empty).IndexOf("DVD", StringComparison.OrdinalIgnoreCase) != -1)
{
codec = "DVDSUB";
}
return codec;
}
/// <summary> /// <summary>
/// Converts ffprobe stream info to our MediaStream class /// Converts ffprobe stream info to our MediaStream class
/// </summary> /// </summary>
@ -474,6 +488,7 @@ namespace MediaBrowser.MediaEncoding.Probing
else if (string.Equals(streamInfo.codec_type, "subtitle", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(streamInfo.codec_type, "subtitle", StringComparison.OrdinalIgnoreCase))
{ {
stream.Type = MediaStreamType.Subtitle; stream.Type = MediaStreamType.Subtitle;
stream.Codec = NormalizeSubtitleCodec(stream.Codec);
} }
else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase))
{ {

View File

@ -609,26 +609,13 @@ namespace MediaBrowser.Model.Dlna
defaultBitrate = StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3") ? 192000 : 128000; defaultBitrate = StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3") ? 192000 : 128000;
} }
if (targetAudioChannels.HasValue) if (StringHelper.EqualsIgnoreCase(subProtocol, "hls"))
{ {
if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1200000) defaultBitrate = Math.Min(384000, defaultBitrate);
{ }
if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3")) else
{ {
if (StringHelper.EqualsIgnoreCase(subProtocol, "hls")) defaultBitrate = Math.Min(448000, defaultBitrate);
{
defaultBitrate = Math.Max(384000, defaultBitrate);
}
else
{
defaultBitrate = Math.Max(448000, defaultBitrate);
}
}
else
{
defaultBitrate = Math.Max(320000, defaultBitrate);
}
}
} }
int encoderAudioBitrateLimit = int.MaxValue; int encoderAudioBitrateLimit = int.MaxValue;
@ -647,6 +634,14 @@ namespace MediaBrowser.Model.Dlna
} }
} }
if (maxTotalBitrate.HasValue)
{
if (maxTotalBitrate.Value < 640000)
{
defaultBitrate = Math.Min(128000, defaultBitrate);
}
}
return Math.Min(defaultBitrate, encoderAudioBitrateLimit); return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
} }

View File

@ -12,6 +12,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Implementations.ScheduledTasks; using MediaBrowser.Server.Implementations.ScheduledTasks;
using MoreLinq;
namespace MediaBrowser.Server.Implementations.IO namespace MediaBrowser.Server.Implementations.IO
{ {
@ -136,9 +137,10 @@ namespace MediaBrowser.Server.Implementations.IO
private async Task ProcessPathChanges(List<string> paths) private async Task ProcessPathChanges(List<string> paths)
{ {
var itemsToRefresh = paths var itemsToRefresh = paths
.Distinct(StringComparer.OrdinalIgnoreCase)
.Select(GetAffectedBaseItem) .Select(GetAffectedBaseItem)
.Where(item => item != null) .Where(item => item != null)
.Distinct() .DistinctBy(i => i.Id)
.ToList(); .ToList();
foreach (var p in paths) foreach (var p in paths)

View File

@ -404,7 +404,20 @@ namespace MediaBrowser.Server.Implementations.IO
{ {
Logger.Debug("Changed detected of type " + e.ChangeType + " to " + e.FullPath); Logger.Debug("Changed detected of type " + e.ChangeType + " to " + e.FullPath);
ReportFileSystemChanged(e.FullPath); var path = e.FullPath;
// For deletes, use the parent path
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
var parentPath = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(parentPath))
{
path = parentPath;
}
}
ReportFileSystemChanged(path);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -89,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return false; return false;
} }
if (IgnoreFiles.Any(i => filename.IndexOf("-" + i, StringComparison.OrdinalIgnoreCase) != -1)) if (IgnoreFiles.Any(i => filename.IndexOf(i, StringComparison.OrdinalIgnoreCase) != -1))
{ {
return false; return false;
} }

View File

@ -27,6 +27,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml; using System.Xml;
using CommonIO; using CommonIO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
@ -1026,6 +1027,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
result.Item3.Release(); result.Item3.Release();
isResourceOpen = false; isResourceOpen = false;
SaveNfo(timer, recordPath, seriesPath);
}; };
var pathWithDuration = result.Item2.ApplyDuration(mediaStreamInfo.Path, duration); var pathWithDuration = result.Item2.ApplyDuration(mediaStreamInfo.Path, duration);
@ -1071,7 +1074,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
timer.Status = RecordingStatus.Completed; timer.Status = RecordingStatus.Completed;
_timerProvider.Delete(timer); _timerProvider.Delete(timer);
OnSuccessfulRecording(timer, recordPath, seriesPath); OnSuccessfulRecording(timer, recordPath);
} }
else if (DateTime.UtcNow < timer.EndDate) else if (DateTime.UtcNow < timer.EndDate)
{ {
@ -1139,7 +1142,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
return new DirectRecorder(_logger, _httpClient, _fileSystem); return new DirectRecorder(_logger, _httpClient, _fileSystem);
} }
private async void OnSuccessfulRecording(TimerInfo timer, string path, string seriesPath) private async void OnSuccessfulRecording(TimerInfo timer, string path)
{ {
if (timer.IsProgramSeries && GetConfiguration().EnableAutoOrganize) if (timer.IsProgramSeries && GetConfiguration().EnableAutoOrganize)
{ {
@ -1163,15 +1166,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_logger.ErrorException("Error processing new recording", ex); _logger.ErrorException("Error processing new recording", ex);
} }
} }
SaveNfo(timer, path, seriesPath);
} }
private void SaveNfo(TimerInfo timer, string recordingPath, string seriesPath) private void SaveNfo(TimerInfo timer, string recordingPath, string seriesPath)
{ {
if (timer.IsProgramSeries) try
{ {
SaveSeriesNfo(timer, recordingPath, seriesPath); if (timer.IsProgramSeries)
{
SaveSeriesNfo(timer, recordingPath, seriesPath);
}
else if (!timer.IsMovie || timer.IsSports)
{
SaveVideoNfo(timer, recordingPath);
}
}
catch (Exception ex)
{
_logger.ErrorException("Error saving nfo", ex);
} }
} }
@ -1209,6 +1221,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
} }
} }
public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
private void SaveVideoNfo(TimerInfo timer, string recordingPath)
{
var nfoPath = Path.ChangeExtension(recordingPath, ".nfo");
if (File.Exists(nfoPath))
{
return;
}
using (var stream = _fileSystem.GetFileStream(nfoPath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
var settings = new XmlWriterSettings
{
Indent = true,
Encoding = Encoding.UTF8,
CloseOutput = false
};
using (XmlWriter writer = XmlWriter.Create(stream, settings))
{
writer.WriteStartDocument(true);
writer.WriteStartElement("movie");
if (!string.IsNullOrWhiteSpace(timer.Name))
{
writer.WriteElementString("title", timer.Name);
}
writer.WriteElementString("dateadded", DateTime.UtcNow.ToLocalTime().ToString(DateAddedFormat));
if (timer.ProductionYear.HasValue)
{
writer.WriteElementString("year", timer.ProductionYear.Value.ToString(CultureInfo.InvariantCulture));
}
if (!string.IsNullOrEmpty(timer.OfficialRating))
{
writer.WriteElementString("mpaa", timer.OfficialRating);
}
var overview = (timer.Overview ?? string.Empty)
.StripHtml()
.Replace("&quot;", "'");
writer.WriteElementString("plot", overview);
writer.WriteElementString("lockdata", true.ToString().ToLower());
if (timer.CommunityRating.HasValue)
{
writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
}
foreach (var genre in timer.Genres)
{
writer.WriteElementString("genre", genre);
}
if (!string.IsNullOrWhiteSpace(timer.ShortOverview))
{
writer.WriteElementString("outline", timer.ShortOverview);
}
if (!string.IsNullOrWhiteSpace(timer.HomePageUrl))
{
writer.WriteElementString("website", timer.HomePageUrl);
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
}
private ProgramInfo GetProgramInfoFromCache(string channelId, string programId) private ProgramInfo GetProgramInfoFromCache(string channelId, string programId)
{ {
var epgData = GetEpgDataForChannel(channelId); var epgData = GetEpgDataForChannel(channelId);

View File

@ -46,6 +46,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
timerInfo.EpisodeTitle = programInfo.EpisodeTitle; timerInfo.EpisodeTitle = programInfo.EpisodeTitle;
timerInfo.OriginalAirDate = programInfo.OriginalAirDate; timerInfo.OriginalAirDate = programInfo.OriginalAirDate;
timerInfo.IsProgramSeries = programInfo.IsSeries; timerInfo.IsProgramSeries = programInfo.IsSeries;
timerInfo.HomePageUrl = programInfo.HomePageUrl;
timerInfo.CommunityRating = programInfo.CommunityRating;
timerInfo.ShortOverview = programInfo.ShortOverview;
timerInfo.OfficialRating = programInfo.OfficialRating;
} }
public static string GetRecordingName(TimerInfo info) public static string GetRecordingName(TimerInfo info)

View File

@ -171,7 +171,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
var data = images[imageIndex].data ?? new List<ScheduleDirect.ImageData>(); var data = images[imageIndex].data ?? new List<ScheduleDirect.ImageData>();
data = data.OrderByDescending(GetSizeOrder).ToList(); data = data.OrderByDescending(GetSizeOrder).ToList();
programEntry.primaryImage = GetProgramImage(ApiUrl, data, "Logo", true, 1280); programEntry.primaryImage = GetProgramImage(ApiUrl, data, "Logo", true, 800);
//programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false); //programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false);
//programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ?? //programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ?? // GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
@ -536,7 +536,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
} }
return false; return false;
}) ?? matches.FirstOrDefault(); });
if (match == null)
{
// Get the second lowest quality image, when possible
if (matches.Count > 1)
{
match = matches[matches.Count - 2];
}
else
{
match = matches.FirstOrDefault();
}
}
if (match == null) if (match == null)
{ {