Fix some warnings

This commit is contained in:
Bond_009 2021-09-03 18:46:34 +02:00
parent fb5385f1df
commit 637e86478f
31 changed files with 366 additions and 451 deletions

View File

@ -114,6 +114,11 @@ namespace Emby.Server.Implementations
/// </summary> /// </summary>
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" }; 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 IFileSystem _fileSystemManager;
private readonly IConfiguration _startupConfig; private readonly IConfiguration _startupConfig;
private readonly IXmlSerializer _xmlSerializer; private readonly IXmlSerializer _xmlSerializer;
@ -125,104 +130,15 @@ namespace Emby.Server.Implementations
private ISessionManager _sessionManager; private ISessionManager _sessionManager;
private string[] _urlPrefixes; 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> /// <summary>
/// Gets or sets all concrete types. /// Gets or sets all concrete types.
/// </summary> /// </summary>
/// <value>All concrete types.</value> /// <value>All concrete types.</value>
private Type[] _allConcreteTypes; private Type[] _allConcreteTypes;
/// <summary> private DeviceId _deviceId;
/// The disposable parts.
/// </summary>
private readonly List<IDisposable> _disposableParts = new List<IDisposable>();
/// <summary> private bool _disposed = false;
/// 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];
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost"/> class. /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
@ -265,6 +181,143 @@ namespace Emby.Server.Implementations
ApplicationVersion); 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> /// <summary>
/// Temporary function to migration network settings out of system.xml and into network.xml. /// 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. /// 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); .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> /// <summary>
/// Creates an instance of type and resolves all constructor dependencies. /// Creates an instance of type and resolves all constructor dependencies.
/// </summary> /// </summary>
@ -857,10 +871,6 @@ namespace Emby.Server.Implementations
} }
} }
private CertificateInfo CertificateInfo { get; set; }
public X509Certificate2 Certificate { get; private set; }
private IEnumerable<string> GetUrlPrefixes() private IEnumerable<string> GetUrlPrefixes()
{ {
var hosts = new[] { "+" }; var hosts = new[] { "+" };
@ -1114,9 +1124,6 @@ namespace Emby.Server.Implementations
}; };
} }
/// <inheritdoc/>
public bool ListenWithHttps => Certificate != null && ConfigurationManager.GetNetworkConfiguration().EnableHttps;
/// <inheritdoc/> /// <inheritdoc/>
public string GetSmartApiUrl(IPAddress remoteAddr, int? port = null) public string GetSmartApiUrl(IPAddress remoteAddr, int? port = null)
{ {
@ -1203,14 +1210,7 @@ namespace Emby.Server.Implementations
}.ToString().TrimEnd('/'); }.ToString().TrimEnd('/');
} }
public string FriendlyName => /// <inheritdoc />
string.IsNullOrEmpty(ConfigurationManager.Configuration.ServerName)
? Environment.MachineName
: ConfigurationManager.Configuration.ServerName;
/// <summary>
/// Shuts down.
/// </summary>
public async Task Shutdown() public async Task Shutdown()
{ {
if (IsShuttingDown) if (IsShuttingDown)
@ -1248,41 +1248,7 @@ namespace Emby.Server.Implementations
} }
} }
public virtual void LaunchUrl(string url) /// <inheritdoc />
{
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>
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);

View File

