aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api')
-rw-r--r--Jellyfin.Api/Controllers/ApiKeyController.cs1
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs1
-rw-r--r--Jellyfin.Api/Controllers/ImageByNameController.cs2
-rw-r--r--Jellyfin.Api/Controllers/ItemLookupController.cs4
-rw-r--r--Jellyfin.Api/Controllers/LiveTvController.cs1
-rw-r--r--Jellyfin.Api/Controllers/MoviesController.cs1
-rw-r--r--Jellyfin.Api/Controllers/RemoteImageController.cs5
-rw-r--r--Jellyfin.Api/Controllers/SuggestionsController.cs1
-rw-r--r--Jellyfin.Api/Controllers/SyncPlayController.cs2
-rw-r--r--Jellyfin.Api/Controllers/SystemController.cs2
-rw-r--r--Jellyfin.Api/Controllers/VideoHlsController.cs12
-rw-r--r--Jellyfin.Api/Controllers/VideosController.cs2
-rw-r--r--Jellyfin.Api/Helpers/AudioHelper.cs2
-rw-r--r--Jellyfin.Api/Helpers/DynamicHlsHelper.cs2
-rw-r--r--Jellyfin.Api/Helpers/HlsHelpers.cs3
-rw-r--r--Jellyfin.Api/Helpers/ProgressiveFileCopier.cs4
-rw-r--r--Jellyfin.Api/Helpers/ProgressiveFileStream.cs3
-rw-r--r--Jellyfin.Api/Helpers/TranscodingJobHelper.cs2
-rw-r--r--Jellyfin.Api/Jellyfin.Api.csproj4
-rw-r--r--Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs14
20 files changed, 29 insertions, 39 deletions
diff --git a/Jellyfin.Api/Controllers/ApiKeyController.cs b/Jellyfin.Api/Controllers/ApiKeyController.cs
index 720b22b1d6..8e0332d3e1 100644
--- a/Jellyfin.Api/Controllers/ApiKeyController.cs
+++ b/Jellyfin.Api/Controllers/ApiKeyController.cs
@@ -1,4 +1,3 @@
-using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index fbfb472154..a540033579 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -5,7 +5,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
diff --git a/Jellyfin.Api/Controllers/ImageByNameController.cs b/Jellyfin.Api/Controllers/ImageByNameController.cs
index e1b8080984..99ab7f232e 100644
--- a/Jellyfin.Api/Controllers/ImageByNameController.cs
+++ b/Jellyfin.Api/Controllers/ImageByNameController.cs
@@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers
}
var contentType = MimeTypes.GetMimeType(path);
- return File(System.IO.File.OpenRead(path), contentType);
+ return File(AsyncFile.OpenRead(path), contentType);
}
/// <summary>
diff --git a/Jellyfin.Api/Controllers/ItemLookupController.cs b/Jellyfin.Api/Controllers/ItemLookupController.cs
index 9fa307858f..448510c06a 100644
--- a/Jellyfin.Api/Controllers/ItemLookupController.cs
+++ b/Jellyfin.Api/Controllers/ItemLookupController.cs
@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
-using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
-using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -17,7 +14,6 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs
index b20eae7506..93dc767291 100644
--- a/Jellyfin.Api/Controllers/LiveTvController.cs
+++ b/Jellyfin.Api/Controllers/LiveTvController.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
-using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Mime;
diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs
index 010a3b19a7..99c90d19e7 100644
--- a/Jellyfin.Api/Controllers/MoviesController.cs
+++ b/Jellyfin.Api/Controllers/MoviesController.cs
@@ -18,7 +18,6 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Api.Controllers
diff --git a/Jellyfin.Api/Controllers/RemoteImageController.cs b/Jellyfin.Api/Controllers/RemoteImageController.cs
index ec836f43e3..7a2c23991b 100644
--- a/Jellyfin.Api/Controllers/RemoteImageController.cs
+++ b/Jellyfin.Api/Controllers/RemoteImageController.cs
@@ -4,10 +4,8 @@ using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Net.Http;
-using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
-using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
@@ -16,7 +14,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@@ -208,7 +205,7 @@ namespace Jellyfin.Api.Controllers
var fullCacheDirectory = Path.GetDirectoryName(fullCachePath) ?? throw new ResourceNotFoundException($"Provided path ({fullCachePath}) is not valid.");
Directory.CreateDirectory(fullCacheDirectory);
// use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
- await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, true);
+ await using var fileStream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO);
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
var pointerCacheDirectory = Path.GetDirectoryName(pointerCachePath) ?? throw new ArgumentException($"Provided path ({pointerCachePath}) is not valid.", nameof(pointerCachePath));
diff --git a/Jellyfin.Api/Controllers/SuggestionsController.cs b/Jellyfin.Api/Controllers/SuggestionsController.cs
index a811a29c31..97eec4bd2e 100644
--- a/Jellyfin.Api/Controllers/SuggestionsController.cs
+++ b/Jellyfin.Api/Controllers/SuggestionsController.cs
@@ -1,6 +1,5 @@
using System;
using System.ComponentModel.DataAnnotations;
-using System.Linq;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders;
diff --git a/Jellyfin.Api/Controllers/SyncPlayController.cs b/Jellyfin.Api/Controllers/SyncPlayController.cs
index 1b3248c0c6..c6b70f3d20 100644
--- a/Jellyfin.Api/Controllers/SyncPlayController.cs
+++ b/Jellyfin.Api/Controllers/SyncPlayController.cs
@@ -162,7 +162,7 @@ namespace Jellyfin.Api.Controllers
[FromBody, Required] RemoveFromPlaylistRequestDto requestData)
{
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
- var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds);
+ var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds, requestData.ClearPlaylist, requestData.ClearPlayingItem);
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
return NoContent();
}
diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs
index bbbe5fb8da..e6584f0fe6 100644
--- a/Jellyfin.Api/Controllers/SystemController.cs
+++ b/Jellyfin.Api/Controllers/SystemController.cs
@@ -201,7 +201,7 @@ namespace Jellyfin.Api.Controllers
// For older files, assume fully static
var fileShare = file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1) ? FileShare.Read : FileShare.ReadWrite;
- FileStream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, fileShare);
+ FileStream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, fileShare, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO);
return File(stream, "text/plain; charset=utf-8");
}
diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs
index 8560df2eac..ef25db8c93 100644
--- a/Jellyfin.Api/Controllers/VideoHlsController.cs
+++ b/Jellyfin.Api/Controllers/VideoHlsController.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
@@ -20,12 +19,10 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Api.Controllers
@@ -267,6 +264,9 @@ namespace Jellyfin.Api.Controllers
// CTS lifecycle is managed internally.
var cancellationTokenSource = new CancellationTokenSource();
+ // Due to CTS.Token calling ThrowIfDisposed (https://github.com/dotnet/runtime/issues/29970) we have to "cache" the token
+ // since it gets disposed when ffmpeg exits
+ var cancellationToken = cancellationTokenSource.Token;
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
Request,
@@ -281,7 +281,7 @@ namespace Jellyfin.Api.Controllers
_deviceManager,
_transcodingJobHelper,
TranscodingJobType,
- cancellationTokenSource.Token)
+ cancellationToken)
.ConfigureAwait(false);
TranscodingJobDto? job = null;
@@ -290,7 +290,7 @@ namespace Jellyfin.Api.Controllers
if (!System.IO.File.Exists(playlistPath))
{
var transcodingLock = _transcodingJobHelper.GetTranscodingLock(playlistPath);
- await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+ await transcodingLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
if (!System.IO.File.Exists(playlistPath))
@@ -317,7 +317,7 @@ namespace Jellyfin.Api.Controllers
minSegments = state.MinSegments;
if (minSegments > 0)
{
- await HlsHelpers.WaitForMinimumSegmentCount(playlistPath, minSegments, _logger, cancellationTokenSource.Token).ConfigureAwait(false);
+ await HlsHelpers.WaitForMinimumSegmentCount(playlistPath, minSegments, _logger, cancellationToken).ConfigureAwait(false);
}
}
}
diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs
index 5c5057c83b..bc6fc904a1 100644
--- a/Jellyfin.Api/Controllers/VideosController.cs
+++ b/Jellyfin.Api/Controllers/VideosController.cs
@@ -25,14 +25,12 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
namespace Jellyfin.Api.Controllers
{
diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs
index 264131905f..ddcde1cf6d 100644
--- a/Jellyfin.Api/Helpers/AudioHelper.cs
+++ b/Jellyfin.Api/Helpers/AudioHelper.cs
@@ -11,12 +11,10 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
namespace Jellyfin.Api.Helpers
{
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index dc5d6715b5..4abe4c5d57 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -18,11 +18,9 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
diff --git a/Jellyfin.Api/Helpers/HlsHelpers.cs b/Jellyfin.Api/Helpers/HlsHelpers.cs
index d1cdaf867e..f36769dc2a 100644
--- a/Jellyfin.Api/Helpers/HlsHelpers.cs
+++ b/Jellyfin.Api/Helpers/HlsHelpers.cs
@@ -1,7 +1,6 @@
using System;
using System.Globalization;
using System.IO;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Models.StreamingDtos;
@@ -39,7 +38,7 @@ namespace Jellyfin.Api.Helpers
FileAccess.Read,
FileShare.ReadWrite,
IODefaults.FileStreamBufferSize,
- FileOptions.SequentialScan);
+ (AsyncFile.UseAsyncIO ? FileOptions.Asynchronous : FileOptions.None) | FileOptions.SequentialScan);
await using (fileStream.ConfigureAwait(false))
{
using var reader = new StreamReader(fileStream);
diff --git a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
index 963e177245..81970b041a 100644
--- a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
+++ b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
@@ -1,7 +1,6 @@
using System;
using System.Buffers;
using System.IO;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Models.PlaybackDtos;
@@ -85,8 +84,7 @@ namespace Jellyfin.Api.Helpers
var fileOptions = FileOptions.SequentialScan;
var allowAsyncFileRead = false;
- // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (AsyncFile.UseAsyncIO)
{
fileOptions |= FileOptions.Asynchronous;
allowAsyncFileRead = true;
diff --git a/Jellyfin.Api/Helpers/ProgressiveFileStream.cs b/Jellyfin.Api/Helpers/ProgressiveFileStream.cs
index 499dbe84d6..d4cc0172d9 100644
--- a/Jellyfin.Api/Helpers/ProgressiveFileStream.cs
+++ b/Jellyfin.Api/Helpers/ProgressiveFileStream.cs
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Models.PlaybackDtos;
@@ -40,7 +39,7 @@ namespace Jellyfin.Api.Helpers
_allowAsyncFileRead = false;
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (AsyncFile.UseAsyncIO)
{
fileOptions |= FileOptions.Asynchronous;
_allowAsyncFileRead = true;
diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
index 5d3724c11f..4e1e98df0d 100644
--- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
+++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
@@ -557,7 +557,7 @@ namespace Jellyfin.Api.Helpers
$"{logFilePrefix}{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{state.Request.MediaSourceId}_{Guid.NewGuid().ToString()[..8]}.log");
// FFmpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
- Stream logStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true);
+ Stream logStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, AsyncFile.UseAsyncIO);
var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(request.Path + Environment.NewLine + Environment.NewLine + JsonSerializer.Serialize(state.MediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
await logStream.WriteAsync(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length, cancellationTokenSource.Token).ConfigureAwait(false);
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index 669925198b..2fca88f24e 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -16,8 +16,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.9" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
- <PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.5" />
- <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.1.5" />
+ <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.1" />
+ <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.2.1" />
</ItemGroup>
<ItemGroup>
diff --git a/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs b/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs
index e9b2b2cb37..02ce5a0488 100644
--- a/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs
+++ b/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs
@@ -17,9 +17,21 @@ namespace Jellyfin.Api.Models.SyncPlayDtos
}
/// <summary>
- /// Gets or sets the playlist identifiers ot the items.
+ /// Gets or sets the playlist identifiers ot the items. Ignored when clearing the playlist.
/// </summary>
/// <value>The playlist identifiers ot the items.</value>
public IReadOnlyList<Guid> PlaylistItemIds { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the entire playlist should be cleared.
+ /// </summary>
+ /// <value>Whether the entire playlist should be cleared.</value>
+ public bool ClearPlaylist { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the playing item should be removed as well. Used only when clearing the playlist.
+ /// </summary>
+ /// <value>Whether the playing item should be removed as well.</value>
+ public bool ClearPlayingItem { get; set; }
}
}