commit
e229f6d9bb
|
@ -114,6 +114,11 @@ namespace Emby.Server.Implementations
|
|||
/// </summary>
|
||||
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" };
|
||||
|
||||
/// <summary>
|
||||
/// The disposable parts.
|
||||
/// </summary>
|
||||
private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
|
||||
|
||||
private readonly IFileSystem _fileSystemManager;
|
||||
private readonly IConfiguration _startupConfig;
|
||||
private readonly IXmlSerializer _xmlSerializer;
|
||||
|
@ -125,104 +130,15 @@ namespace Emby.Server.Implementations
|
|||
private ISessionManager _sessionManager;
|
||||
private string[] _urlPrefixes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self restart.
|
||||
/// </summary>
|
||||
public bool CanSelfRestart => _startupOptions.RestartPath != null;
|
||||
|
||||
public bool CoreStartupHasCompleted { get; private set; }
|
||||
|
||||
public virtual bool CanLaunchWebBrowser
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Environment.UserInteractive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_startupOptions.IsService)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="INetworkManager"/> singleton instance.
|
||||
/// </summary>
|
||||
public INetworkManager NetManager { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [has pending restart changed].
|
||||
/// </summary>
|
||||
public event EventHandler HasPendingRestartChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has changes that require the entire application to restart.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
|
||||
public bool HasPendingRestart { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsShuttingDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
protected ILogger<ApplicationHost> Logger { get; }
|
||||
|
||||
protected IServiceCollection ServiceCollection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger factory.
|
||||
/// </summary>
|
||||
protected ILoggerFactory LoggerFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application paths.
|
||||
/// </summary>
|
||||
/// <value>The application paths.</value>
|
||||
protected IServerApplicationPaths ApplicationPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets all concrete types.
|
||||
/// </summary>
|
||||
/// <value>All concrete types.</value>
|
||||
private Type[] _allConcreteTypes;
|
||||
|
||||
/// <summary>
|
||||
/// The disposable parts.
|
||||
/// </summary>
|
||||
private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
|
||||
private DeviceId _deviceId;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration manager.
|
||||
/// </summary>
|
||||
/// <value>The configuration manager.</value>
|
||||
public ServerConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service provider.
|
||||
/// </summary>
|
||||
public IServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the http port for the webhost.
|
||||
/// </summary>
|
||||
public int HttpPort { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the https port for the webhost.
|
||||
/// </summary>
|
||||
public int HttpsPort { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the PublishedServerUrl setting.
|
||||
/// </summary>
|
||||
public string PublishedServerUrl => _startupOptions.PublishedServerUrl ?? _startupConfig[UdpServer.AddressOverrideConfigKey];
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApplicationHost"/> class.
|
||||
|
@ -265,6 +181,143 @@ namespace Emby.Server.Implementations
|
|||
ApplicationVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [has pending restart changed].
|
||||
/// </summary>
|
||||
public event EventHandler HasPendingRestartChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance can self restart.
|
||||
/// </summary>
|
||||
public bool CanSelfRestart => _startupOptions.RestartPath != null;
|
||||
|
||||
public bool CoreStartupHasCompleted { get; private set; }
|
||||
|
||||
public virtual bool CanLaunchWebBrowser
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Environment.UserInteractive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_startupOptions.IsService)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="INetworkManager"/> singleton instance.
|
||||
/// </summary>
|
||||
public INetworkManager NetManager { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance has changes that require the entire application to restart.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
|
||||
public bool HasPendingRestart { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsShuttingDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
protected ILogger<ApplicationHost> Logger { get; }
|
||||
|
||||
protected IServiceCollection ServiceCollection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger factory.
|
||||
/// </summary>
|
||||
protected ILoggerFactory LoggerFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application paths.
|
||||
/// </summary>
|
||||
/// <value>The application paths.</value>
|
||||
protected IServerApplicationPaths ApplicationPaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration manager.
|
||||
/// </summary>
|
||||
/// <value>The configuration manager.</value>
|
||||
public ServerConfigurationManager ConfigurationManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service provider.
|
||||
/// </summary>
|
||||
public IServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the http port for the webhost.
|
||||
/// </summary>
|
||||
public int HttpPort { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the https port for the webhost.
|
||||
/// </summary>
|
||||
public int HttpsPort { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the PublishedServerUrl setting.
|
||||
/// </summary>
|
||||
public string PublishedServerUrl => _startupOptions.PublishedServerUrl ?? _startupConfig[UdpServer.AddressOverrideConfigKey];
|
||||
|
||||
/// <inheritdoc />
|
||||
public Version ApplicationVersion { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationVersionString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current application user agent.
|
||||
/// </summary>
|
||||
/// <value>The application user agent.</value>
|
||||
public string ApplicationUserAgent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the email address for use within a comment section of a user agent field.
|
||||
/// Presently used to provide contact information to MusicBrainz service.
|
||||
/// </summary>
|
||||
public string ApplicationUserAgentAddress => "team@jellyfin.org";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current application name.
|
||||
/// </summary>
|
||||
/// <value>The application name.</value>
|
||||
public string ApplicationProductName { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName;
|
||||
|
||||
public string SystemId
|
||||
{
|
||||
get
|
||||
{
|
||||
_deviceId ??= new DeviceId(ApplicationPaths, LoggerFactory);
|
||||
|
||||
return _deviceId.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => ApplicationProductName;
|
||||
|
||||
private CertificateInfo CertificateInfo { get; set; }
|
||||
|
||||
public X509Certificate2 Certificate { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ListenWithHttps => Certificate != null && ConfigurationManager.GetNetworkConfiguration().EnableHttps;
|
||||
|
||||
public string FriendlyName =>
|
||||
string.IsNullOrEmpty(ConfigurationManager.Configuration.ServerName)
|
||||
? Environment.MachineName
|
||||
: ConfigurationManager.Configuration.ServerName;
|
||||
|
||||
/// <summary>
|
||||
/// Temporary function to migration network settings out of system.xml and into network.xml.
|
||||
/// TODO: remove at the point when a fixed migration path has been decided upon.
|
||||
|
@ -297,45 +350,6 @@ namespace Emby.Server.Implementations
|
|||
.Replace(appPaths.InternalMetadataPath, appPaths.VirtualInternalMetadataPath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Version ApplicationVersion { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationVersionString { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current application user agent.
|
||||
/// </summary>
|
||||
/// <value>The application user agent.</value>
|
||||
public string ApplicationUserAgent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the email address for use within a comment section of a user agent field.
|
||||
/// Presently used to provide contact information to MusicBrainz service.
|
||||
/// </summary>
|
||||
public string ApplicationUserAgentAddress => "team@jellyfin.org";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current application name.
|
||||
/// </summary>
|
||||
/// <value>The application name.</value>
|
||||
public string ApplicationProductName { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductName;
|
||||
|
||||
private DeviceId _deviceId;
|
||||
|
||||
public string SystemId
|
||||
{
|
||||
get
|
||||
{
|
||||
_deviceId ??= new DeviceId(ApplicationPaths, LoggerFactory);
|
||||
|
||||
return _deviceId.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => ApplicationProductName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of type and resolves all constructor dependencies.
|
||||
/// </summary>
|
||||
|
@ -857,10 +871,6 @@ namespace Emby.Server.Implementations
|
|||
}
|
||||
}
|
||||
|
||||
private CertificateInfo CertificateInfo { get; set; }
|
||||
|
||||
public X509Certificate2 Certificate { get; private set; }
|
||||
|
||||
private IEnumerable<string> GetUrlPrefixes()
|
||||
{
|
||||
var hosts = new[] { "+" };
|
||||
|
@ -1114,9 +1124,6 @@ namespace Emby.Server.Implementations
|
|||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool ListenWithHttps => Certificate != null && ConfigurationManager.GetNetworkConfiguration().EnableHttps;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetSmartApiUrl(IPAddress remoteAddr, int? port = null)
|
||||
{
|
||||
|
@ -1203,14 +1210,7 @@ namespace Emby.Server.Implementations
|
|||
}.ToString().TrimEnd('/');
|
||||
}
|
||||
|
||||
public string FriendlyName =>
|
||||
string.IsNullOrEmpty(ConfigurationManager.Configuration.ServerName)
|
||||
? Environment.MachineName
|
||||
: ConfigurationManager.Configuration.ServerName;
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public async Task Shutdown()
|
||||
{
|
||||
if (IsShuttingDown)
|
||||
|
@ -1248,41 +1248,7 @@ namespace Emby.Server.Implementations
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void LaunchUrl(string url)
|
||||
{
|
||||
if (!CanLaunchWebBrowser)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = url,
|
||||
UseShellExecute = true,
|
||||
ErrorDialog = false
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
process.Exited += (sender, args) => ((Process)sender).Dispose();
|
||||
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error launching url: {url}", url);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
|
|
@ -196,8 +196,8 @@ namespace Emby.Server.Implementations.Collections
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> ids)
|
||||
=> AddToCollectionAsync(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
||||
public Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> itemIds)
|
||||
=> AddToCollectionAsync(collectionId, itemIds, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
|
||||
|
||||
private async Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
|
||||
{
|
||||
|
|
|
@ -1902,12 +1902,7 @@ namespace Emby.Server.Implementations.Data
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets chapters for an item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>IEnumerable{ChapterInfo}.</returns>
|
||||
/// <exception cref="ArgumentNullException">id</exception>
|
||||
/// <inheritdoc />
|
||||
public List<ChapterInfo> GetChapters(BaseItem item)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
@ -1930,13 +1925,7 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single chapter for an item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>ChapterInfo.</returns>
|
||||
/// <exception cref="ArgumentNullException">id</exception>
|
||||
/// <inheritdoc />
|
||||
public ChapterInfo GetChapter(BaseItem item, int index)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
@ -2048,7 +2037,7 @@ namespace Emby.Server.Implementations.Data
|
|||
|
||||
for (var i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
insertText.AppendFormat("(@ItemId, @ChapterIndex{0}, @StartPositionTicks{0}, @Name{0}, @ImagePath{0}, @ImageDateModified{0}),", i.ToString(CultureInfo.InvariantCulture));
|
||||
insertText.AppendFormat(CultureInfo.InvariantCulture, "(@ItemId, @ChapterIndex{0}, @StartPositionTicks{0}, @Name{0}, @ImagePath{0}, @ImageDateModified{0}),", i.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
insertText.Length -= 1; // Remove last ,
|
||||
|
|
|
@ -129,19 +129,17 @@ namespace Emby.Server.Implementations.Data
|
|||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the user data.
|
||||
/// </summary>
|
||||
public void SaveUserData(long internalUserId, string key, UserItemData userData, CancellationToken cancellationToken)
|
||||
/// <inheritdoc />
|
||||
public void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken)
|
||||
{
|
||||
if (userData == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(userData));
|
||||
}
|
||||
|
||||
if (internalUserId <= 0)
|
||||
if (userId <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(internalUserId));
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(key))
|
||||
|
@ -149,22 +147,23 @@ namespace Emby.Server.Implementations.Data
|
|||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
PersistUserData(internalUserId, key, userData, cancellationToken);
|
||||
PersistUserData(userId, key, userData, cancellationToken);
|
||||
}
|
||||
|
||||
public void SaveAllUserData(long internalUserId, UserItemData[] userData, CancellationToken cancellationToken)
|
||||
/// <inheritdoc />
|
||||
public void SaveAllUserData(long userId, UserItemData[] userData, CancellationToken cancellationToken)
|
||||
{
|
||||
if (userData == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(userData));
|
||||
}
|
||||
|
||||
if (internalUserId <= 0)
|
||||
if (userId <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(internalUserId));
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
}
|
||||
|
||||
PersistAllUserData(internalUserId, userData, cancellationToken);
|
||||
PersistAllUserData(userId, userData, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -263,19 +262,19 @@ namespace Emby.Server.Implementations.Data
|
|||
/// <summary>
|
||||
/// Gets the user data.
|
||||
/// </summary>
|
||||
/// <param name="internalUserId">The user id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>Task{UserItemData}.</returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// userId
|
||||
/// or
|
||||
/// key
|
||||
/// key.
|
||||
/// </exception>
|
||||
public UserItemData GetUserData(long internalUserId, string key)
|
||||
public UserItemData GetUserData(long userId, string key)
|
||||
{
|
||||
if (internalUserId <= 0)
|
||||
if (userId <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(internalUserId));
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(key))
|
||||
|
@ -287,7 +286,7 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where key =@Key and userId=@UserId"))
|
||||
{
|
||||
statement.TryBind("@UserId", internalUserId);
|
||||
statement.TryBind("@UserId", userId);
|
||||
statement.TryBind("@Key", key);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
|
@ -300,7 +299,7 @@ namespace Emby.Server.Implementations.Data
|
|||
}
|
||||
}
|
||||
|
||||
public UserItemData GetUserData(long internalUserId, List<string> keys)
|
||||
public UserItemData GetUserData(long userId, List<string> keys)
|
||||
{
|
||||
if (keys == null)
|
||||
{
|
||||
|
@ -312,19 +311,19 @@ namespace Emby.Server.Implementations.Data
|
|||
return null;
|
||||
}
|
||||
|
||||
return GetUserData(internalUserId, keys[0]);
|
||||
return GetUserData(userId, keys[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all user-data associated with the given user.
|
||||
/// </summary>
|
||||
/// <param name="internalUserId">The internal user id.</param>
|
||||
/// <param name="userId">The internal user id.</param>
|
||||
/// <returns>The list of user item data.</returns>
|
||||
public List<UserItemData> GetAllUserData(long internalUserId)
|
||||
public List<UserItemData> GetAllUserData(long userId)
|
||||
{
|
||||
if (internalUserId <= 0)
|
||||
if (userId <= 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(internalUserId));
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
}
|
||||
|
||||
var list = new List<UserItemData>();
|
||||
|
@ -333,7 +332,7 @@ namespace Emby.Server.Implementations.Data
|
|||
{
|
||||
using (var statement = connection.PrepareStatement("select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from UserDatas where userId=@UserId"))
|
||||
{
|
||||
statement.TryBind("@UserId", internalUserId);
|
||||
statement.TryBind("@UserId", userId);
|
||||
|
||||
foreach (var row in statement.ExecuteQuery())
|
||||
{
|
||||
|
|
|
@ -51,8 +51,6 @@ namespace Emby.Server.Implementations.Dto
|
|||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
private readonly Lazy<ILiveTvManager> _livetvManagerFactory;
|
||||
|
||||
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
|
||||
|
||||
public DtoService(
|
||||
ILogger<DtoService> logger,
|
||||
ILibraryManager libraryManager,
|
||||
|
@ -75,6 +73,8 @@ namespace Emby.Server.Implementations.Dto
|
|||
_livetvManagerFactory = livetvManagerFactory;
|
||||
}
|
||||
|
||||
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<BaseItemDto> GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
|
||||
{
|
||||
|
@ -507,7 +507,6 @@ namespace Emby.Server.Implementations.Dto
|
|||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private void AttachPeople(BaseItemDto dto, BaseItem item)
|
||||
{
|
||||
// Ordering by person type to ensure actors and artists are at the front.
|
||||
|
@ -616,7 +615,6 @@ namespace Emby.Server.Implementations.Dto
|
|||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private void AttachStudios(BaseItemDto dto, BaseItem item)
|
||||
{
|
||||
dto.Studios = item.Studios
|
||||
|
@ -1313,9 +1311,12 @@ namespace Emby.Server.Implementations.Dto
|
|||
|
||||
var imageTags = dto.ImageTags;
|
||||
|
||||
while (((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && artLimit > 0) || (!(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && thumbLimit > 0) || parent is Series) &&
|
||||
(parent ??= (isFirst ? GetImageDisplayParent(item, item) ?? owner : parent)) != null)
|
||||
while ((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0)
|
||||
|| (!(imageTags != null && imageTags.ContainsKey(ImageType.Art)) && artLimit > 0)
|
||||
|| (!(imageTags != null && imageTags.ContainsKey(ImageType.Thumb)) && thumbLimit > 0)
|
||||
|| parent is Series)
|
||||
{
|
||||
parent ??= isFirst ? GetImageDisplayParent(item, item) ?? owner : parent;
|
||||
if (parent == null)
|
||||
{
|
||||
break;
|
||||
|
@ -1395,7 +1396,6 @@ namespace Emby.Server.Implementations.Dto
|
|||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item)
|
||||
{
|
||||
dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item);
|
||||
|
|
|
@ -423,7 +423,7 @@ namespace Emby.Server.Implementations.IO
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void SetAttributes(string path, bool isHidden, bool isReadOnly)
|
||||
public virtual void SetAttributes(string path, bool isHidden, bool readOnly)
|
||||
{
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
|
@ -437,14 +437,14 @@ namespace Emby.Server.Implementations.IO
|
|||
return;
|
||||
}
|
||||
|
||||
if (info.IsReadOnly == isReadOnly && info.IsHidden == isHidden)
|
||||
if (info.IsReadOnly == readOnly && info.IsHidden == isHidden)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var attributes = File.GetAttributes(path);
|
||||
|
||||
if (isReadOnly)
|
||||
if (readOnly)
|
||||
{
|
||||
attributes = attributes | FileAttributes.ReadOnly;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Images
|
|||
|
||||
public int Order => 0;
|
||||
|
||||
protected virtual bool Supports(BaseItem _) => true;
|
||||
protected virtual bool Supports(BaseItem item) => true;
|
||||
|
||||
public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -1761,22 +1761,20 @@ namespace Emby.Server.Implementations.Library
|
|||
return orderedItems ?? items;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<ValueTuple<string, SortOrder>> orderByList)
|
||||
public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<ValueTuple<string, SortOrder>> orderBy)
|
||||
{
|
||||
var isFirst = true;
|
||||
|
||||
IOrderedEnumerable<BaseItem> orderedItems = null;
|
||||
|
||||
foreach (var orderBy in orderByList)
|
||||
foreach (var (name, sortOrder) in orderBy)
|
||||
{
|
||||
var comparer = GetComparer(orderBy.Item1, user);
|
||||
var comparer = GetComparer(name, user);
|
||||
if (comparer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var sortOrder = orderBy.Item2;
|
||||
|
||||
if (isFirst)
|
||||
{
|
||||
orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer);
|
||||
|
@ -3076,9 +3074,9 @@ namespace Emby.Server.Implementations.Library
|
|||
});
|
||||
}
|
||||
|
||||
public void AddMediaPath(string virtualFolderName, MediaPathInfo pathInfo)
|
||||
public void AddMediaPath(string virtualFolderName, MediaPathInfo mediaPath)
|
||||
{
|
||||
AddMediaPathInternal(virtualFolderName, pathInfo, true);
|
||||
AddMediaPathInternal(virtualFolderName, mediaPath, true);
|
||||
}
|
||||
|
||||
private void AddMediaPathInternal(string virtualFolderName, MediaPathInfo pathInfo, bool saveLibraryOptions)
|
||||
|
@ -3131,11 +3129,11 @@ namespace Emby.Server.Implementations.Library
|
|||
}
|
||||
}
|
||||
|
||||
public void UpdateMediaPath(string virtualFolderName, MediaPathInfo pathInfo)
|
||||
public void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath)
|
||||
{
|
||||
if (pathInfo == null)
|
||||
if (mediaPath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pathInfo));
|
||||
throw new ArgumentNullException(nameof(mediaPath));
|
||||
}
|
||||
|
||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
|
@ -3148,9 +3146,9 @@ namespace Emby.Server.Implementations.Library
|
|||
var list = libraryOptions.PathInfos.ToList();
|
||||
foreach (var originalPathInfo in list)
|
||||
{
|
||||
if (string.Equals(pathInfo.Path, originalPathInfo.Path, StringComparison.Ordinal))
|
||||
if (string.Equals(mediaPath.Path, originalPathInfo.Path, StringComparison.Ordinal))
|
||||
{
|
||||
originalPathInfo.NetworkPath = pathInfo.NetworkPath;
|
||||
originalPathInfo.NetworkPath = mediaPath.NetworkPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,9 +36,10 @@ namespace Emby.Server.Implementations.Library
|
|||
return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)).ToList();
|
||||
}
|
||||
|
||||
public List<BaseItem> GetInstantMixFromArtist(MusicArtist item, User user, DtoOptions dtoOptions)
|
||||
/// <inheritdoc />
|
||||
public List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User user, DtoOptions dtoOptions)
|
||||
{
|
||||
return GetInstantMixFromGenres(item.Genres, user, dtoOptions);
|
||||
return GetInstantMixFromGenres(artist.Genres, user, dtoOptions);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions)
|
||||
|
|
|
@ -21,13 +21,13 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
|||
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
|
||||
where T : Video, new()
|
||||
{
|
||||
protected readonly ILibraryManager LibraryManager;
|
||||
|
||||
protected BaseVideoResolver(ILibraryManager libraryManager)
|
||||
{
|
||||
LibraryManager = libraryManager;
|
||||
}
|
||||
|
||||
protected ILibraryManager LibraryManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the specified args.
|
||||
/// </summary>
|
||||
|
|
|
@ -177,6 +177,7 @@ namespace Emby.Server.Implementations.Library
|
|||
return dto;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions options)
|
||||
{
|
||||
var userData = GetUserData(user, item);
|
||||
|
@ -191,7 +192,7 @@ namespace Emby.Server.Implementations.Library
|
|||
/// </summary>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>DtoUserItemData.</returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
|
||||
private UserItemDataDto GetUserItemDataDto(UserItemData data)
|
||||
{
|
||||
if (data == null)
|
||||
|
@ -212,6 +213,7 @@ namespace Emby.Server.Implementations.Library
|
|||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks)
|
||||
{
|
||||
var playedToCompletion = false;
|
||||
|
|
|
@ -610,11 +610,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> CreateTimer(TimerInfo timer, CancellationToken cancellationToken)
|
||||
public Task<string> CreateTimer(TimerInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
var existingTimer = string.IsNullOrWhiteSpace(timer.ProgramId) ?
|
||||
var existingTimer = string.IsNullOrWhiteSpace(info.ProgramId) ?
|
||||
null :
|
||||
_timerProvider.GetTimerByProgramId(timer.ProgramId);
|
||||
_timerProvider.GetTimerByProgramId(info.ProgramId);
|
||||
|
||||
if (existingTimer != null)
|
||||
{
|
||||
|
@ -632,32 +632,32 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
}
|
||||
|
||||
timer.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
|
||||
info.Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
|
||||
|
||||
LiveTvProgram programInfo = null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(timer.ProgramId))
|
||||
if (!string.IsNullOrWhiteSpace(info.ProgramId))
|
||||
{
|
||||
programInfo = GetProgramInfoFromCache(timer);
|
||||
programInfo = GetProgramInfoFromCache(info);
|
||||
}
|
||||
|
||||
if (programInfo == null)
|
||||
{
|
||||
_logger.LogInformation("Unable to find program with Id {0}. Will search using start date", timer.ProgramId);
|
||||
programInfo = GetProgramInfoFromCache(timer.ChannelId, timer.StartDate);
|
||||
_logger.LogInformation("Unable to find program with Id {0}. Will search using start date", info.ProgramId);
|
||||
programInfo = GetProgramInfoFromCache(info.ChannelId, info.StartDate);
|
||||
}
|
||||
|
||||
if (programInfo != null)
|
||||
{
|
||||
CopyProgramInfoToTimerInfo(programInfo, timer);
|
||||
CopyProgramInfoToTimerInfo(programInfo, info);
|
||||
}
|
||||
|
||||
timer.IsManual = true;
|
||||
_timerProvider.Add(timer);
|
||||
info.IsManual = true;
|
||||
_timerProvider.Add(info);
|
||||
|
||||
TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(timer));
|
||||
TimerCreated?.Invoke(this, new GenericEventArgs<TimerInfo>(info));
|
||||
|
||||
return Task.FromResult(timer.Id);
|
||||
return Task.FromResult(info.Id);
|
||||
}
|
||||
|
||||
public async Task<string> CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken)
|
||||
|
|
|
@ -65,6 +65,8 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>();
|
||||
private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>();
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
public LiveTvManager(
|
||||
IServerConfigurationManager config,
|
||||
ILogger<LiveTvManager> logger,
|
||||
|
@ -520,7 +522,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
return item;
|
||||
}
|
||||
|
||||
private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
||||
private (LiveTvProgram item, bool isNew, bool isUpdated) GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel)
|
||||
{
|
||||
var id = _tvDtoService.GetInternalProgramId(info.Id);
|
||||
|
||||
|
@ -559,8 +561,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
item.ParentId = channel.Id;
|
||||
|
||||
// item.ChannelType = channelType;
|
||||
|
||||
item.Audio = info.Audio;
|
||||
item.ChannelId = channel.Id;
|
||||
item.CommunityRating ??= info.CommunityRating;
|
||||
|
@ -772,7 +772,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
item.OnMetadataChanged();
|
||||
}
|
||||
|
||||
return new Tuple<LiveTvProgram, bool, bool>(item, isNew, isUpdated);
|
||||
return (item, isNew, isUpdated);
|
||||
}
|
||||
|
||||
public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
|
||||
|
@ -1187,14 +1187,14 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
foreach (var program in channelPrograms)
|
||||
{
|
||||
var programTuple = GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken);
|
||||
var programItem = programTuple.Item1;
|
||||
var programTuple = GetProgram(program, existingPrograms, currentChannel);
|
||||
var programItem = programTuple.item;
|
||||
|
||||
if (programTuple.Item2)
|
||||
if (programTuple.isNew)
|
||||
{
|
||||
newPrograms.Add(programItem);
|
||||
}
|
||||
else if (programTuple.Item3)
|
||||
else if (programTuple.isUpdated)
|
||||
{
|
||||
updatedPrograms.Add(programItem);
|
||||
}
|
||||
|
@ -1385,10 +1385,10 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
// var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
|
||||
|
||||
// return new QueryResult<BaseItem>
|
||||
//{
|
||||
// {
|
||||
// Items = items,
|
||||
// TotalRecordCount = items.Length
|
||||
//};
|
||||
// };
|
||||
|
||||
dtoOptions.Fields = dtoOptions.Fields.Concat(new[] { ItemFields.Tags }).Distinct().ToArray();
|
||||
}
|
||||
|
@ -1425,16 +1425,15 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
return result;
|
||||
}
|
||||
|
||||
public Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> tuples, IReadOnlyList<ItemFields> fields, User user = null)
|
||||
public Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> programs, IReadOnlyList<ItemFields> fields, User user = null)
|
||||
{
|
||||
var programTuples = new List<Tuple<BaseItemDto, string, string>>();
|
||||
var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
|
||||
var hasChannelInfo = fields.Contains(ItemFields.ChannelInfo);
|
||||
|
||||
foreach (var tuple in tuples)
|
||||
foreach (var (item, dto) in programs)
|
||||
{
|
||||
var program = (LiveTvProgram)tuple.Item1;
|
||||
var dto = tuple.Item2;
|
||||
var program = (LiveTvProgram)item;
|
||||
|
||||
dto.StartDate = program.StartDate;
|
||||
dto.EpisodeTitle = program.EpisodeTitle;
|
||||
|
@ -1871,11 +1870,11 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
return _libraryManager.GetItemById(internalChannelId);
|
||||
}
|
||||
|
||||
public void AddChannelInfo(IReadOnlyCollection<(BaseItemDto, LiveTvChannel)> tuples, DtoOptions options, User user)
|
||||
public void AddChannelInfo(IReadOnlyCollection<(BaseItemDto, LiveTvChannel)> items, DtoOptions options, User user)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var channelIds = tuples.Select(i => i.Item2.Id).Distinct().ToArray();
|
||||
var channelIds = items.Select(i => i.Item2.Id).Distinct().ToArray();
|
||||
|
||||
var programs = options.AddCurrentProgram ? _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
|
@ -1896,7 +1895,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
var addCurrentProgram = options.AddCurrentProgram;
|
||||
|
||||
foreach (var tuple in tuples)
|
||||
foreach (var tuple in items)
|
||||
{
|
||||
var dto = tuple.Item1;
|
||||
var channel = tuple.Item2;
|
||||
|
@ -2118,17 +2117,13 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Releases unmanaged and - optionally - managed resources.
|
||||
/// </summary>
|
||||
|
@ -2324,20 +2319,20 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
_taskManager.CancelIfRunningAndQueue<RefreshGuideScheduledTask>();
|
||||
}
|
||||
|
||||
public async Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelId, string providerChannelId)
|
||||
public async Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber)
|
||||
{
|
||||
var config = GetConfiguration();
|
||||
|
||||
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase));
|
||||
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelId, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||
|
||||
if (!string.Equals(tunerChannelId, providerChannelId, StringComparison.OrdinalIgnoreCase))
|
||||
if (!string.Equals(tunerChannelNumber, providerChannelNumber, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var list = listingsProviderInfo.ChannelMappings.ToList();
|
||||
list.Add(new NameValuePair
|
||||
{
|
||||
Name = tunerChannelId,
|
||||
Value = providerChannelId
|
||||
Name = tunerChannelNumber,
|
||||
Value = providerChannelNumber
|
||||
});
|
||||
listingsProviderInfo.ChannelMappings = list.ToArray();
|
||||
}
|
||||
|
@ -2357,10 +2352,10 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
_taskManager.CancelIfRunningAndQueue<RefreshGuideScheduledTask>();
|
||||
|
||||
return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase));
|
||||
return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelNumber, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> epgChannels)
|
||||
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> providerChannels)
|
||||
{
|
||||
var result = new TunerChannelMapping
|
||||
{
|
||||
|
@ -2373,7 +2368,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
result.Name = tunerChannel.Number + " " + result.Name;
|
||||
}
|
||||
|
||||
var providerChannel = EmbyTV.EmbyTV.Current.GetEpgChannelFromTunerChannel(mappings, tunerChannel, epgChannels);
|
||||
var providerChannel = EmbyTV.EmbyTV.Current.GetEpgChannelFromTunerChannel(mappings, tunerChannel, providerChannels);
|
||||
|
||||
if (providerChannel != null)
|
||||
{
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
return new List<MediaSourceInfo>();
|
||||
}
|
||||
|
||||
protected abstract Task<ILiveStream> GetChannelStream(TunerHostInfo tuner, ChannelInfo channel, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||
protected abstract Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||
|
||||
public async Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -95,17 +95,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
public bool IsLegacyTuner { get; set; }
|
||||
}
|
||||
|
||||
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
|
||||
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
|
||||
{
|
||||
var lineup = await GetLineup(info, cancellationToken).ConfigureAwait(false);
|
||||
var lineup = await GetLineup(tuner, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return lineup.Select(i => new HdHomerunChannelInfo
|
||||
{
|
||||
Name = i.GuideName,
|
||||
Number = i.GuideNumber,
|
||||
Id = GetChannelId(info, i),
|
||||
Id = GetChannelId(tuner, i),
|
||||
IsFavorite = i.Favorite,
|
||||
TunerHostId = info.Id,
|
||||
TunerHostId = tuner.Id,
|
||||
IsHD = i.HD,
|
||||
AudioCodec = i.AudioCodec,
|
||||
VideoCodec = i.VideoCodec,
|
||||
|
@ -496,57 +496,53 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
return mediaSource;
|
||||
}
|
||||
|
||||
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, ChannelInfo channelInfo, CancellationToken cancellationToken)
|
||||
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, ChannelInfo channel, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<MediaSourceInfo>();
|
||||
|
||||
var channelId = channelInfo.Id;
|
||||
var channelId = channel.Id;
|
||||
var hdhrId = GetHdHrIdFromChannelId(channelId);
|
||||
|
||||
var hdHomerunChannelInfo = channelInfo as HdHomerunChannelInfo;
|
||||
|
||||
var isLegacyTuner = hdHomerunChannelInfo != null && hdHomerunChannelInfo.IsLegacyTuner;
|
||||
|
||||
if (isLegacyTuner)
|
||||
if (channel is HdHomerunChannelInfo hdHomerunChannelInfo && hdHomerunChannelInfo.IsLegacyTuner)
|
||||
{
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "native"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "native"));
|
||||
}
|
||||
else
|
||||
{
|
||||
var modelInfo = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
|
||||
var modelInfo = await GetModelInfo(tuner, false, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (modelInfo != null && modelInfo.SupportsTranscoding)
|
||||
{
|
||||
if (info.AllowHWTranscoding)
|
||||
if (tuner.AllowHWTranscoding)
|
||||
{
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "heavy"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "heavy"));
|
||||
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet540"));
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet480"));
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet360"));
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet240"));
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "mobile"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "internet540"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "internet480"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "internet360"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "internet240"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "mobile"));
|
||||
}
|
||||
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "native"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "native"));
|
||||
}
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
list.Add(GetMediaSource(info, hdhrId, channelInfo, "native"));
|
||||
list.Add(GetMediaSource(tuner, hdhrId, channel, "native"));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, ChannelInfo channelInfo, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
{
|
||||
var tunerCount = info.TunerCount;
|
||||
var tunerCount = tunerHost.TunerCount;
|
||||
|
||||
if (tunerCount > 0)
|
||||
{
|
||||
var tunerHostId = info.Id;
|
||||
var tunerHostId = tunerHost.Id;
|
||||
var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (liveStreams.Count() >= tunerCount)
|
||||
|
@ -557,26 +553,26 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
|
||||
var profile = streamId.Split('_')[0];
|
||||
|
||||
Logger.LogInformation("GetChannelStream: channel id: {0}. stream id: {1} profile: {2}", channelInfo.Id, streamId, profile);
|
||||
Logger.LogInformation("GetChannelStream: channel id: {0}. stream id: {1} profile: {2}", channel.Id, streamId, profile);
|
||||
|
||||
var hdhrId = GetHdHrIdFromChannelId(channelInfo.Id);
|
||||
var hdhrId = GetHdHrIdFromChannelId(channel.Id);
|
||||
|
||||
var hdhomerunChannel = channelInfo as HdHomerunChannelInfo;
|
||||
var hdhomerunChannel = channel as HdHomerunChannelInfo;
|
||||
|
||||
var modelInfo = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
|
||||
var modelInfo = await GetModelInfo(tunerHost, false, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!modelInfo.SupportsTranscoding)
|
||||
{
|
||||
profile = "native";
|
||||
}
|
||||
|
||||
var mediaSource = GetMediaSource(info, hdhrId, channelInfo, profile);
|
||||
var mediaSource = GetMediaSource(tunerHost, hdhrId, channel, profile);
|
||||
|
||||
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
|
||||
{
|
||||
return new HdHomerunUdpStream(
|
||||
mediaSource,
|
||||
info,
|
||||
tunerHost,
|
||||
streamId,
|
||||
new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path),
|
||||
modelInfo.TunerCount,
|
||||
|
@ -592,7 +588,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
{
|
||||
mediaSource.Protocol = MediaProtocol.Http;
|
||||
|
||||
var httpUrl = channelInfo.Path;
|
||||
var httpUrl = channel.Path;
|
||||
|
||||
// If raw was used, the tuner doesn't support params
|
||||
if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
|
||||
|
@ -604,7 +600,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
|
||||
return new SharedHttpStream(
|
||||
mediaSource,
|
||||
info,
|
||||
tunerHost,
|
||||
streamId,
|
||||
FileSystem,
|
||||
_httpClientFactory,
|
||||
|
@ -616,7 +612,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
|
||||
return new HdHomerunUdpStream(
|
||||
mediaSource,
|
||||
info,
|
||||
tunerHost,
|
||||
streamId,
|
||||
new HdHomerunChannelCommands(hdhomerunChannel.Number, profile),
|
||||
modelInfo.TunerCount,
|
||||
|
|
|
@ -71,12 +71,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
return ChannelIdPrefix + info.Url.GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
|
||||
protected override async Task<List<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
|
||||
{
|
||||
var channelIdPrefix = GetFullChannelIdPrefix(info);
|
||||
var channelIdPrefix = GetFullChannelIdPrefix(tuner);
|
||||
|
||||
return await new M3uParser(Logger, _httpClientFactory)
|
||||
.Parse(info, channelIdPrefix, cancellationToken)
|
||||
.Parse(tuner, channelIdPrefix, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -96,13 +96,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
return Task.FromResult(list);
|
||||
}
|
||||
|
||||
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, ChannelInfo channelInfo, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||
{
|
||||
var tunerCount = info.TunerCount;
|
||||
var tunerCount = tunerHost.TunerCount;
|
||||
|
||||
if (tunerCount > 0)
|
||||
{
|
||||
var tunerHostId = info.Id;
|
||||
var tunerHostId = tunerHost.Id;
|
||||
var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (liveStreams.Count() >= tunerCount)
|
||||
|
@ -111,7 +111,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
}
|
||||
}
|
||||
|
||||
var sources = await GetChannelStreamMediaSources(info, channelInfo, cancellationToken).ConfigureAwait(false);
|
||||
var sources = await GetChannelStreamMediaSources(tunerHost, channel, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var mediaSource = sources[0];
|
||||
|
||||
|
@ -121,11 +121,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
|
||||
if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
|
||||
return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return new LiveStream(mediaSource, info, FileSystem, Logger, Config, _streamHelper);
|
||||
return new LiveStream(mediaSource, tunerHost, FileSystem, Logger, Config, _streamHelper);
|
||||
}
|
||||
|
||||
public async Task Validate(TunerHostInfo info)
|
||||
|
@ -135,9 +135,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||
}
|
||||
}
|
||||
|
||||
protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, ChannelInfo channelInfo, CancellationToken cancellationToken)
|
||||
protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, ChannelInfo channel, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(new List<MediaSourceInfo> { CreateMediaSourceInfo(info, channelInfo) });
|
||||
return Task.FromResult(new List<MediaSourceInfo> { CreateMediaSourceInfo(tuner, channel) });
|
||||
}
|
||||
|
||||
protected virtual MediaSourceInfo CreateMediaSourceInfo(TunerHostInfo info, ChannelInfo channel)
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Emby.Server.Implementations.Net
|
|||
{
|
||||
public class SocketFactory : ISocketFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ISocket CreateUdpBroadcastSocket(int localPort)
|
||||
{
|
||||
if (localPort < 0)
|
||||
|
@ -35,11 +36,8 @@ namespace Emby.Server.Implementations.Net
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new UDP acceptSocket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
|
||||
/// </summary>
|
||||
/// <returns>An implementation of the <see cref="ISocket"/> interface used by RSSDP components to perform acceptSocket operations.</returns>
|
||||
public ISocket CreateSsdpUdpSocket(IPAddress localIpAddress, int localPort)
|
||||
/// <inheritdoc />
|
||||
public ISocket CreateSsdpUdpSocket(IPAddress localIp, int localPort)
|
||||
{
|
||||
if (localPort < 0)
|
||||
{
|
||||
|
@ -53,8 +51,8 @@ namespace Emby.Server.Implementations.Net
|
|||
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
|
||||
|
||||
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress));
|
||||
return new UdpSocket(retVal, localPort, localIpAddress);
|
||||
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp));
|
||||
return new UdpSocket(retVal, localPort, localIp);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -64,13 +62,7 @@ namespace Emby.Server.Implementations.Net
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new UDP acceptSocket that is a member of the specified multicast IP address, and binds it to the specified local port.
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">The multicast IP address to make the acceptSocket a member of.</param>
|
||||
/// <param name="multicastTimeToLive">The multicast time to live value for the acceptSocket.</param>
|
||||
/// <param name="localPort">The number of the local port to bind to.</param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc />
|
||||
public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort)
|
||||
{
|
||||
if (ipAddress == null)
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Net
|
|||
return taskCompletion.Task;
|
||||
}
|
||||
|
||||
public Task SendToAsync(byte[] buffer, int offset, int size, IPEndPoint endPoint, CancellationToken cancellationToken)
|
||||
public Task SendToAsync(byte[] buffer, int offset, int bytes, IPEndPoint endPoint, CancellationToken cancellationToken)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
|
@ -214,7 +214,7 @@ namespace Emby.Server.Implementations.Net
|
|||
}
|
||||
};
|
||||
|
||||
var result = BeginSendTo(buffer, offset, size, endPoint, new AsyncCallback(callback), null);
|
||||
var result = BeginSendTo(buffer, offset, bytes, endPoint, new AsyncCallback(callback), null);
|
||||
|
||||
if (result.CompletedSynchronously)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class.
|
||||
/// </summary>
|
||||
/// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
||||
public DeleteCacheFileTask(
|
||||
IApplicationPaths appPaths,
|
||||
ILogger<DeleteCacheFileTask> logger,
|
||||
|
|
|
@ -235,12 +235,12 @@ namespace Emby.Server.Implementations.Session
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void UpdateDeviceName(string sessionId, string deviceName)
|
||||
public void UpdateDeviceName(string sessionId, string reportedDeviceName)
|
||||
{
|
||||
var session = GetSession(sessionId);
|
||||
if (session != null)
|
||||
{
|
||||
session.DeviceName = deviceName;
|
||||
session.DeviceName = reportedDeviceName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,14 +316,14 @@ namespace Emby.Server.Implementations.Session
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnSessionControllerConnected(SessionInfo info)
|
||||
public void OnSessionControllerConnected(SessionInfo session)
|
||||
{
|
||||
EventHelper.QueueEventIfNotNull(
|
||||
SessionControllerConnected,
|
||||
this,
|
||||
new SessionEventArgs
|
||||
{
|
||||
SessionInfo = info
|
||||
SessionInfo = session
|
||||
},
|
||||
_logger);
|
||||
}
|
||||
|
@ -1581,16 +1581,16 @@ namespace Emby.Server.Implementations.Session
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Logout(Device existing)
|
||||
public async Task Logout(Device device)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
_logger.LogInformation("Logging out access token {0}", existing.AccessToken);
|
||||
_logger.LogInformation("Logging out access token {0}", device.AccessToken);
|
||||
|
||||
await _deviceManager.DeleteDevice(existing).ConfigureAwait(false);
|
||||
await _deviceManager.DeleteDevice(device).ConfigureAwait(false);
|
||||
|
||||
var sessions = Sessions
|
||||
.Where(i => string.Equals(i.DeviceId, existing.DeviceId, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(i => string.Equals(i.DeviceId, device.DeviceId, StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
foreach (var session in sessions)
|
||||
|
@ -1601,7 +1601,7 @@ namespace Emby.Server.Implementations.Session
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Error reporting session ended", ex);
|
||||
_logger.LogError(ex, "Error reporting session ended");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ namespace Emby.Server.Implementations.TV
|
|||
_configurationManager = configurationManager;
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery request, DtoOptions dtoOptions)
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery query, DtoOptions options)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
@ -43,9 +43,9 @@ namespace Emby.Server.Implementations.TV
|
|||
}
|
||||
|
||||
string presentationUniqueKey = null;
|
||||
if (!string.IsNullOrEmpty(request.SeriesId))
|
||||
if (!string.IsNullOrEmpty(query.SeriesId))
|
||||
{
|
||||
if (_libraryManager.GetItemById(request.SeriesId) is Series series)
|
||||
if (_libraryManager.GetItemById(query.SeriesId) is Series series)
|
||||
{
|
||||
presentationUniqueKey = GetUniqueSeriesKey(series);
|
||||
}
|
||||
|
@ -53,14 +53,14 @@ namespace Emby.Server.Implementations.TV
|
|||
|
||||
if (!string.IsNullOrEmpty(presentationUniqueKey))
|
||||
{
|
||||
return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request);
|
||||
return GetResult(GetNextUpEpisodes(query, user, new[] { presentationUniqueKey }, options), query);
|
||||
}
|
||||
|
||||
BaseItem[] parents;
|
||||
|
||||
if (request.ParentId.HasValue)
|
||||
if (query.ParentId.HasValue)
|
||||
{
|
||||
var parent = _libraryManager.GetItemById(request.ParentId.Value);
|
||||
var parent = _libraryManager.GetItemById(query.ParentId.Value);
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
|
@ -79,10 +79,10 @@ namespace Emby.Server.Implementations.TV
|
|||
.ToArray();
|
||||
}
|
||||
|
||||
return GetNextUp(request, parents, dtoOptions);
|
||||
return GetNextUp(query, parents, options);
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery request, BaseItem[] parentsFolders, DtoOptions dtoOptions)
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery request, BaseItem[] parentsFolders, DtoOptions options)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace Emby.Server.Implementations.TV
|
|||
|
||||
if (!string.IsNullOrEmpty(presentationUniqueKey))
|
||||
{
|
||||
return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request);
|
||||
return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, options), request);
|
||||
}
|
||||
|
||||
if (limit.HasValue)
|
||||
|
@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.TV
|
|||
.Select(GetUniqueSeriesKey);
|
||||
|
||||
// Avoid implicitly captured closure
|
||||
var episodes = GetNextUpEpisodes(request, user, items, dtoOptions);
|
||||
var episodes = GetNextUpEpisodes(request, user, items, options);
|
||||
|
||||
return GetResult(episodes, request);
|
||||
}
|
||||
|
|
|
@ -97,8 +97,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
try
|
||||
{
|
||||
var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) as LibraryOptions;
|
||||
if (result == null)
|
||||
if (XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) is not LibraryOptions result)
|
||||
{
|
||||
return new LibraryOptions();
|
||||
}
|
||||
|
|
|
@ -104,13 +104,6 @@ namespace MediaBrowser.Controller
|
|||
/// <returns>The API URL.</returns>
|
||||
string GetLocalApiUrl(string hostname, string scheme = null, int? port = null);
|
||||
|
||||
/// <summary>
|
||||
/// Open a URL in an external browser window.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to open.</param>
|
||||
/// <exception cref="NotSupportedException"><see cref="CanLaunchWebBrowser"/> is false.</exception>
|
||||
void LaunchUrl(string url);
|
||||
|
||||
IEnumerable<WakeOnLanInfo> GetWakeOnLanInfo();
|
||||
|
||||
string ExpandVirtualPath(string path);
|
||||
|
|
|
@ -595,11 +595,11 @@ namespace MediaBrowser.Controller.Library
|
|||
|
||||
Task RemoveVirtualFolder(string name, bool refreshLibrary);
|
||||
|
||||
void AddMediaPath(string virtualFolderName, MediaPathInfo path);
|
||||
void AddMediaPath(string virtualFolderName, MediaPathInfo mediaPath);
|
||||
|
||||
void UpdateMediaPath(string virtualFolderName, MediaPathInfo path);
|
||||
void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath);
|
||||
|
||||
void RemoveMediaPath(string virtualFolderName, string path);
|
||||
void RemoveMediaPath(string virtualFolderName, string mediaPath);
|
||||
|
||||
QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, User user);
|
||||
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions dto_options);
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Get all user data for the given user.
|
||||
|
@ -69,8 +69,8 @@ namespace MediaBrowser.Controller.Library
|
|||
/// </summary>
|
||||
/// <param name="item">Item to update.</param>
|
||||
/// <param name="data">Data to update.</param>
|
||||
/// <param name="positionTicks">New playstate.</param>
|
||||
/// <param name="reportedPositionTicks">New playstate.</param>
|
||||
/// <returns>True if playstate was updated.</returns>
|
||||
bool UpdatePlayState(BaseItem item, UserItemData data, long? positionTicks);
|
||||
bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
|
||||
Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber);
|
||||
|
||||
TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, NameValuePair[] mappings, List<ChannelInfo> providerChannels);
|
||||
TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> providerChannels);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lineups.
|
||||
|
|
|
@ -70,10 +70,10 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <summary>
|
||||
/// Updates the timer asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="updatedTimer">The updated timer information.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken);
|
||||
Task UpdateTimerAsync(TimerInfo updatedTimer, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the series timer asynchronous.
|
||||
|
|
|
@ -49,17 +49,17 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// <summary>
|
||||
/// Gets chapters for an item.
|
||||
/// </summary>
|
||||
/// <param name="id">The item.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The list of chapter info.</returns>
|
||||
List<ChapterInfo> GetChapters(BaseItem id);
|
||||
List<ChapterInfo> GetChapters(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single chapter for an item.
|
||||
/// </summary>
|
||||
/// <param name="id">The item.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="index">The chapter index.</param>
|
||||
/// <returns>The chapter info at the specified index.</returns>
|
||||
ChapterInfo GetChapter(BaseItem id, int index);
|
||||
ChapterInfo GetChapter(BaseItem item, int index);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
|
|
|
@ -344,7 +344,7 @@ namespace MediaBrowser.Controller.Session
|
|||
/// <returns>A <see cref="Task"/> representing the log out process.</returns>
|
||||
Task Logout(string accessToken);
|
||||
|
||||
Task Logout(Device accessToken);
|
||||
Task Logout(Device device);
|
||||
|
||||
/// <summary>
|
||||
/// Revokes the user tokens.
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
var stream = TargetAudioStream;
|
||||
return AudioSampleRate.HasValue && !IsDirectStream
|
||||
? AudioSampleRate
|
||||
: stream == null ? null : stream.SampleRate;
|
||||
: stream?.SampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
|
||||
return TargetAudioStream?.BitDepth;
|
||||
}
|
||||
|
||||
var targetAudioCodecs = TargetAudioCodec;
|
||||
|
@ -156,7 +156,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetTargetAudioBitDepth(audioCodec);
|
||||
}
|
||||
|
||||
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth;
|
||||
return TargetAudioStream?.BitDepth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
|
||||
return TargetVideoStream?.BitDepth;
|
||||
}
|
||||
|
||||
var targetVideoCodecs = TargetVideoCodec;
|
||||
|
@ -179,7 +179,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetTargetVideoBitDepth(videoCodec);
|
||||
}
|
||||
|
||||
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth;
|
||||
return TargetVideoStream?.BitDepth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
|
||||
return TargetVideoStream?.RefFrames;
|
||||
}
|
||||
|
||||
var targetVideoCodecs = TargetVideoCodec;
|
||||
|
@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetTargetRefFrames(videoCodec);
|
||||
}
|
||||
|
||||
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
|
||||
return TargetVideoStream?.RefFrames;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
|
||||
return TargetVideoStream?.Level;
|
||||
}
|
||||
|
||||
var targetVideoCodecs = TargetVideoCodec;
|
||||
|
@ -240,7 +240,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetTargetVideoLevel(videoCodec);
|
||||
}
|
||||
|
||||
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
|
||||
return TargetVideoStream?.Level;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
var stream = TargetVideoStream;
|
||||
return !IsDirectStream
|
||||
? null
|
||||
: stream == null ? null : stream.PacketLength;
|
||||
: stream?.PacketLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
|
||||
return TargetVideoStream?.Profile;
|
||||
}
|
||||
|
||||
var targetVideoCodecs = TargetVideoCodec;
|
||||
|
@ -277,7 +277,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetOption(videoCodec, "profile");
|
||||
}
|
||||
|
||||
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
|
||||
return TargetVideoStream?.Profile;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
var stream = TargetVideoStream;
|
||||
return !IsDirectStream
|
||||
? null
|
||||
: stream == null ? null : stream.CodecTag;
|
||||
: stream?.CodecTag;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
var stream = TargetAudioStream;
|
||||
return AudioBitrate.HasValue && !IsDirectStream
|
||||
? AudioBitrate
|
||||
: stream == null ? null : stream.BitRate;
|
||||
: stream?.BitRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
|
||||
return TargetAudioStream?.Channels;
|
||||
}
|
||||
|
||||
var targetAudioCodecs = TargetAudioCodec;
|
||||
|
@ -329,7 +329,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
return GetTargetRefFrames(codec);
|
||||
}
|
||||
|
||||
return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels;
|
||||
return TargetAudioStream?.Channels;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,7 +425,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
|
||||
return VideoBitrate.HasValue && !IsDirectStream
|
||||
? VideoBitrate
|
||||
: stream == null ? null : stream.BitRate;
|
||||
: stream?.BitRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic;
|
||||
return TargetVideoStream?.IsAnamorphic;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -464,7 +464,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
|
||||
return TargetVideoStream?.IsInterlaced;
|
||||
}
|
||||
|
||||
var targetVideoCodecs = TargetVideoCodec;
|
||||
|
@ -477,7 +477,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
}
|
||||
}
|
||||
|
||||
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
|
||||
return TargetVideoStream?.IsInterlaced;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,7 +487,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return TargetVideoStream == null ? null : TargetVideoStream.IsAVC;
|
||||
return TargetVideoStream?.IsAVC;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -618,20 +618,20 @@ namespace MediaBrowser.Model.Dlna
|
|||
}
|
||||
|
||||
// Try to keep the url clean by omitting defaults
|
||||
if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
|
||||
}
|
||||
|
||||
string queryString = string.Join("&", list.ToArray());
|
||||
string queryString = string.Join('&', list);
|
||||
|
||||
return GetUrl(baseUrl, queryString);
|
||||
}
|
||||
|
@ -681,11 +681,11 @@ namespace MediaBrowser.Model.Dlna
|
|||
|
||||
string audioCodecs = item.AudioCodecs.Length == 0 ?
|
||||
string.Empty :
|
||||
string.Join(",", item.AudioCodecs);
|
||||
string.Join(',', item.AudioCodecs);
|
||||
|
||||
string videoCodecs = item.VideoCodecs.Length == 0 ?
|
||||
string.Empty :
|
||||
string.Join(",", item.VideoCodecs);
|
||||
string.Join(',', item.VideoCodecs);
|
||||
|
||||
list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
|
||||
list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
|
||||
|
@ -1024,30 +1024,5 @@ namespace MediaBrowser.Model.Dlna
|
|||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<MediaStream> GetSelectableAudioStreams()
|
||||
{
|
||||
return GetSelectableStreams(MediaStreamType.Audio);
|
||||
}
|
||||
|
||||
public List<MediaStream> GetSelectableSubtitleStreams()
|
||||
{
|
||||
return GetSelectableStreams(MediaStreamType.Subtitle);
|
||||
}
|
||||
|
||||
public List<MediaStream> GetSelectableStreams(MediaStreamType type)
|
||||
{
|
||||
var list = new List<MediaStream>();
|
||||
|
||||
foreach (var stream in MediaSource.MediaStreams)
|
||||
{
|
||||
if (type == stream.Type)
|
||||
{
|
||||
list.Add(stream);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
<Rule Id="SA1101" Action="None" />
|
||||
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
|
||||
<Rule Id="SA1108" Action="None" />
|
||||
<!-- disable warning SA1118: Parameter must not span multiple lines. -->
|
||||
<Rule Id="SA1118" Action="None" />
|
||||
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
|
||||
<Rule Id="SA1128" Action="None" />
|
||||
<!-- disable warning SA1130: Use lambda syntax -->
|
||||
|
@ -39,6 +41,10 @@
|
|||
</Rules>
|
||||
|
||||
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<!-- error on CA1305: Specify IFormatProvider -->
|
||||
<Rule Id="CA1305" Action="Error" />
|
||||
<!-- error on CA1725: Parameter names should match base declaration -->
|
||||
<Rule Id="CA1725" Action="Error" />
|
||||
<!-- error on CA2016: Forward the CancellationToken parameter to methods that take one
|
||||
or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
|
||||
<Rule Id="CA2016" Action="Error" />
|
||||
|
|
Loading…
Reference in New Issue
Block a user