@ -196,8 +196,8 @@ namespace Emby.Server.Implementations.Collections
} }
/// <inheritdoc /> /// <inheritdoc />
public Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> ids) public Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> itemIds)
=> AddToCollectionAsync(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem))); => AddToCollectionAsync(collectionId, itemIds, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem)));
private async Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) private async Task AddToCollectionAsync(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
{ {

View File

@ -1902,12 +1902,7 @@ namespace Emby.Server.Implementations.Data
return result; return result;
} }
/// <summary> /// <inheritdoc />
/// Gets chapters for an item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IEnumerable{ChapterInfo}.</returns>
/// <exception cref="ArgumentNullException">id</exception>
public List<ChapterInfo> GetChapters(BaseItem item) public List<ChapterInfo> GetChapters(BaseItem item)
{ {
CheckDisposed(); CheckDisposed();
@ -1930,13 +1925,7 @@ namespace Emby.Server.Implementations.Data
} }
} }
/// <summary> /// <inheritdoc />
/// 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>
public ChapterInfo GetChapter(BaseItem item, int index) public ChapterInfo GetChapter(BaseItem item, int index)
{ {
CheckDisposed(); CheckDisposed();
@ -2048,7 +2037,7 @@ namespace Emby.Server.Implementations.Data
for (var i = startIndex; i < endIndex; i++) 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 , insertText.Length -= 1; // Remove last ,

View File

@ -129,19 +129,17 @@ namespace Emby.Server.Implementations.Data
return list; return list;
} }
/// <summary> /// <inheritdoc />
/// Saves the user data. public void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken)
/// </summary>
public void SaveUserData(long internalUserId, string key, UserItemData userData, CancellationToken cancellationToken)
{ {
if (userData == null) if (userData == null)
{ {
throw new ArgumentNullException(nameof(userData)); 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)) if (string.IsNullOrEmpty(key))
@ -149,22 +147,23 @@ namespace Emby.Server.Implementations.Data
throw new ArgumentNullException(nameof(key)); 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) if (userData == null)
{ {
throw new ArgumentNullException(nameof(userData)); 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> /// <summary>
@ -263,19 +262,19 @@ namespace Emby.Server.Implementations.Data
/// <summary> /// <summary>
/// Gets the user data. /// Gets the user data.
/// </summary> /// </summary>
/// <param name="internalUserId">The user id.</param> /// <param name="userId">The user id.</param>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
/// <returns>Task{UserItemData}.</returns> /// <returns>Task{UserItemData}.</returns>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// userId /// userId
/// or /// or
/// key /// key.
/// </exception> /// </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)) 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")) 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); statement.TryBind("@Key", key);
foreach (var row in statement.ExecuteQuery()) 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) if (keys == null)
{ {
@ -312,19 +311,19 @@ namespace Emby.Server.Implementations.Data
return null; return null;
} }
return GetUserData(internalUserId, keys[0]); return GetUserData(userId, keys[0]);
} }
/// <summary> /// <summary>
/// Return all user-data associated with the given user. /// Return all user-data associated with the given user.
/// </summary> /// </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> /// <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>(); 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")) 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()) foreach (var row in statement.ExecuteQuery())
{ {

View File

@ -51,8 +51,6 @@ namespace Emby.Server.Implementations.Dto
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly Lazy<ILiveTvManager> _livetvManagerFactory; private readonly Lazy<ILiveTvManager> _livetvManagerFactory;
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
public DtoService( public DtoService(
ILogger<DtoService> logger, ILogger<DtoService> logger,
ILibraryManager libraryManager, ILibraryManager libraryManager,
@ -75,6 +73,8 @@ namespace Emby.Server.Implementations.Dto
_livetvManagerFactory = livetvManagerFactory; _livetvManagerFactory = livetvManagerFactory;
} }
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<BaseItemDto> GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null) 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> /// </summary>
/// <param name="dto">The dto.</param> /// <param name="dto">The dto.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>Task.</returns>
private void AttachPeople(BaseItemDto dto, BaseItem item) private void AttachPeople(BaseItemDto dto, BaseItem item)
{ {
// Ordering by person type to ensure actors and artists are at the front. // Ordering by person type to ensure actors and artists are at the front.
@ -616,7 +615,6 @@ namespace Emby.Server.Implementations.Dto
/// </summary> /// </summary>
/// <param name="dto">The dto.</param> /// <param name="dto">The dto.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>Task.</returns>
private void AttachStudios(BaseItemDto dto, BaseItem item) private void AttachStudios(BaseItemDto dto, BaseItem item)
{ {
dto.Studios = item.Studios dto.Studios = item.Studios
@ -1313,9 +1311,12 @@ namespace Emby.Server.Implementations.Dto
var imageTags = dto.ImageTags; 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) && while ((!(imageTags != null && imageTags.ContainsKey(ImageType.Logo)) && logoLimit > 0)
(parent ??= (isFirst ? GetImageDisplayParent(item, item) ?? owner : parent)) != null) || (!(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) if (parent == null)
{ {
break; break;
@ -1395,7 +1396,6 @@ namespace Emby.Server.Implementations.Dto
/// </summary> /// </summary>
/// <param name="dto">The dto.</param> /// <param name="dto">The dto.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>Task.</returns>
public void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item) public void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item)
{ {
dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item);

View File

@ -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()) if (!OperatingSystem.IsWindows())
{ {
@ -437,14 +437,14 @@ namespace Emby.Server.Implementations.IO
return; return;
} }
if (info.IsReadOnly == isReadOnly && info.IsHidden == isHidden) if (info.IsReadOnly == readOnly && info.IsHidden == isHidden)
{ {
return; return;
} }
var attributes = File.GetAttributes(path); var attributes = File.GetAttributes(path);
if (isReadOnly) if (readOnly)
{ {
attributes = attributes | FileAttributes.ReadOnly; attributes = attributes | FileAttributes.ReadOnly;
} }

View File

@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Images
public int Order => 0; 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) public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{ {

View File

@ -1761,22 +1761,20 @@ namespace Emby.Server.Implementations.Library
return orderedItems ?? items; 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; var isFirst = true;
IOrderedEnumerable<BaseItem> orderedItems = null; 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) if (comparer == null)
{ {
continue; continue;
} }
var sortOrder = orderBy.Item2;
if (isFirst) if (isFirst)
{ {
orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer); 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) 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; var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
@ -3148,9 +3146,9 @@ namespace Emby.Server.Implementations.Library
var list = libraryOptions.PathInfos.ToList(); var list = libraryOptions.PathInfos.ToList();
foreach (var originalPathInfo in list) 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; break;
} }
} }

View File

@ -36,9 +36,10 @@ namespace Emby.Server.Implementations.Library
return list.Concat(GetInstantMixFromGenres(item.Genres, user, dtoOptions)).ToList(); 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) public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User user, DtoOptions dtoOptions)

