mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-31 12:58:28 +01:00
Merge remote-tracking branch 'upstream/master' into do-not-instantiate-services-at-startup
This commit is contained in:
@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Channels
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{DynamicImageInfo}.</returns>
|
||||
/// <returns>Task{DynamicImageResponse}.</returns>
|
||||
Task<DynamicImageResponse> GetChannelImage(ImageType type, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Chapters
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IChapterManager
|
||||
/// Interface IChapterManager.
|
||||
/// </summary>
|
||||
public interface IChapterManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
/// </summary>
|
||||
void SaveChapters(string itemId, List<ChapterInfo> chapters);
|
||||
void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
@@ -178,6 +177,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
public int? TotalBitrate { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ExtraType? ExtraType { get; set; }
|
||||
|
||||
@@ -2190,13 +2190,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Do whatever refreshing is necessary when the filesystem pertaining to this item has changed.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public virtual void ChangedExternally()
|
||||
{
|
||||
ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(new DirectoryService(FileSystem))
|
||||
{
|
||||
|
||||
}, RefreshPriority.High);
|
||||
ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(new DirectoryService(FileSystem)), RefreshPriority.High);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2227,7 +2223,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
existingImage.Width = image.Width;
|
||||
existingImage.Height = image.Height;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var current = ImageInfos;
|
||||
@@ -2270,7 +2265,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public void DeleteImage(ImageType type, int index)
|
||||
{
|
||||
var info = GetImageInfo(type, index);
|
||||
@@ -2308,7 +2302,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that images within the item are still on the file system
|
||||
/// Validates that images within the item are still on the filesystem.
|
||||
/// </summary>
|
||||
public bool ValidateImages(IDirectoryService directoryService)
|
||||
{
|
||||
@@ -2602,7 +2596,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true if changes were made.
|
||||
/// </summary>
|
||||
public virtual bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
@@ -2662,36 +2656,43 @@ namespace MediaBrowser.Controller.Entities
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.Genres = item.Genres;
|
||||
}
|
||||
|
||||
if (!item.Studios.SequenceEqual(ownedItem.Studios, StringComparer.Ordinal))
|
||||
{
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.Studios = item.Studios;
|
||||
}
|
||||
|
||||
if (!item.ProductionLocations.SequenceEqual(ownedItem.ProductionLocations, StringComparer.Ordinal))
|
||||
{
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.ProductionLocations = item.ProductionLocations;
|
||||
}
|
||||
|
||||
if (item.CommunityRating != ownedItem.CommunityRating)
|
||||
{
|
||||
ownedItem.CommunityRating = item.CommunityRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (item.CriticRating != ownedItem.CriticRating)
|
||||
{
|
||||
ownedItem.CriticRating = item.CriticRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.Overview, ownedItem.Overview, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.Overview = item.Overview;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.OfficialRating, ownedItem.OfficialRating, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.OfficialRating = item.OfficialRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.CustomRating, ownedItem.CustomRating, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.CustomRating = item.CustomRating;
|
||||
@@ -2883,7 +2884,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public IEnumerable<BaseItem> GetExtras(IReadOnlyCollection<ExtraType> extraTypes)
|
||||
{
|
||||
return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i != null && extraTypes.Contains(i.ExtraType.Value));
|
||||
return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i?.ExtraType != null && extraTypes.Contains(i.ExtraType.Value));
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTrailers()
|
||||
@@ -2900,11 +2901,17 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
public virtual bool IsHD => Height >= 720;
|
||||
|
||||
public bool IsShortcut { get; set; }
|
||||
|
||||
public string ShortcutPath { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public Guid[] ExtraIds { get; set; }
|
||||
|
||||
public virtual long GetRunTimeTicksForPlayState()
|
||||
{
|
||||
return RunTimeTicks ?? 0;
|
||||
|
||||
@@ -13,8 +13,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid SeriesId { get; set; }
|
||||
|
||||
@@ -22,10 +24,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
return SeriesPresentationUniqueKey;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -28,7 +30,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class Folder : BaseItem
|
||||
{
|
||||
public static IUserManager UserManager { get; set; }
|
||||
public static IUserViewManager UserViewManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -620,7 +621,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
EnableImages = false
|
||||
}
|
||||
|
||||
}).TotalRecordCount;
|
||||
}
|
||||
|
||||
@@ -1713,7 +1713,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
EnableImages = false
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
double unplayedCount = unplayedQueryResult.TotalRecordCount;
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface
|
||||
/// Marker interface.
|
||||
/// </summary>
|
||||
public interface IItemByName
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Extensions
|
||||
public const string PlaylistsAllowDuplicatesKey = "playlists:allowDuplicates";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the application should not host static web content from the <see cref="IConfiguration"/>.
|
||||
/// Gets a value indicating whether the application should host static web content from the <see cref="IConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to retrieve the value from.</param>
|
||||
/// <returns>The parsed config value.</returns>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -460,16 +460,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
if (state.IsVideoRequest
|
||||
&& string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
|
||||
var hwOutputFormat = "vaapi";
|
||||
|
||||
if (hasGraphicalSubs)
|
||||
{
|
||||
hwOutputFormat = "yuv420p";
|
||||
}
|
||||
|
||||
arg.Append("-hwaccel vaapi -hwaccel_output_format ")
|
||||
.Append(hwOutputFormat)
|
||||
arg.Append("-hwaccel vaapi -hwaccel_output_format vaapi")
|
||||
.Append(" -vaapi_device ")
|
||||
.Append(encodingOptions.VaapiDevice)
|
||||
.Append(' ');
|
||||
@@ -480,20 +471,26 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions);
|
||||
var outputVideoCodec = GetVideoEncoder(state, encodingOptions);
|
||||
|
||||
var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
|
||||
|
||||
if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
||||
if (!hasTextSubs)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))
|
||||
// While using QSV encoder
|
||||
if ((outputVideoCodec ?? string.Empty).IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
arg.Append("-hwaccel qsv ");
|
||||
}
|
||||
else
|
||||
{
|
||||
arg.Append("-init_hw_device qsv=hw -filter_hw_device hw ");
|
||||
// While using QSV decoder
|
||||
if ((videoDecoder ?? string.Empty).IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
arg.Append("-hwaccel qsv ");
|
||||
}
|
||||
// While using SW decoder
|
||||
else
|
||||
{
|
||||
arg.Append("-init_hw_device qsv=hw -filter_hw_device hw ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arg.Append(videoDecoder + " ");
|
||||
}
|
||||
|
||||
arg.Append("-i ")
|
||||
@@ -503,17 +500,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode
|
||||
&& state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
|
||||
{
|
||||
if (state.VideoStream != null && state.VideoStream.Width.HasValue)
|
||||
{
|
||||
// This is hacky but not sure how to get the exact subtitle resolution
|
||||
int height = Convert.ToInt32(state.VideoStream.Width.Value / 16.0 * 9.0);
|
||||
|
||||
arg.Append(" -canvas_size ")
|
||||
.Append(state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture))
|
||||
.Append(':')
|
||||
.Append(height.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
var subtitlePath = state.SubtitleStream.Path;
|
||||
|
||||
if (string.Equals(Path.GetExtension(subtitlePath), ".sub", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1546,9 +1532,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal graphical subtitle param.
|
||||
/// Gets the graphical subtitle param.
|
||||
/// </summary>
|
||||
public string GetGraphicalSubtitleParam(EncodingJobInfo state, EncodingOptions options, string outputVideoCodec)
|
||||
public string GetGraphicalSubtitleParam(
|
||||
EncodingJobInfo state,
|
||||
EncodingOptions options,
|
||||
string outputVideoCodec)
|
||||
{
|
||||
var outputSizeParam = string.Empty;
|
||||
|
||||
@@ -1562,53 +1551,77 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"');
|
||||
|
||||
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
|
||||
var index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase);
|
||||
if (index != -1)
|
||||
{
|
||||
var index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
|
||||
if (index != -1)
|
||||
{
|
||||
outputSizeParam = "," + outputSizeParam.Substring(index);
|
||||
}
|
||||
outputSizeParam = "," + outputSizeParam.Substring(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
var index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase);
|
||||
index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase);
|
||||
if (index != -1)
|
||||
{
|
||||
outputSizeParam = "," + outputSizeParam.Substring(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
|
||||
&& outputSizeParam.Length == 0)
|
||||
{
|
||||
outputSizeParam = ",format=nv12|vaapi,hwupload";
|
||||
|
||||
// Add parameters to use VAAPI with burn-in subttiles (GH issue #642)
|
||||
if (state.SubtitleStream != null
|
||||
&& state.SubtitleStream.IsTextSubtitleStream
|
||||
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode) {
|
||||
outputSizeParam += ",hwmap=mode=read+write+direct";
|
||||
else
|
||||
{
|
||||
index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase);
|
||||
if (index != -1)
|
||||
{
|
||||
outputSizeParam = "," + outputSizeParam.Substring(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase);
|
||||
if (index != -1)
|
||||
{
|
||||
outputSizeParam = "," + outputSizeParam.Substring(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var videoSizeParam = string.Empty;
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
||||
|
||||
// Setup subtitle scaling
|
||||
if (state.VideoStream != null && state.VideoStream.Width.HasValue && state.VideoStream.Height.HasValue)
|
||||
{
|
||||
// force_original_aspect_ratio=decrease
|
||||
// Enable decreasing output video width or height if necessary to keep the original aspect ratio
|
||||
videoSizeParam = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"scale={0}:{1}",
|
||||
"scale={0}:{1}:force_original_aspect_ratio=decrease",
|
||||
state.VideoStream.Width.Value,
|
||||
state.VideoStream.Height.Value);
|
||||
|
||||
//For QSV, feed it into hardware encoder now
|
||||
// For QSV, feed it into hardware encoder now
|
||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
videoSizeParam += ",hwupload=extra_hw_frames=64";
|
||||
}
|
||||
|
||||
// For VAAPI and CUVID decoder
|
||||
// these encoders cannot automatically adjust the size of graphical subtitles to fit the output video,
|
||||
// thus needs to be manually adjusted.
|
||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
|
||||
|| (videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
var videoStream = state.VideoStream;
|
||||
var inputWidth = videoStream?.Width;
|
||||
var inputHeight = videoStream?.Height;
|
||||
var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
|
||||
|
||||
if (width.HasValue && height.HasValue)
|
||||
{
|
||||
videoSizeParam = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"scale={0}:{1}:force_original_aspect_ratio=decrease",
|
||||
width.Value,
|
||||
height.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mapPrefix = state.SubtitleStream.IsExternal ?
|
||||
@@ -1619,12 +1632,34 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
? 0
|
||||
: state.SubtitleStream.Index;
|
||||
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
||||
|
||||
// Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference)
|
||||
var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\"";
|
||||
|
||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
// When the input may or may not be hardware VAAPI decodable
|
||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase) && options.EnableHardwareEncoding)
|
||||
{
|
||||
/*
|
||||
[base]: HW scaling video to OutputSize
|
||||
[sub]: SW scaling subtitle to FixedOutputSize
|
||||
[base][sub]: SW overlay
|
||||
*/
|
||||
outputSizeParam = outputSizeParam.TrimStart(',');
|
||||
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3},hwdownload[base];[base][sub]overlay,format=nv12,hwupload\"";
|
||||
}
|
||||
|
||||
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
|
||||
else if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase) && !options.EnableHardwareEncoding)
|
||||
{
|
||||
/*
|
||||
[base]: SW scaling video to OutputSize
|
||||
[sub]: SW scaling subtitle to FixedOutputSize
|
||||
[base][sub]: SW overlay
|
||||
*/
|
||||
outputSizeParam = outputSizeParam.TrimStart(',');
|
||||
retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay\"";
|
||||
}
|
||||
|
||||
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
/*
|
||||
QSV in FFMpeg can now setup hardware overlay for transcodes.
|
||||
@@ -1688,7 +1723,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
return (Convert.ToInt32(outputWidth), Convert.ToInt32(outputHeight));
|
||||
}
|
||||
|
||||
public List<string> GetScalingFilters(int? videoWidth,
|
||||
public List<string> GetScalingFilters(EncodingJobInfo state,
|
||||
int? videoWidth,
|
||||
int? videoHeight,
|
||||
Video3DFormat? threedFormat,
|
||||
string videoDecoder,
|
||||
@@ -1707,7 +1743,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
requestedMaxWidth,
|
||||
requestedMaxHeight);
|
||||
|
||||
if ((string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) || string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
|
||||
|
||||
if (string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) || (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) && !hasTextSubs)
|
||||
&& width.HasValue
|
||||
&& height.HasValue)
|
||||
{
|
||||
@@ -1737,7 +1775,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv));
|
||||
}
|
||||
}
|
||||
else if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1
|
||||
else if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1
|
||||
&& width.HasValue
|
||||
&& height.HasValue)
|
||||
{
|
||||
@@ -1941,8 +1979,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
public string GetOutputSizeParam(
|
||||
EncodingJobInfo state,
|
||||
EncodingOptions options,
|
||||
string outputVideoCodec,
|
||||
bool allowTimeStampCopy = true)
|
||||
string outputVideoCodec)
|
||||
{
|
||||
// http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/
|
||||
|
||||
@@ -1951,42 +1988,57 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var videoStream = state.VideoStream;
|
||||
var filters = new List<string>();
|
||||
|
||||
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
|
||||
var hwType = options.HardwareAccelerationType ?? string.Empty;
|
||||
if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !options.EnableHardwareEncoding )
|
||||
{
|
||||
filters.Add("hwdownload");
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
||||
var inputWidth = videoStream?.Width;
|
||||
var inputHeight = videoStream?.Height;
|
||||
var threeDFormat = state.MediaSource.Video3DFormat;
|
||||
|
||||
// If transcoding from 10 bit, transform colour spaces too
|
||||
if (!string.IsNullOrEmpty(videoStream.PixelFormat)
|
||||
&& videoStream.PixelFormat.IndexOf("p10", StringComparison.OrdinalIgnoreCase) != -1
|
||||
&& string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
filters.Add("format=p010le");
|
||||
filters.Add("format=nv12");
|
||||
}
|
||||
else
|
||||
{
|
||||
filters.Add("format=nv12");
|
||||
}
|
||||
}
|
||||
var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
|
||||
|
||||
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
|
||||
// When the input may or may not be hardware VAAPI decodable
|
||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase) && options.EnableHardwareEncoding)
|
||||
{
|
||||
filters.Add("format=nv12|vaapi");
|
||||
filters.Add("hwupload");
|
||||
}
|
||||
|
||||
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options);
|
||||
|
||||
// If we are software decoding, and hardware encoding
|
||||
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)
|
||||
&& (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)))
|
||||
// When the input may or may not be hardware QSV decodable
|
||||
else if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) && options.EnableHardwareEncoding)
|
||||
{
|
||||
filters.Add("format=nv12|qsv");
|
||||
filters.Add("hwupload=extra_hw_frames=64");
|
||||
if (!hasTextSubs)
|
||||
{
|
||||
filters.Add("format=nv12|qsv");
|
||||
filters.Add("hwupload=extra_hw_frames=64");
|
||||
}
|
||||
}
|
||||
|
||||
// If we're hardware VAAPI decoding and software encoding, download frames from the decoder first
|
||||
|
||||
else if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase) && !options.EnableHardwareEncoding)
|
||||
{
|
||||
var codec = videoStream.Codec.ToLowerInvariant();
|
||||
var pixelFormat = videoStream.PixelFormat.ToLowerInvariant();
|
||||
|
||||
// Assert 10-bit hardware VAAPI decodable
|
||||
if ((pixelFormat ?? string.Empty).IndexOf("p10", StringComparison.OrdinalIgnoreCase) != -1
|
||||
&& (string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codec, "vp9", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
filters.Add("hwdownload");
|
||||
filters.Add("format=p010le");
|
||||
filters.Add("format=nv12");
|
||||
}
|
||||
|
||||
// Assert 8-bit hardware VAAPI decodable
|
||||
else if ((pixelFormat ?? string.Empty).IndexOf("p10", StringComparison.OrdinalIgnoreCase) == -1)
|
||||
{
|
||||
filters.Add("hwdownload");
|
||||
filters.Add("format=nv12");
|
||||
}
|
||||
}
|
||||
|
||||
// Add hardware deinterlace filter before scaling filter
|
||||
if (state.DeInterlace("h264", true))
|
||||
{
|
||||
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -1995,17 +2047,23 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_qsv"));
|
||||
if (!hasTextSubs)
|
||||
{
|
||||
filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_qsv"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true))
|
||||
&& !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
|
||||
// Add software deinterlace filter before scaling filter
|
||||
if (((state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true))
|
||||
&& !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
|
||||
&& !string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
|
||||
|| (hasTextSubs && state.DeInterlace("h264", true) && string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var inputFramerate = videoStream?.RealFrameRate;
|
||||
|
||||
// If it is already 60fps then it will create an output framerate that is much too high for roku and others to handle
|
||||
if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase) && (inputFramerate ?? 60) <= 30)
|
||||
if (string.Equals(options.DeinterlaceMethod, "yadif_bob", StringComparison.OrdinalIgnoreCase) && (inputFramerate ?? 60) <= 30)
|
||||
{
|
||||
filters.Add("yadif=1:-1:0");
|
||||
}
|
||||
@@ -2015,11 +2073,21 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
}
|
||||
|
||||
var inputWidth = videoStream?.Width;
|
||||
var inputHeight = videoStream?.Height;
|
||||
var threeDFormat = state.MediaSource.Video3DFormat;
|
||||
// Add scaling filter: scale_*=format=nv12 or scale_*=w=*:h=*:format=nv12 or scale=expr
|
||||
filters.AddRange(GetScalingFilters(state, inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight));
|
||||
|
||||
filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight));
|
||||
// Add parameters to use VAAPI with burn-in text subttiles (GH issue #642)
|
||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase) && options.EnableHardwareEncoding)
|
||||
{
|
||||
if (state.SubtitleStream != null
|
||||
&& state.SubtitleStream.IsTextSubtitleStream
|
||||
&& state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
|
||||
{
|
||||
// Test passed on Intel and AMD gfx
|
||||
filters.Add("hwmap=mode=read+write");
|
||||
filters.Add("format=nv12");
|
||||
}
|
||||
}
|
||||
|
||||
var output = string.Empty;
|
||||
|
||||
@@ -2037,11 +2105,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
filters.Add("hwmap");
|
||||
}
|
||||
|
||||
if (allowTimeStampCopy)
|
||||
{
|
||||
output += " -copyts";
|
||||
}
|
||||
}
|
||||
|
||||
if (filters.Count > 0)
|
||||
@@ -2218,7 +2281,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
inputModifier += " " + videoDecoder;
|
||||
|
||||
if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
var videoStream = state.VideoStream;
|
||||
var inputWidth = videoStream?.Width;
|
||||
@@ -2227,7 +2290,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
var (width, height) = GetFixedOutputSize(inputWidth, inputHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
|
||||
|
||||
if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1
|
||||
if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1
|
||||
&& width.HasValue
|
||||
&& height.HasValue)
|
||||
{
|
||||
@@ -2525,6 +2588,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
case "h264":
|
||||
if (_mediaEncoder.SupportsDecoder("h264_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
// cuvid decoder does not support 10-bit input
|
||||
if ((videoStream.BitDepth ?? 8) > 8)
|
||||
{
|
||||
encodingOptions.HardwareDecodingCodecs = Array.Empty<string>();
|
||||
return null;
|
||||
}
|
||||
return "-c:v h264_cuvid ";
|
||||
}
|
||||
break;
|
||||
@@ -2637,7 +2706,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
if(Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor > 1))
|
||||
if (Environment.OSVersion.Version.Major > 6 || (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor > 1))
|
||||
return "-hwaccel d3d11va";
|
||||
else
|
||||
return "-hwaccel dxva2";
|
||||
@@ -2772,14 +2841,27 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
|
||||
|
||||
var hasCopyTs = false;
|
||||
|
||||
// Add resolution params, if specified
|
||||
if (!hasGraphicalSubs)
|
||||
{
|
||||
var outputSizeParam = GetOutputSizeParam(state, encodingOptions, videoCodec);
|
||||
|
||||
args += outputSizeParam;
|
||||
|
||||
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
}
|
||||
|
||||
// This is for graphical subs
|
||||
if (hasGraphicalSubs)
|
||||
{
|
||||
var graphicalSubtitleParam = GetGraphicalSubtitleParam(state, encodingOptions, videoCodec);
|
||||
|
||||
args += graphicalSubtitleParam;
|
||||
|
||||
hasCopyTs = graphicalSubtitleParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
}
|
||||
|
||||
if (state.RunTimeTicks.HasValue && state.BaseRequest.CopyTimestamps)
|
||||
{
|
||||
if (!hasCopyTs)
|
||||
@@ -2787,13 +2869,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
args += " -copyts";
|
||||
}
|
||||
|
||||
args += " -avoid_negative_ts disabled -start_at_zero";
|
||||
}
|
||||
args += " -avoid_negative_ts disabled";
|
||||
|
||||
// This is for internal graphical subs
|
||||
if (hasGraphicalSubs)
|
||||
{
|
||||
args += GetGraphicalSubtitleParam(state, encodingOptions, videoCodec);
|
||||
if (!(state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream))
|
||||
{
|
||||
args += " -start_at_zero";
|
||||
}
|
||||
}
|
||||
|
||||
var qualityParam = GetVideoQualityParam(state, videoCodec, encodingOptions, defaultPreset);
|
||||
@@ -2899,6 +2980,5 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
string.Empty,
|
||||
string.Empty).Trim();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.Session;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -12,6 +14,6 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <summary>
|
||||
/// Refreshes the chapter images.
|
||||
/// </summary>
|
||||
Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, List<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken);
|
||||
Task<bool> RefreshChapterImages(Video video, IDirectoryService directoryService, IReadOnlyList<ChapterInfo> chapters, bool extractImages, bool saveChapters, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Persistence
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
/// </summary>
|
||||
void SaveChapters(Guid id, List<ChapterInfo> chapters);
|
||||
void SaveChapters(Guid id, IReadOnlyList<ChapterInfo> chapters);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// </summary>
|
||||
/// <value>The artist provider ids.</value>
|
||||
public Dictionary<string, string> ArtistProviderIds { get; set; }
|
||||
|
||||
public List<SongInfo> SongInfos { get; set; }
|
||||
|
||||
public AlbumInfo()
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class BoxSetInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
entries = _fileSystem.GetFileSystemEntries(path).ToArray();
|
||||
|
||||
//_cache.TryAdd(path, entries);
|
||||
_cache[path] = entries;
|
||||
}
|
||||
|
||||
@@ -56,7 +55,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
|
||||
if (file != null && file.Exists)
|
||||
{
|
||||
//_fileCache.TryAdd(path, file);
|
||||
_fileCache[path] = file;
|
||||
}
|
||||
else
|
||||
@@ -66,15 +64,12 @@ namespace MediaBrowser.Controller.Providers
|
||||
}
|
||||
|
||||
return file;
|
||||
//return _fileSystem.GetFileInfo(path);
|
||||
}
|
||||
|
||||
public List<string> GetFilePaths(string path)
|
||||
{
|
||||
return GetFilePaths(path, false);
|
||||
}
|
||||
public IReadOnlyList<string> GetFilePaths(string path)
|
||||
=> GetFilePaths(path, false);
|
||||
|
||||
public List<string> GetFilePaths(string path, bool clearCache)
|
||||
public IReadOnlyList<string> GetFilePaths(string path, bool clearCache)
|
||||
{
|
||||
if (clearCache || !_filePathCache.TryGetValue(path, out List<string> result))
|
||||
{
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class DynamicImageInfo
|
||||
{
|
||||
public string ImageId { get; set; }
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class DynamicImageResponse
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public MediaProtocol Protocol { get; set; }
|
||||
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
public ImageFormat Format { get; set; }
|
||||
|
||||
public bool HasImage { get; set; }
|
||||
|
||||
public void SetFormatFromMimeType(string mimeType)
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public int? IndexNumberEnd { get; set; }
|
||||
|
||||
public bool IsMissingEpisode { get; set; }
|
||||
|
||||
public string SeriesDisplayOrder { get; set; }
|
||||
|
||||
public EpisodeInfo()
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class ExtraInfo
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public LocationType LocationType { get; set; }
|
||||
|
||||
public bool IsDownloadable { get; set; }
|
||||
|
||||
public ExtraType ExtraType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public enum ExtraSource
|
||||
{
|
||||
Local = 1,
|
||||
Metadata = 2,
|
||||
Remote = 3
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
where TItemType : BaseItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches the asynchronous.
|
||||
/// Fetches the metadata asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
|
||||
@@ -6,10 +6,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public interface IDirectoryService
|
||||
{
|
||||
FileSystemMetadata[] GetFileSystemEntries(string path);
|
||||
|
||||
List<FileSystemMetadata> GetFiles(string path);
|
||||
|
||||
FileSystemMetadata GetFile(string path);
|
||||
|
||||
List<string> GetFilePaths(string path);
|
||||
List<string> GetFilePaths(string path, bool clearCache);
|
||||
IReadOnlyList<string> GetFilePaths(string path);
|
||||
|
||||
IReadOnlyList<string> GetFilePaths(string path, bool clearCache);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IExtrasProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool Supports(BaseItem item);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a marker interface that will cause a provider to run even if IsLocked=true
|
||||
/// This is a marker interface that will cause a provider to run even if an item is locked from changes.
|
||||
/// </summary>
|
||||
public interface IForcedProvider
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using MediaBrowser.Controller.Entities;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProvider
|
||||
/// Interface IImageProvider.
|
||||
/// </summary>
|
||||
public interface IImageProvider
|
||||
{
|
||||
@@ -14,10 +14,10 @@ namespace MediaBrowser.Controller.Providers
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// Supports the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
/// <returns><c>true</c> if the provider supports the item.</returns>
|
||||
bool Supports(BaseItem item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface ILocalImageFileProvider : ILocalImageProvider
|
||||
{
|
||||
List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is just a marker interface
|
||||
/// This is just a marker interface.
|
||||
/// </summary>
|
||||
public interface ILocalImageProvider : IImageProvider
|
||||
{
|
||||
List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="directoryService">The directory service.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{MetadataResult{`0}}.</returns>
|
||||
Task<MetadataResult<TItemType>> GetMetadata(ItemInfo info,
|
||||
/// <returns>Task{MetadataResult{0}}.</returns>
|
||||
Task<MetadataResult<TItemType>> GetMetadata(
|
||||
ItemInfo info,
|
||||
IDirectoryService directoryService,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// Determines whether this instance can refresh the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if this instance can refresh the specified item; otherwise, <c>false</c>.</returns>
|
||||
/// <returns><c>true</c> if this instance can refresh the specified item.</returns>
|
||||
bool CanRefresh(BaseItem item);
|
||||
|
||||
bool CanRefreshPrimary(Type type);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IPreRefreshProvider : ICustomMetadataProvider
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ using MediaBrowser.Model.Providers;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IProviderManager
|
||||
/// Interface IProviderManager.
|
||||
/// </summary>
|
||||
public interface IProviderManager
|
||||
{
|
||||
@@ -159,13 +159,17 @@ namespace MediaBrowser.Controller.Providers
|
||||
Dictionary<Guid, Guid> GetRefreshQueue();
|
||||
|
||||
void OnRefreshStart(BaseItem item);
|
||||
|
||||
void OnRefreshProgress(BaseItem item, double progress);
|
||||
|
||||
void OnRefreshComplete(BaseItem item);
|
||||
|
||||
double? GetRefreshProgress(Guid id);
|
||||
|
||||
event EventHandler<GenericEventArgs<BaseItem>> RefreshStarted;
|
||||
|
||||
event EventHandler<GenericEventArgs<BaseItem>> RefreshCompleted;
|
||||
|
||||
event EventHandler<GenericEventArgs<Tuple<BaseItem, double>>> RefreshProgress;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ using MediaBrowser.Model.Providers;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProvider
|
||||
/// Interface IImageProvider.
|
||||
/// </summary>
|
||||
public interface IRemoteImageProvider : IImageProvider
|
||||
{
|
||||
|
||||
@@ -23,10 +23,15 @@ namespace MediaBrowser.Controller.Providers
|
||||
}
|
||||
|
||||
public Type ItemType { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string ContainingFolderPath { get; set; }
|
||||
|
||||
public VideoType VideoType { get; set; }
|
||||
|
||||
public bool IsInMixedFolder { get; set; }
|
||||
|
||||
public bool IsPlaceHolder { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,29 +11,37 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata language.
|
||||
/// </summary>
|
||||
/// <value>The metadata language.</value>
|
||||
public string MetadataLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata country code.
|
||||
/// </summary>
|
||||
/// <value>The metadata country code.</value>
|
||||
public string MetadataCountryCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider ids.
|
||||
/// </summary>
|
||||
/// <value>The provider ids.</value>
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the year.
|
||||
/// </summary>
|
||||
/// <value>The year.</value>
|
||||
public int? Year { get; set; }
|
||||
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
public DateTime? PremiereDate { get; set; }
|
||||
|
||||
public bool IsAutomated { get; set; }
|
||||
|
||||
public ItemLookupInfo()
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class LocalImageInfo
|
||||
{
|
||||
public FileSystemMetadata FileInfo { get; set; }
|
||||
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines when a provider should execute, relative to others
|
||||
/// </summary>
|
||||
public enum MetadataProviderPriority
|
||||
{
|
||||
// Run this provider at the beginning
|
||||
/// <summary>
|
||||
/// The first
|
||||
/// </summary>
|
||||
First = 1,
|
||||
|
||||
// Run this provider after all first priority providers
|
||||
/// <summary>
|
||||
/// The second
|
||||
/// </summary>
|
||||
Second = 2,
|
||||
|
||||
// Run this provider after all second priority providers
|
||||
/// <summary>
|
||||
/// The third
|
||||
/// </summary>
|
||||
Third = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The fourth
|
||||
/// </summary>
|
||||
Fourth = 4,
|
||||
|
||||
Fifth = 5,
|
||||
|
||||
// Run this provider last
|
||||
/// <summary>
|
||||
/// The last
|
||||
/// </summary>
|
||||
Last = 999
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public bool ReplaceAllMetadata { get; set; }
|
||||
|
||||
public MetadataRefreshMode MetadataRefreshMode { get; set; }
|
||||
|
||||
public RemoteSearchResult SearchResult { get; set; }
|
||||
|
||||
public string[] RefreshPaths { get; set; }
|
||||
|
||||
public bool ForceSave { get; set; }
|
||||
|
||||
public bool EnableRemoteContentProbe { get; set; }
|
||||
|
||||
public MetadataRefreshOptions(IDirectoryService directoryService)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class MetadataResult<T>
|
||||
{
|
||||
public List<LocalImageInfo> Images { get; set; }
|
||||
|
||||
public List<UserItemData> UserDataList { get; set; }
|
||||
|
||||
public MetadataResult()
|
||||
@@ -19,10 +20,15 @@ namespace MediaBrowser.Controller.Providers
|
||||
public List<PersonInfo> People { get; set; }
|
||||
|
||||
public bool HasMetadata { get; set; }
|
||||
|
||||
public T Item { get; set; }
|
||||
|
||||
public string ResultLanguage { get; set; }
|
||||
|
||||
public string Provider { get; set; }
|
||||
|
||||
public bool QueriedById { get; set; }
|
||||
|
||||
public void AddPerson(PersonInfo p)
|
||||
{
|
||||
if (People == null)
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class MovieInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class PersonLookupInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ namespace MediaBrowser.Controller.Providers
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set will only search within the given provider
|
||||
/// Will only search within the given provider when set.
|
||||
/// </summary>
|
||||
public string SearchProviderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [include disabled providers].
|
||||
/// Gets or sets a value indicating whether disabled providers should be included.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [include disabled providers]; otherwise, <c>false</c>.</value>
|
||||
/// <value><c>true</c> if disabled providers should be included.</value>
|
||||
public bool IncludeDisabledProviders { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user