mirror of https://github.com/jellyfin/jellyfin.git
Compare commits
8 Commits
80db405e4f
...
a28d8fb0a1
Author | SHA1 | Date |
---|---|---|
Tim Eisele | a28d8fb0a1 | |
renovate[bot] | 5612cb8178 | |
renovate[bot] | ccd06bc547 | |
Bond-009 | d29b85a134 | |
Shadowghost | f1b1c7355c | |
Shadowghost | a68dd94174 | |
Shadowghost | c41d95b31b | |
Shadowghost | a75c9d4547 |
|
@ -20,7 +20,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
|
||||
with:
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
|
@ -39,7 +39,7 @@ jobs:
|
|||
permissions: read-all
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
|
@ -78,12 +78,12 @@ jobs:
|
|||
- openapi-base
|
||||
steps:
|
||||
- name: Download openapi-head
|
||||
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
|
||||
with:
|
||||
name: openapi-head
|
||||
path: openapi-head
|
||||
- name: Download openapi-base
|
||||
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
|
||||
with:
|
||||
name: openapi-base
|
||||
path: openapi-base
|
||||
|
@ -152,7 +152,7 @@ jobs:
|
|||
run: |-
|
||||
echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
|
||||
- name: Download openapi-head
|
||||
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
|
||||
with:
|
||||
name: openapi-head
|
||||
path: openapi-head
|
||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
|
||||
runs-on: "${{ matrix.os }}"
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
|
||||
- uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
|
||||
with:
|
||||
|
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
reactions: '+1'
|
||||
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
@ -51,7 +51,7 @@ jobs:
|
|||
reactions: eyes
|
||||
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
@ -128,7 +128,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: pull in script
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
repository: jellyfin/jellyfin-triage-script
|
||||
- name: install python
|
||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
issues: write
|
||||
steps:
|
||||
- name: pull in script
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
repository: jellyfin/jellyfin-triage-script
|
||||
- name: install python
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
yq-version: v4.9.8
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
ref: ${{ env.TAG_BRANCH }}
|
||||
|
||||
|
@ -66,7 +66,7 @@ jobs:
|
|||
NEXT_VERSION: ${{ github.event.inputs.NEXT_VERSION }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
with:
|
||||
ref: ${{ env.TAG_BRANCH }}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<PackageVersion Include="BlurHashSharp" Version="1.3.2" />
|
||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
|
||||
<PackageVersion Include="Diacritics" Version="3.3.27" />
|
||||
<PackageVersion Include="Diacritics" Version="3.3.29" />
|
||||
<PackageVersion Include="DiscUtils.Udf" Version="0.16.13" />
|
||||
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
|
||||
<PackageVersion Include="EFCoreSecondLevelCacheInterceptor" Version="4.4.3" />
|
||||
|
|
|
@ -44,7 +44,6 @@ using MediaBrowser.Model.Library;
|
|||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TMDbLib.Objects.Authentication;
|
||||
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||
using EpisodeInfo = Emby.Naming.TV.EpisodeInfo;
|
||||
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||
|
@ -1612,14 +1611,18 @@ namespace Emby.Server.Implementations.Library
|
|||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
public async Task<IEnumerable<Video>> GetIntros(BaseItem item, User user)
|
||||
{
|
||||
if (IntroProviders.Length == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var tasks = IntroProviders
|
||||
.Take(1)
|
||||
.Select(i => GetIntros(i, item, user));
|
||||
|
||||
var items = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
return items
|
||||
.SelectMany(i => i.ToArray())
|
||||
.SelectMany(i => i)
|
||||
.Select(ResolveIntro)
|
||||
.Where(i => i is not null)!; // null values got filtered out
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ namespace Emby.Server.Implementations.Library
|
|||
var tasks = _providers.Select(i => GetDynamicMediaSources(item, i, cancellationToken));
|
||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
return results.SelectMany(i => i.ToList());
|
||||
return results.SelectMany(i => i);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, IMediaSourceProvider provider, CancellationToken cancellationToken)
|
||||
|
|
|
@ -34,20 +34,9 @@ namespace Jellyfin.Api.Auth.LocalAccessOrRequiresElevationPolicy
|
|||
var ip = _httpContextAccessor.HttpContext?.GetNormalizedRemoteIP();
|
||||
|
||||
// Loopback will be on LAN, so we can accept null.
|
||||
if (ip is null || _networkManager.IsInLocalNetwork(ip))
|
||||
if (ip is null || _networkManager.IsInLocalNetwork(ip) || context.User.IsInRole(UserRoles.Administrator))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (context.User.IsInRole(UserRoles.Administrator))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Fail();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
|
|
@ -4,10 +4,11 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.Models.StreamingDtos;
|
||||
using MediaBrowser.Common.Api;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Streaming;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -16,6 +17,7 @@ namespace Jellyfin.Api.Controllers;
|
|||
/// <summary>
|
||||
/// The audio controller.
|
||||
/// </summary>
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
public class AudioController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly AudioHelper _audioHelper;
|
||||
|
|
|
@ -15,6 +15,7 @@ using Jellyfin.Api.Models.StreamingDtos;
|
|||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using Jellyfin.MediaEncoding.Hls.Playlist;
|
||||
using MediaBrowser.Common.Api;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -36,16 +37,14 @@ namespace Jellyfin.Api.Controllers;
|
|||
/// <summary>
|
||||
/// Dynamic hls controller.
|
||||
/// </summary>
|
||||
[Route("")]
|
||||
[Authorize]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
public class DynamicHlsController : BaseJellyfinApiController
|
||||
{
|
||||
private const string DefaultVodEncoderPreset = "veryfast";
|
||||
private const string DefaultEventEncoderPreset = "superfast";
|
||||
private const TranscodingJobType TranscodingJobType = MediaBrowser.Controller.MediaEncoding.TranscodingJobType.Hls;
|
||||
private const TranscodingJobType DefaultTranscodingJobType = TranscodingJobType.Hls;
|
||||
|
||||
private readonly Version _minFFmpegFlacInMp4 = new Version(6, 0);
|
||||
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IMediaSourceManager _mediaSourceManager;
|
||||
|
@ -285,7 +284,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
_mediaEncoder,
|
||||
_encodingHelper,
|
||||
_transcodeManager,
|
||||
TranscodingJobType,
|
||||
DefaultTranscodingJobType,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
@ -306,7 +305,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
playlistPath,
|
||||
GetCommandLineArguments(playlistPath, state, true, 0),
|
||||
Request.HttpContext.User.GetUserId(),
|
||||
TranscodingJobType,
|
||||
DefaultTranscodingJobType,
|
||||
cancellationTokenSource)
|
||||
.ConfigureAwait(false);
|
||||
job.IsLiveOutput = true;
|
||||
|
@ -326,7 +325,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
}
|
||||
}
|
||||
|
||||
job ??= _transcodeManager.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||
job ??= _transcodeManager.OnTranscodeBeginRequest(playlistPath, DefaultTranscodingJobType);
|
||||
|
||||
if (job is not null)
|
||||
{
|
||||
|
@ -508,7 +507,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
EnableTrickplay = enableTrickplay
|
||||
};
|
||||
|
||||
return await _dynamicHlsHelper.GetMasterHlsPlaylist(TranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
|
||||
return await _dynamicHlsHelper.GetMasterHlsPlaylist(DefaultTranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -674,7 +673,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming
|
||||
};
|
||||
|
||||
return await _dynamicHlsHelper.GetMasterHlsPlaylist(TranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
|
||||
return await _dynamicHlsHelper.GetMasterHlsPlaylist(DefaultTranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1379,7 +1378,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
_mediaEncoder,
|
||||
_encodingHelper,
|
||||
_transcodeManager,
|
||||
TranscodingJobType,
|
||||
DefaultTranscodingJobType,
|
||||
cancellationTokenSource.Token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
@ -1417,7 +1416,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
_mediaEncoder,
|
||||
_encodingHelper,
|
||||
_transcodeManager,
|
||||
TranscodingJobType,
|
||||
DefaultTranscodingJobType,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
@ -1431,7 +1430,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
|
||||
if (System.IO.File.Exists(segmentPath))
|
||||
{
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, DefaultTranscodingJobType);
|
||||
_logger.LogDebug("returning {0} [it exists, try 1]", segmentPath);
|
||||
return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, segmentId, job, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -1441,7 +1440,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
var startTranscoding = false;
|
||||
if (System.IO.File.Exists(segmentPath))
|
||||
{
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, DefaultTranscodingJobType);
|
||||
_logger.LogDebug("returning {0} [it exists, try 2]", segmentPath);
|
||||
return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, segmentId, job, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -1492,7 +1491,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
playlistPath,
|
||||
GetCommandLineArguments(playlistPath, state, false, segmentId),
|
||||
Request.HttpContext.User.GetUserId(),
|
||||
TranscodingJobType,
|
||||
DefaultTranscodingJobType,
|
||||
cancellationTokenSource).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
|
@ -1505,7 +1504,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
}
|
||||
else
|
||||
{
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||
job = _transcodeManager.OnTranscodeBeginRequest(playlistPath, DefaultTranscodingJobType);
|
||||
if (job?.TranscodingThrottler is not null)
|
||||
{
|
||||
await job.TranscodingThrottler.UnpauseTranscoding().ConfigureAwait(false);
|
||||
|
@ -1514,7 +1513,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
}
|
||||
|
||||
_logger.LogDebug("returning {0} [general case]", segmentPath);
|
||||
job ??= _transcodeManager.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
|
||||
job ??= _transcodeManager.OnTranscodeBeginRequest(playlistPath, DefaultTranscodingJobType);
|
||||
return await GetSegmentResult(state, playlistPath, segmentPath, segmentExtension, segmentId, job, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -1970,7 +1969,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
|
||||
private int? GetCurrentTranscodingIndex(string playlist, string segmentExtension)
|
||||
{
|
||||
var job = _transcodeManager.GetTranscodingJob(playlist, TranscodingJobType);
|
||||
var job = _transcodeManager.GetTranscodingJob(playlist, DefaultTranscodingJobType);
|
||||
|
||||
if (job is null || job.HasExited)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using MediaBrowser.Common.Api;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
|
@ -20,6 +21,7 @@ namespace Jellyfin.Api.Controllers;
|
|||
/// The hls segment controller.
|
||||
/// </summary>
|
||||
[Route("")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
public class HlsSegmentController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
|
|
@ -1156,6 +1156,7 @@ public class LiveTvController : BaseJellyfinApiController
|
|||
/// or a <see cref="NotFoundResult"/> if recording not found.
|
||||
/// </returns>
|
||||
[HttpGet("LiveRecordings/{recordingId}/stream")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesVideoFile]
|
||||
|
@ -1183,6 +1184,7 @@ public class LiveTvController : BaseJellyfinApiController
|
|||
/// or a <see cref="NotFoundResult"/> if stream not found.
|
||||
/// </returns>
|
||||
[HttpGet("LiveStreamFiles/{streamId}/stream.{container}")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ProducesVideoFile]
|
||||
|
|
|
@ -8,6 +8,7 @@ using Jellyfin.Api.Attributes;
|
|||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Api.Models.StreamingDtos;
|
||||
using MediaBrowser.Common.Api;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
|
@ -28,6 +29,7 @@ namespace Jellyfin.Api.Controllers;
|
|||
/// The universal audio controller.
|
||||
/// </summary>
|
||||
[Route("")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
public class UniversalAudioController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
@ -89,7 +91,6 @@ public class UniversalAudioController : BaseJellyfinApiController
|
|||
/// <returns>A <see cref="Task"/> containing the audio file.</returns>
|
||||
[HttpGet("Audio/{itemId}/universal")]
|
||||
[HttpHead("Audio/{itemId}/universal", Name = "HeadUniversalAudioStream")]
|
||||
[Authorize]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
|
|
|
@ -10,6 +10,7 @@ using MediaBrowser.Common.Extensions;
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
@ -19,6 +20,7 @@ namespace Jellyfin.Api.Controllers;
|
|||
/// Attachments controller.
|
||||
/// </summary>
|
||||
[Route("Videos")]
|
||||
[Authorize]
|
||||
public class VideoAttachmentsController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
|
|
@ -310,6 +310,7 @@ public class VideosController : BaseJellyfinApiController
|
|||
/// <returns>A <see cref="FileResult"/> containing the audio file.</returns>
|
||||
[HttpGet("{itemId}/stream")]
|
||||
[HttpHead("{itemId}/stream", Name = "HeadVideoStream")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesVideoFile]
|
||||
public async Task<ActionResult> GetVideoStream(
|
||||
|
@ -548,6 +549,7 @@ public class VideosController : BaseJellyfinApiController
|
|||
/// <returns>A <see cref="FileResult"/> containing the audio file.</returns>
|
||||
[HttpGet("{itemId}/stream.{container}")]
|
||||
[HttpHead("{itemId}/stream.{container}", Name = "HeadVideoStreamByContainer")]
|
||||
[Authorize(Policy = Policies.Playback)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesVideoFile]
|
||||
public Task<ActionResult> GetVideoStreamByContainer(
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace Jellyfin.Server.Extensions
|
|||
options.AddPolicy(Policies.LiveTvAccess, new UserPermissionRequirement(PermissionKind.EnableLiveTvAccess));
|
||||
options.AddPolicy(Policies.LiveTvManagement, new UserPermissionRequirement(PermissionKind.EnableLiveTvManagement));
|
||||
options.AddPolicy(Policies.LocalAccessOrRequiresElevation, new LocalAccessOrRequiresElevationRequirement());
|
||||
options.AddPolicy(Policies.Playback, new UserPermissionRequirement(PermissionKind.EnableMediaPlayback));
|
||||
options.AddPolicy(Policies.SyncPlayHasAccess, new SyncPlayAccessRequirement(SyncPlayAccessRequirementType.HasAccess));
|
||||
options.AddPolicy(Policies.SyncPlayCreateGroup, new SyncPlayAccessRequirement(SyncPlayAccessRequirementType.CreateGroup));
|
||||
options.AddPolicy(Policies.SyncPlayJoinGroup, new SyncPlayAccessRequirement(SyncPlayAccessRequirementType.JoinGroup));
|
||||
|
|
|
@ -94,4 +94,9 @@ public static class Policies
|
|||
/// Policy name for accessing lyric management.
|
||||
/// </summary>
|
||||
public const string LyricManagement = "LyricManagement";
|
||||
|
||||
/// <summary>
|
||||
/// Policy name for playback.
|
||||
/// </summary>
|
||||
public const string Playback = "Playback";
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
|
||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
return results.SelectMany(i => i.ToList());
|
||||
return results.SelectMany(i => i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in New Issue