View File

@ -21,13 +21,13 @@ namespace Emby.Server.Implementations.Library.Resolvers
public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T> public abstract class BaseVideoResolver<T> : MediaBrowser.Controller.Resolvers.ItemResolver<T>
where T : Video, new() where T : Video, new()
{ {
protected readonly ILibraryManager LibraryManager;
protected BaseVideoResolver(ILibraryManager libraryManager) protected BaseVideoResolver(ILibraryManager libraryManager)
{ {
LibraryManager = libraryManager; LibraryManager = libraryManager;
} }
protected ILibraryManager LibraryManager { get; }
/// <summary> /// <summary>
/// Resolves the specified args. /// Resolves the specified args.
/// </summary> /// </summary>

View File

@ -177,6 +177,7 @@ namespace Emby.Server.Implementations.Library
return dto; return dto;
} }
/// <inheritdoc />
public UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions options) public UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions options)
{ {
var userData = GetUserData(user, item); var userData = GetUserData(user, item);
@ -191,7 +192,7 @@ namespace Emby.Server.Implementations.Library
/// </summary> /// </summary>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>DtoUserItemData.</returns> /// <returns>DtoUserItemData.</returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
private UserItemDataDto GetUserItemDataDto(UserItemData data) private UserItemDataDto GetUserItemDataDto(UserItemData data)
{ {
if (data == null) if (data == null)
@ -212,6 +213,7 @@ namespace Emby.Server.Implementations.Library
}; };
} }
/// <inheritdoc />
public bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks) public bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks)
{ {
var playedToCompletion = false; var playedToCompletion = false;

View File

@ -610,11 +610,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
throw new NotImplementedException(); 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 : null :
_timerProvider.GetTimerByProgramId(timer.ProgramId); _timerProvider.GetTimerByProgramId(info.ProgramId);
if (existingTimer != null) 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; LiveTvProgram programInfo = null;
if (!string.IsNullOrWhiteSpace(timer.ProgramId)) if (!string.IsNullOrWhiteSpace(info.ProgramId))
{ {
programInfo = GetProgramInfoFromCache(timer); programInfo = GetProgramInfoFromCache(info);
} }
if (programInfo == null) if (programInfo == null)
{ {
_logger.LogInformation("Unable to find program with Id {0}. Will search using start date", timer.ProgramId); _logger.LogInformation("Unable to find program with Id {0}. Will search using start date", info.ProgramId);
programInfo = GetProgramInfoFromCache(timer.ChannelId, timer.StartDate); programInfo = GetProgramInfoFromCache(info.ChannelId, info.StartDate);
} }
if (programInfo != null) if (programInfo != null)
{ {
CopyProgramInfoToTimerInfo(programInfo, timer); CopyProgramInfoToTimerInfo(programInfo, info);
} }
timer.IsManual = true; info.IsManual = true;
_timerProvider.Add(timer); _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) public async Task<string> CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken)

View File

@ -65,6 +65,8 @@ namespace Emby.Server.Implementations.LiveTv
private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>(); private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>();
private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>(); private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>();
private bool _disposed = false;
public LiveTvManager( public LiveTvManager(
IServerConfigurationManager config, IServerConfigurationManager config,
ILogger<LiveTvManager> logger, ILogger<LiveTvManager> logger,
@ -520,7 +522,7 @@ namespace Emby.Server.Implementations.LiveTv
return item; 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); var id = _tvDtoService.GetInternalProgramId(info.Id);
@ -559,8 +561,6 @@ namespace Emby.Server.Implementations.LiveTv
item.ParentId = channel.Id; item.ParentId = channel.Id;
// item.ChannelType = channelType;
item.Audio = info.Audio; item.Audio = info.Audio;
item.ChannelId = channel.Id; item.ChannelId = channel.Id;
item.CommunityRating ??= info.CommunityRating; item.CommunityRating ??= info.CommunityRating;
@ -772,7 +772,7 @@ namespace Emby.Server.Implementations.LiveTv
item.OnMetadataChanged(); 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) 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) foreach (var program in channelPrograms)
{ {
var programTuple = GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken); var programTuple = GetProgram(program, existingPrograms, currentChannel);
var programItem = programTuple.Item1; var programItem = programTuple.item;
if (programTuple.Item2) if (programTuple.isNew)
{ {
newPrograms.Add(programItem); newPrograms.Add(programItem);
} }
else if (programTuple.Item3) else if (programTuple.isUpdated)
{ {
updatedPrograms.Add(programItem); 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(); // var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
// return new QueryResult<BaseItem> // return new QueryResult<BaseItem>
//{ // {
// Items = items, // Items = items,
// TotalRecordCount = items.Length // TotalRecordCount = items.Length
//}; // };
dtoOptions.Fields = dtoOptions.Fields.Concat(new[] { ItemFields.Tags }).Distinct().ToArray(); dtoOptions.Fields = dtoOptions.Fields.Concat(new[] { ItemFields.Tags }).Distinct().ToArray();
} }
@ -1425,16 +1425,15 @@ namespace Emby.Server.Implementations.LiveTv
return result; 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 programTuples = new List<Tuple<BaseItemDto, string, string>>();
var hasChannelImage = fields.Contains(ItemFields.ChannelImage); var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
var hasChannelInfo = fields.Contains(ItemFields.ChannelInfo); var hasChannelInfo = fields.Contains(ItemFields.ChannelInfo);
foreach (var tuple in tuples) foreach (var (item, dto) in programs)
{ {
var program = (LiveTvProgram)tuple.Item1; var program = (LiveTvProgram)item;
var dto = tuple.Item2;
dto.StartDate = program.StartDate; dto.StartDate = program.StartDate;
dto.EpisodeTitle = program.EpisodeTitle; dto.EpisodeTitle = program.EpisodeTitle;
@ -1871,11 +1870,11 @@ namespace Emby.Server.Implementations.LiveTv
return _libraryManager.GetItemById(internalChannelId); 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 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) var programs = options.AddCurrentProgram ? _libraryManager.GetItemList(new InternalItemsQuery(user)
{ {
@ -1896,7 +1895,7 @@ namespace Emby.Server.Implementations.LiveTv
var addCurrentProgram = options.AddCurrentProgram; var addCurrentProgram = options.AddCurrentProgram;
foreach (var tuple in tuples) foreach (var tuple in items)
{ {
var dto = tuple.Item1; var dto = tuple.Item1;
var channel = tuple.Item2; var channel = tuple.Item2;
@ -2118,17 +2117,13 @@ namespace Emby.Server.Implementations.LiveTv
}; };
} }
/// <summary> /// <inheritdoc />
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
private bool _disposed = false;
/// <summary> /// <summary>
/// Releases unmanaged and - optionally - managed resources. /// Releases unmanaged and - optionally - managed resources.
/// </summary> /// </summary>
@ -2324,20 +2319,20 @@ namespace Emby.Server.Implementations.LiveTv
_taskManager.CancelIfRunningAndQueue<RefreshGuideScheduledTask>(); _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 config = GetConfiguration();
var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase)); 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(); var list = listingsProviderInfo.ChannelMappings.ToList();
list.Add(new NameValuePair list.Add(new NameValuePair
{ {
Name = tunerChannelId, Name = tunerChannelNumber,
Value = providerChannelId Value = providerChannelNumber
}); });
listingsProviderInfo.ChannelMappings = list.ToArray(); listingsProviderInfo.ChannelMappings = list.ToArray();
} }
@ -2357,10 +2352,10 @@ namespace Emby.Server.Implementations.LiveTv
_taskManager.CancelIfRunningAndQueue<RefreshGuideScheduledTask>(); _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 var result = new TunerChannelMapping
{ {
@ -2373,7 +2368,7 @@ namespace Emby.Server.Implementations.LiveTv
result.Name = tunerChannel.Number + " " + result.Name; 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) if (providerChannel != null)
{ {

View File

@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return new List<MediaSourceInfo>(); 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) public async Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
{ {

View File

@ -95,17 +95,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
public bool IsLegacyTuner { get; set; } 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 return lineup.Select(i => new HdHomerunChannelInfo
{ {
Name = i.GuideName, Name = i.GuideName,
Number = i.GuideNumber, Number = i.GuideNumber,
Id = GetChannelId(info, i), Id = GetChannelId(tuner, i),
IsFavorite = i.Favorite, IsFavorite = i.Favorite,
TunerHostId = info.Id, TunerHostId = tuner.Id,
IsHD = i.HD, IsHD = i.HD,
AudioCodec = i.AudioCodec, AudioCodec = i.AudioCodec,
VideoCodec = i.VideoCodec, VideoCodec = i.VideoCodec,
@ -496,57 +496,53 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return mediaSource; 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 list = new List<MediaSourceInfo>();
var channelId = channelInfo.Id; var channelId = channel.Id;
var hdhrId = GetHdHrIdFromChannelId(channelId); var hdhrId = GetHdHrIdFromChannelId(channelId);
var hdHomerunChannelInfo = channelInfo as HdHomerunChannelInfo; if (channel is HdHomerunChannelInfo hdHomerunChannelInfo && hdHomerunChannelInfo.IsLegacyTuner)
var isLegacyTuner = hdHomerunChannelInfo != null && hdHomerunChannelInfo.IsLegacyTuner;
if (isLegacyTuner)
{ {
list.Add(GetMediaSource(info, hdhrId, channelInfo, "native")); list.Add(GetMediaSource(tuner, hdhrId, channel, "native"));
} }
else 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 (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(tuner, hdhrId, channel, "internet540"));
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet480")); list.Add(GetMediaSource(tuner, hdhrId, channel, "internet480"));
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet360")); list.Add(GetMediaSource(tuner, hdhrId, channel, "internet360"));
list.Add(GetMediaSource(info, hdhrId, channelInfo, "internet240")); list.Add(GetMediaSource(tuner, hdhrId, channel, "internet240"));
list.Add(GetMediaSource(info, hdhrId, channelInfo, "mobile")); 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) if (list.Count == 0)
{ {
list.Add(GetMediaSource(info, hdhrId, channelInfo, "native")); list.Add(GetMediaSource(tuner, hdhrId, channel, "native"));
} }
} }
return list; 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) if (tunerCount > 0)
{ {
var tunerHostId = info.Id; var tunerHostId = tunerHost.Id;
var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase)); var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase));
if (liveStreams.Count() >= tunerCount) if (liveStreams.Count() >= tunerCount)
@ -557,26 +553,26 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var profile = streamId.Split('_')[0]; 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) if (!modelInfo.SupportsTranscoding)
{ {
profile = "native"; profile = "native";
} }
var mediaSource = GetMediaSource(info, hdhrId, channelInfo, profile); var mediaSource = GetMediaSource(tunerHost, hdhrId, channel, profile);
if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner) if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
{ {
return new HdHomerunUdpStream( return new HdHomerunUdpStream(
mediaSource, mediaSource,
info, tunerHost,
streamId, streamId,
new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path), new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path),
modelInfo.TunerCount, modelInfo.TunerCount,
@ -592,7 +588,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{ {
mediaSource.Protocol = MediaProtocol.Http; mediaSource.Protocol = MediaProtocol.Http;
var httpUrl = channelInfo.Path; var httpUrl = channel.Path;
// If raw was used, the tuner doesn't support params // If raw was used, the tuner doesn't support params
if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase)) if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
@ -604,7 +600,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return new SharedHttpStream( return new SharedHttpStream(
mediaSource, mediaSource,
info, tunerHost,
streamId, streamId,
FileSystem, FileSystem,
_httpClientFactory, _httpClientFactory,
@ -616,7 +612,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return new HdHomerunUdpStream( return new HdHomerunUdpStream(
mediaSource, mediaSource,
info, tunerHost,
streamId, streamId,
new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), new HdHomerunChannelCommands(hdhomerunChannel.Number, profile),
modelInfo.TunerCount, modelInfo.TunerCount,

View File

@ -71,12 +71,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return ChannelIdPrefix + info.Url.GetMD5().ToString("N", CultureInfo.InvariantCulture); 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) return await new M3uParser(Logger, _httpClientFactory)
.Parse(info, channelIdPrefix, cancellationToken) .Parse(tuner, channelIdPrefix, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -96,13 +96,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list); 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) if (tunerCount > 0)
{ {
var tunerHostId = info.Id; var tunerHostId = tunerHost.Id;
var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase)); var liveStreams = currentLiveStreams.Where(i => string.Equals(i.TunerHostId, tunerHostId, StringComparison.OrdinalIgnoreCase));
if (liveStreams.Count() >= tunerCount) 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]; var mediaSource = sources[0];
@ -121,11 +121,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) 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) 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) protected virtual MediaSourceInfo CreateMediaSourceInfo(TunerHostInfo info, ChannelInfo channel)

View File

@ -11,6 +11,7 @@ namespace Emby.Server.Implementations.Net
{ {
public class SocketFactory : ISocketFactory public class SocketFactory : ISocketFactory
{ {
/// <inheritdoc />
public ISocket CreateUdpBroadcastSocket(int localPort) public ISocket CreateUdpBroadcastSocket(int localPort)
{ {
if (localPort < 0) if (localPort < 0)
@ -35,11 +36,8 @@ namespace Emby.Server.Implementations.Net
} }
} }
/// <summary> /// <inheritdoc />
/// Creates a new UDP acceptSocket that is a member of the SSDP multicast local admin group and binds it to the specified local port. public ISocket CreateSsdpUdpSocket(IPAddress localIp, int localPort)
/// </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)
{ {
if (localPort < 0) if (localPort < 0)
{ {
@ -53,8 +51,8 @@ namespace Emby.Server.Implementations.Net
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress)); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp));
return new UdpSocket(retVal, localPort, localIpAddress); return new UdpSocket(retVal, localPort, localIp);
} }
catch catch
{ {
@ -64,13 +62,7 @@ namespace Emby.Server.Implementations.Net
} }
} }
/// <summary> /// <inheritdoc />
/// 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>
public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort)
{ {
if (ipAddress == null) if (ipAddress == null)

View File

@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Net
return taskCompletion.Task; 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(); 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) if (result.CompletedSynchronously)
{ {

View File

@ -29,6 +29,10 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class. /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class.
/// </summary> /// </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( public DeleteCacheFileTask(
IApplicationPaths appPaths, IApplicationPaths appPaths,
ILogger<DeleteCacheFileTask> logger, ILogger<DeleteCacheFileTask> logger,

View File

@ -235,12 +235,12 @@ namespace Emby.Server.Implementations.Session
} }
/// <inheritdoc /> /// <inheritdoc />
public void UpdateDeviceName(string sessionId, string deviceName) public void UpdateDeviceName(string sessionId, string reportedDeviceName)
{ {
var session = GetSession(sessionId); var session = GetSession(sessionId);
if (session != null) if (session != null)
{ {
session.DeviceName = deviceName; session.DeviceName = reportedDeviceName;
} }
} }
@ -316,14 +316,14 @@ namespace Emby.Server.Implementations.Session
} }
/// <inheritdoc /> /// <inheritdoc />
public void OnSessionControllerConnected(SessionInfo info) public void OnSessionControllerConnected(SessionInfo session)
{ {
EventHelper.QueueEventIfNotNull( EventHelper.QueueEventIfNotNull(
SessionControllerConnected, SessionControllerConnected,
this, this,
new SessionEventArgs new SessionEventArgs
{ {
SessionInfo = info SessionInfo = session
}, },
_logger); _logger);
} }
@ -1581,16 +1581,16 @@ namespace Emby.Server.Implementations.Session
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task Logout(Device existing) public async Task Logout(Device device)
{ {
CheckDisposed(); 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 var sessions = Sessions
.Where(i => string.Equals(i.DeviceId, existing.DeviceId, StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(i.DeviceId, device.DeviceId, StringComparison.OrdinalIgnoreCase))
.ToList(); .ToList();
foreach (var session in sessions) foreach (var session in sessions)
@ -1601,7 +1601,7 @@ namespace Emby.Server.Implementations.Session
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError("Error reporting session ended", ex); _logger.LogError(ex, "Error reporting session ended");
} }
} }
} }

View File

@ -33,9 +33,9 @@ namespace Emby.Server.Implementations.TV
_configurationManager = configurationManager; _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) if (user == null)
{ {
@ -43,9 +43,9 @@ namespace Emby.Server.Implementations.TV
} }
string presentationUniqueKey = null; 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); presentationUniqueKey = GetUniqueSeriesKey(series);
} }
@ -53,14 +53,14 @@ namespace Emby.Server.Implementations.TV
if (!string.IsNullOrEmpty(presentationUniqueKey)) if (!string.IsNullOrEmpty(presentationUniqueKey))
{ {
return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request); return GetResult(GetNextUpEpisodes(query, user, new[] { presentationUniqueKey }, options), query);
} }
BaseItem[] parents; 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) if (parent != null)
{ {
@ -79,10 +79,10 @@ namespace Emby.Server.Implementations.TV
.ToArray(); .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); var user = _userManager.GetUserById(request.UserId);
@ -104,7 +104,7 @@ namespace Emby.Server.Implementations.TV
if (!string.IsNullOrEmpty(presentationUniqueKey)) 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) if (limit.HasValue)
@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.TV
.Select(GetUniqueSeriesKey); .Select(GetUniqueSeriesKey);
// Avoid implicitly captured closure // Avoid implicitly captured closure
var episodes = GetNextUpEpisodes(request, user, items, dtoOptions); var episodes = GetNextUpEpisodes(request, user, items, options);
return GetResult(episodes, request); return GetResult(episodes, request);
} }

View File

@ -97,8 +97,7 @@ namespace MediaBrowser.Controller.Entities
{ {
try try
{ {
var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) as LibraryOptions; if (XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) is not LibraryOptions result)
if (result == null)
{ {
return new LibraryOptions(); return new LibraryOptions();
} }

View File

@ -104,13 +104,6 @@ namespace MediaBrowser.Controller
/// <returns>The API URL.</returns> /// <returns>The API URL.</returns>
string GetLocalApiUrl(string hostname, string scheme = null, int? port = null); 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(); IEnumerable<WakeOnLanInfo> GetWakeOnLanInfo();
string ExpandVirtualPath(string path); string ExpandVirtualPath(string path);

View File

@ -595,11 +595,11 @@ namespace MediaBrowser.Controller.Library
Task RemoveVirtualFolder(string name, bool refreshLibrary); 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); QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query);

View File

@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Library
/// <returns>User data dto.</returns> /// <returns>User data dto.</returns>
UserItemDataDto GetUserDataDto(BaseItem item, User user); 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> /// <summary>
/// Get all user data for the given user. /// Get all user data for the given user.
@ -69,8 +69,8 @@ namespace MediaBrowser.Controller.Library
/// </summary> /// </summary>
/// <param name="item">Item to update.</param> /// <param name="item">Item to update.</param>
/// <param name="data">Data 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> /// <returns>True if playstate was updated.</returns>
bool UpdatePlayState(BaseItem item, UserItemData data, long? positionTicks); bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks);
} }
} }

View File

@ -274,7 +274,7 @@ namespace MediaBrowser.Controller.LiveTv
Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber); 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> /// <summary>
/// Gets the lineups. /// Gets the lineups.

View File

@ -70,10 +70,10 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary> /// <summary>
/// Updates the timer asynchronous. /// Updates the timer asynchronous.
/// </summary> /// </summary>
/// <param name="info">The information.</param> /// <param name="updatedTimer">The updated timer information.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken); Task UpdateTimerAsync(TimerInfo updatedTimer, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Updates the series timer asynchronous. /// Updates the series timer asynchronous.

View File

@ -49,17 +49,17 @@ namespace MediaBrowser.Controller.Persistence
/// <summary> /// <summary>
/// Gets chapters for an item. /// Gets chapters for an item.
/// </summary> /// </summary>
/// <param name="id">The item.</param> /// <param name="item">The item.</param>
/// <returns>The list of chapter info.</returns> /// <returns>The list of chapter info.</returns>
List<ChapterInfo> GetChapters(BaseItem id); List<ChapterInfo> GetChapters(BaseItem item);
/// <summary> /// <summary>
/// Gets a single chapter for an item. /// Gets a single chapter for an item.
/// </summary> /// </summary>
/// <param name="id">The item.</param> /// <param name="item">The item.</param>
/// <param name="index">The chapter index.</param> /// <param name="index">The chapter index.</param>
/// <returns>The chapter info at the specified index.</returns> /// <returns>The chapter info at the specified index.</returns>
ChapterInfo GetChapter(BaseItem id, int index); ChapterInfo GetChapter(BaseItem item, int index);
/// <summary> /// <summary>
/// Saves the chapters. /// Saves the chapters.

View File

@ -344,7 +344,7 @@ namespace MediaBrowser.Controller.Session
/// <returns>A <see cref="Task"/> representing the log out process.</returns> /// <returns>A <see cref="Task"/> representing the log out process.</returns>
Task Logout(string accessToken); Task Logout(string accessToken);
Task Logout(Device accessToken); Task Logout(Device device);
/// <summary> /// <summary>
/// Revokes the user tokens. /// Revokes the user tokens.

View File

@ -133,7 +133,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetAudioStream; var stream = TargetAudioStream;
return AudioSampleRate.HasValue && !IsDirectStream return AudioSampleRate.HasValue && !IsDirectStream
? AudioSampleRate ? AudioSampleRate
: stream == null ? null : stream.SampleRate; : stream?.SampleRate;
} }
} }
@ -146,7 +146,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth; return TargetAudioStream?.BitDepth;
} }
var targetAudioCodecs = TargetAudioCodec; var targetAudioCodecs = TargetAudioCodec;
@ -156,7 +156,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetAudioBitDepth(audioCodec); return GetTargetAudioBitDepth(audioCodec);
} }
return TargetAudioStream == null ? (int?)null : TargetAudioStream.BitDepth; return TargetAudioStream?.BitDepth;
} }
} }
@ -169,7 +169,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth; return TargetVideoStream?.BitDepth;
} }
var targetVideoCodecs = TargetVideoCodec; var targetVideoCodecs = TargetVideoCodec;
@ -179,7 +179,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetVideoBitDepth(videoCodec); return GetTargetVideoBitDepth(videoCodec);
} }
return TargetVideoStream == null ? (int?)null : TargetVideoStream.BitDepth; return TargetVideoStream?.BitDepth;
} }
} }
@ -193,7 +193,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; return TargetVideoStream?.RefFrames;
} }
var targetVideoCodecs = TargetVideoCodec; var targetVideoCodecs = TargetVideoCodec;
@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetRefFrames(videoCodec); return GetTargetRefFrames(videoCodec);
} }
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; return TargetVideoStream?.RefFrames;
} }
} }
@ -230,7 +230,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; return TargetVideoStream?.Level;
} }
var targetVideoCodecs = TargetVideoCodec; var targetVideoCodecs = TargetVideoCodec;
@ -240,7 +240,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetVideoLevel(videoCodec); return GetTargetVideoLevel(videoCodec);
} }
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; return TargetVideoStream?.Level;
} }
} }
@ -254,7 +254,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetVideoStream; var stream = TargetVideoStream;
return !IsDirectStream return !IsDirectStream
? null ? null
: stream == null ? null : stream.PacketLength; : stream?.PacketLength;
} }
} }
@ -267,7 +267,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? null : TargetVideoStream.Profile; return TargetVideoStream?.Profile;
} }
var targetVideoCodecs = TargetVideoCodec; var targetVideoCodecs = TargetVideoCodec;
@ -277,7 +277,7 @@ namespace MediaBrowser.Model.Dlna
return GetOption(videoCodec, "profile"); return GetOption(videoCodec, "profile");
} }
return TargetVideoStream == null ? null : TargetVideoStream.Profile; return TargetVideoStream?.Profile;
} }
} }
@ -292,7 +292,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetVideoStream; var stream = TargetVideoStream;
return !IsDirectStream return !IsDirectStream
? null ? null
: stream == null ? null : stream.CodecTag; : stream?.CodecTag;
} }
} }
@ -306,7 +306,7 @@ namespace MediaBrowser.Model.Dlna
var stream = TargetAudioStream; var stream = TargetAudioStream;
return AudioBitrate.HasValue && !IsDirectStream return AudioBitrate.HasValue && !IsDirectStream
? AudioBitrate ? AudioBitrate
: stream == null ? null : stream.BitRate; : stream?.BitRate;
} }
} }
@ -319,7 +319,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetAudioStream == null ? (int?)null : TargetAudioStream.Channels; return TargetAudioStream?.Channels;
} }
var targetAudioCodecs = TargetAudioCodec; var targetAudioCodecs = TargetAudioCodec;
@ -329,7 +329,7 @@ namespace MediaBrowser.Model.Dlna
return GetTargetRefFrames(codec); 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 return VideoBitrate.HasValue && !IsDirectStream
? VideoBitrate ? VideoBitrate
: stream == null ? null : stream.BitRate; : stream?.BitRate;
} }
} }
@ -451,7 +451,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? null : TargetVideoStream.IsAnamorphic; return TargetVideoStream?.IsAnamorphic;
} }
return false; return false;
@ -464,7 +464,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (IsDirectStream) if (IsDirectStream)
{ {
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced; return TargetVideoStream?.IsInterlaced;
} }
var targetVideoCodecs = TargetVideoCodec; 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) if (IsDirectStream)
{ {
return TargetVideoStream == null ? null : TargetVideoStream.IsAVC; return TargetVideoStream?.IsAVC;
} }
return true; return true;
@ -618,20 +618,20 @@ namespace MediaBrowser.Model.Dlna
} }
// Try to keep the url clean by omitting defaults // Try to keep the url clean by omitting defaults
if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase) && if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase)
string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase)) && string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
{ {
continue; continue;
} }
if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase) && if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase)
string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase)) && string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
{ {
continue; continue;
} }
if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) && if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase)
string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase)) && string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
{ {
continue; continue;
} }
@ -641,7 +641,7 @@ namespace MediaBrowser.Model.Dlna
list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue)); 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); return GetUrl(baseUrl, queryString);
} }
@ -681,11 +681,11 @@ namespace MediaBrowser.Model.Dlna
string audioCodecs = item.AudioCodecs.Length == 0 ? string audioCodecs = item.AudioCodecs.Length == 0 ?
string.Empty : string.Empty :
string.Join(",", item.AudioCodecs); string.Join(',', item.AudioCodecs);
string videoCodecs = item.VideoCodecs.Length == 0 ? string videoCodecs = item.VideoCodecs.Length == 0 ?
string.Empty : string.Empty :
string.Join(",", item.VideoCodecs); string.Join(',', item.VideoCodecs);
list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty)); list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty)); list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
@ -1024,30 +1024,5 @@ namespace MediaBrowser.Model.Dlna
return count; 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;
}
} }
} }

View File

@ -12,6 +12,8 @@
<Rule Id="SA1101" Action="None" /> <Rule Id="SA1101" Action="None" />
<!-- disable warning SA1108: Block statements should not contain embedded comments --> <!-- disable warning SA1108: Block statements should not contain embedded comments -->
<Rule Id="SA1108" Action="None" /> <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 --> <!-- disable warning SA1128:: Put constructor initializers on their own line -->
<Rule Id="SA1128" Action="None" /> <Rule Id="SA1128" Action="None" />
<!-- disable warning SA1130: Use lambda syntax --> <!-- disable warning SA1130: Use lambda syntax -->
@ -39,6 +41,10 @@
</Rules> </Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design"> <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 <!-- 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 --> or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
<Rule Id="CA2016" Action="Error" /> <Rule Id="CA2016" Action="Error" />