linuxserver / docker-jellyfin

GNU General Public License v3.0
600 stars 92 forks source link

[BUG] abc user doesn't have privileges for nvidia gpu and can't transcode #238

Closed JurgenCruz closed 4 weeks ago

JurgenCruz commented 4 months ago

Is there an existing issue for this?

Current Behavior

Executing docker-compose with non-root user and also having the PUID and PGID set to another non-root user in the service definition leads to the abc user inside the container not being able to access the gpu. Transcoding is not working because of this and ffmpeg returns 1 error. Both running user and PUID user belong to the video group in the host machine.

I verified this by doing docker exec -it jellyfin bash to run a shell inside the container. It logs me in as the container's root even if I didn't use sudo. if I run nvidia-smi it correctly shows me the gpu. This means the container has access to the GPU just fine. I even ran the ffmpeg command that was failing that I grabbed from the logs and it worked. I then used runuser -u abc bash to run a shell as abc. When I execute nvidia-smi I get an error Failed to initialize NVML: Insufficient Permissions.

Expected Behavior

I expect the abc user to have enough permissions to access the gpu when not running docker-compose as root and when PUID and PGID are set to non-root user.

Steps To Reproduce

  1. Create 2 users media and admin
  2. Create folder mnt/Tank/Apps/jellyfin and chown it to media user
  3. Create folder mnt/Tank/MediaCenter and chown it to media user
  4. Add some videos to mnt/Tank/MediaCenter
  5. Add the video group to both users with usermod -aG video {user}
  6. Run from admin user the docker-compose up -d command from the same folder with the docker-compose.yml (pasted below)
  7. Either enable HW Accel and try to watch a video or run interactive shell with docker exec -it jellyfin bash and then runuser -u abc bash followed by nvidia-smi

Environment

- OS: OpenSUSE Leap 15.5
- How docker service was installed: distro's package manager. docker-compose however was installed from user repo `https://download.opensuse.org/repositories/home:jloehel:golang/15.5/home:jloehel:golang.repo`
- installed nvidia drivers and container toolkit:

    zypper in nvidia-video-G06 nvidia-gl-G06 nvidia-container-toolkit
    nvidia-ctk runtime configure --runtime=docker
    systemctl restart docker

CPU architecture

x86-64

Docker creation

version: "3.8"
services:
  jellyfin:
    image: lscr.io/linuxserver/jellyfin
    container_name: jellyfin
    environment:
      - PUID=472
      - PGID=472
      - TZ=America/New_York
      - NVIDIA_VISIBLE_DEVICES=all
    volumes:
      - type: bind
        source: /mnt/Tank/Apps/jellyfin
        target: /config
      - type: bind
        source: /mnt/Tank/MediaCenter
        target: /MediaCenter
    ports:
      - 8096:8096
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    restart: unless-stopped

Container logs

[12:56:04] [INF] [13] Jellyfin.Api.Helpers.MediaInfoHelper: StreamBuilder.BuildVideoItem( Profile=Anonymous Profile, Path=/MediaCenter/media/movies/movie.mkv, AudioStreamIndex=null, SubtitleStreamIndex=null ) => ( PlayMethod=Transcode, TranscodeReason=VideoCodecNotSupported, AudioCodecNotSupported, SubtitleCodecNotSupported ) media:/videos/2bd73ab4-8136-8053-0b36-a44342090621/master.m3u8?MediaSourceId=2bd73ab4813680530b36a44342090621&VideoCodec=h264,h264&AudioCodec=aac,mp3&AudioStreamIndex=1&SubtitleStreamIndex=5&VideoBitrate=139616000&AudioBitrate=384000&MaxFramerate=23.976025&api_key=<token>&SubtitleMethod=Encode&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=42cce935175c97afca01f528cf343e8b&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&h264-level=41&h264-videobitdepth=8&h264-profile=high&h264-rangetype=SDR&h264-deinterlace=true&TranscodeReasons=VideoCodecNotSupported,%20AudioCodecNotSupported,%20SubtitleCodecNotSupported
[12:56:04] [INF] [88] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[12:56:04] [INF] [88] Jellyfin.Api.Helpers.TranscodingJobHelper: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -threads 1 -autorotate 0 -canvas_size 1920x800 -i file:"/MediaCenter/media/movies/movie.mkv" -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 h264_nvenc -preset p1 -b:v 11162772 -maxrate 11162772 -bufsize 22325544 -profile:v:0 high -g:v:0 72 -keyint_min:v:0 72 -filter_complex "[0:5]scale=s=1920x800:flags=fast_bilinear,format=yuva420p,hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=format=yuv420p[main];[main][sub]overlay_cuda=eof_action=endall:shortest=1:repeatlast=0" -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/6387e39cbb8b1411eb28a3a29fa9c0af%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/6387e39cbb8b1411eb28a3a29fa9c0af.m3u8"
[12:56:04] [ERR] [88] Jellyfin.Api.Helpers.TranscodingJobHelper: FFmpeg exited with code 1
[12:56:04] [ERR] [88] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /videos/2bd73ab4-8136-8053-0b36-a44342090621/hls1/main/0.ts.
MediaBrowser.Common.FfmpegException: FFmpeg exited with code 1
   at Jellyfin.Api.Helpers.TranscodingJobHelper.StartFfMpeg(StreamState state, String outputPath, String commandLineArguments, HttpRequest request, TranscodingJobType transcodingJobType, CancellationTokenSource cancellationTokenSource, String workingDirectory)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetDynamicSegment(StreamingRequestDto streamingRequest, Int32 segmentId)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetHlsVideoSegment(Guid itemId, String playlistId, Int32 segmentId, String container, Int64 runtimeTicks, Int64 actualSegmentLengthTicks, Nullable`1 static, String params, String tag, String deviceProfileId, String playSessionId, String segmentContainer, Nullable`1 segmentLength, Nullable`1 minSegments, String mediaSourceId, String deviceId, String audioCodec, Nullable`1 enableAutoStreamCopy, Nullable`1 allowVideoStreamCopy, Nullable`1 allowAudioStreamCopy, Nullable`1 breakOnNonKeyFrames, Nullable`1 audioSampleRate, Nullable`1 maxAudioBitDepth, Nullable`1 audioBitRate, Nullable`1 audioChannels, Nullable`1 maxAudioChannels, String profile, String level, Nullable`1 framerate, Nullable`1 maxFramerate, Nullable`1 copyTimestamps, Nullable`1 startTimeTicks, Nullable`1 width, Nullable`1 height, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 videoBitRate, Nullable`1 subtitleStreamIndex, Nullable`1 subtitleMethod, Nullable`1 maxRefFrames, Nullable`1 maxVideoBitDepth, Nullable`1 requireAvc, Nullable`1 deInterlace, Nullable`1 requireNonAnamorphic, Nullable`1 transcodingMaxAudioChannels, Nullable`1 cpuCoreLimit, String liveStreamId, Nullable`1 enableMpegtsM2TsMode, String videoCodec, String subtitleCodec, String transcodeReasons, Nullable`1 audioStreamIndex, Nullable`1 videoStreamIndex, Nullable`1 context, Dictionary`2 streamOptions)
   at lambda_method1733(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[12:56:04] [INF] [77] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for User1. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[12:56:04] [INF] [77] Jellyfin.Api.Helpers.MediaInfoHelper: StreamBuilder.BuildVideoItem( Profile=Anonymous Profile, Path=/MediaCenter/media/movies/movie.mkv, AudioStreamIndex=1, SubtitleStreamIndex=5 ) => ( PlayMethod=Transcode, TranscodeReason=VideoCodecNotSupported, AudioCodecNotSupported, SubtitleCodecNotSupported ) media:/videos/2bd73ab4-8136-8053-0b36-a44342090621/master.m3u8?MediaSourceId=2bd73ab4813680530b36a44342090621&VideoCodec=h264,h264&AudioCodec=aac,mp3&AudioStreamIndex=1&SubtitleStreamIndex=5&VideoBitrate=139616000&AudioBitrate=384000&MaxFramerate=23.976025&api_key=<token>&SubtitleMethod=Encode&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=42cce935175c97afca01f528cf343e8b&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&h264-level=41&h264-videobitdepth=8&h264-profile=high&h264-rangetype=SDR&h264-deinterlace=true&TranscodeReasons=VideoCodecNotSupported,%20AudioCodecNotSupported,%20SubtitleCodecNotSupported
[12:56:04] [INF] [13] Jellyfin.Api.Helpers.TranscodingJobHelper: Deleting partial stream file(s) /config/data/transcodes/6387e39cbb8b1411eb28a3a29fa9c0af.m3u8
[12:56:05] [INF] [71] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[12:56:05] [INF] [71] Jellyfin.Api.Helpers.TranscodingJobHelper: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -threads 1 -autorotate 0 -canvas_size 1920x800 -i file:"/MediaCenter/media/movies/movie.mkv" -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 h264_nvenc -preset p1 -b:v 11162772 -maxrate 11162772 -bufsize 22325544 -profile:v:0 high -g:v:0 72 -keyint_min:v:0 72 -filter_complex "[0:5]scale=s=1920x800:flags=fast_bilinear,format=yuva420p,hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=format=yuv420p[main];[main][sub]overlay_cuda=eof_action=endall:shortest=1:repeatlast=0" -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/64e3c4aba6c512754e347e124fbbb570%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/64e3c4aba6c512754e347e124fbbb570.m3u8"
[12:56:05] [ERR] [71] Jellyfin.Api.Helpers.TranscodingJobHelper: FFmpeg exited with code 1
[12:56:05] [ERR] [71] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /videos/2bd73ab4-8136-8053-0b36-a44342090621/hls1/main/0.ts.
MediaBrowser.Common.FfmpegException: FFmpeg exited with code 1
   at Jellyfin.Api.Helpers.TranscodingJobHelper.StartFfMpeg(StreamState state, String outputPath, String commandLineArguments, HttpRequest request, TranscodingJobType transcodingJobType, CancellationTokenSource cancellationTokenSource, String workingDirectory)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetDynamicSegment(StreamingRequestDto streamingRequest, Int32 segmentId)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetHlsVideoSegment(Guid itemId, String playlistId, Int32 segmentId, String container, Int64 runtimeTicks, Int64 actualSegmentLengthTicks, Nullable`1 static, String params, String tag, String deviceProfileId, String playSessionId, String segmentContainer, Nullable`1 segmentLength, Nullable`1 minSegments, String mediaSourceId, String deviceId, String audioCodec, Nullable`1 enableAutoStreamCopy, Nullable`1 allowVideoStreamCopy, Nullable`1 allowAudioStreamCopy, Nullable`1 breakOnNonKeyFrames, Nullable`1 audioSampleRate, Nullable`1 maxAudioBitDepth, Nullable`1 audioBitRate, Nullable`1 audioChannels, Nullable`1 maxAudioChannels, String profile, String level, Nullable`1 framerate, Nullable`1 maxFramerate, Nullable`1 copyTimestamps, Nullable`1 startTimeTicks, Nullable`1 width, Nullable`1 height, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 videoBitRate, Nullable`1 subtitleStreamIndex, Nullable`1 subtitleMethod, Nullable`1 maxRefFrames, Nullable`1 maxVideoBitDepth, Nullable`1 requireAvc, Nullable`1 deInterlace, Nullable`1 requireNonAnamorphic, Nullable`1 transcodingMaxAudioChannels, Nullable`1 cpuCoreLimit, String liveStreamId, Nullable`1 enableMpegtsM2TsMode, String videoCodec, String subtitleCodec, String transcodeReasons, Nullable`1 audioStreamIndex, Nullable`1 videoStreamIndex, Nullable`1 context, Dictionary`2 streamOptions)
   at lambda_method1733(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[12:56:05] [INF] [71] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for User1. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[12:56:05] [INF] [71] Jellyfin.Api.Helpers.MediaInfoHelper: StreamBuilder.BuildVideoItem( Profile=Anonymous Profile, Path=/MediaCenter/media/movies/movie.mkv, AudioStreamIndex=1, SubtitleStreamIndex=5 ) => ( PlayMethod=Transcode, TranscodeReason=VideoCodecNotSupported, AudioCodecNotSupported, SubtitleCodecNotSupported ) media:/videos/2bd73ab4-8136-8053-0b36-a44342090621/master.m3u8?MediaSourceId=2bd73ab4813680530b36a44342090621&VideoCodec=h264,h264&AudioCodec=aac,mp3&AudioStreamIndex=1&SubtitleStreamIndex=5&VideoBitrate=139616000&AudioBitrate=384000&MaxFramerate=23.976025&api_key=<token>&SubtitleMethod=Encode&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=42cce935175c97afca01f528cf343e8b&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&h264-level=41&h264-videobitdepth=8&h264-profile=high&h264-rangetype=SDR&h264-deinterlace=true&TranscodeReasons=VideoCodecNotSupported,%20AudioCodecNotSupported,%20SubtitleCodecNotSupported
[12:56:05] [INF] [71] Jellyfin.Api.Helpers.TranscodingJobHelper: Deleting partial stream file(s) /config/data/transcodes/64e3c4aba6c512754e347e124fbbb570.m3u8
[12:56:05] [INF] [86] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[12:56:05] [INF] [86] Jellyfin.Api.Helpers.TranscodingJobHelper: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -threads 1 -autorotate 0 -canvas_size 1920x800 -i file:"/MediaCenter/media/movies/movie.mkv" -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 h264_nvenc -preset p1 -b:v 11162772 -maxrate 11162772 -bufsize 22325544 -profile:v:0 high -g:v:0 72 -keyint_min:v:0 72 -filter_complex "[0:5]scale=s=1920x800:flags=fast_bilinear,format=yuva420p,hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=format=yuv420p[main];[main][sub]overlay_cuda=eof_action=endall:shortest=1:repeatlast=0" -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/b76b8d0928420f7ee43a42bd87e9b8d3%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/b76b8d0928420f7ee43a42bd87e9b8d3.m3u8"
[12:56:05] [ERR] [86] Jellyfin.Api.Helpers.TranscodingJobHelper: FFmpeg exited with code 1
[12:56:05] [ERR] [86] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /videos/2bd73ab4-8136-8053-0b36-a44342090621/hls1/main/0.ts.
MediaBrowser.Common.FfmpegException: FFmpeg exited with code 1
   at Jellyfin.Api.Helpers.TranscodingJobHelper.StartFfMpeg(StreamState state, String outputPath, String commandLineArguments, HttpRequest request, TranscodingJobType transcodingJobType, CancellationTokenSource cancellationTokenSource, String workingDirectory)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetDynamicSegment(StreamingRequestDto streamingRequest, Int32 segmentId)
   at Jellyfin.Api.Controllers.DynamicHlsController.GetHlsVideoSegment(Guid itemId, String playlistId, Int32 segmentId, String container, Int64 runtimeTicks, Int64 actualSegmentLengthTicks, Nullable`1 static, String params, String tag, String deviceProfileId, String playSessionId, String segmentContainer, Nullable`1 segmentLength, Nullable`1 minSegments, String mediaSourceId, String deviceId, String audioCodec, Nullable`1 enableAutoStreamCopy, Nullable`1 allowVideoStreamCopy, Nullable`1 allowAudioStreamCopy, Nullable`1 breakOnNonKeyFrames, Nullable`1 audioSampleRate, Nullable`1 maxAudioBitDepth, Nullable`1 audioBitRate, Nullable`1 audioChannels, Nullable`1 maxAudioChannels, String profile, String level, Nullable`1 framerate, Nullable`1 maxFramerate, Nullable`1 copyTimestamps, Nullable`1 startTimeTicks, Nullable`1 width, Nullable`1 height, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 videoBitRate, Nullable`1 subtitleStreamIndex, Nullable`1 subtitleMethod, Nullable`1 maxRefFrames, Nullable`1 maxVideoBitDepth, Nullable`1 requireAvc, Nullable`1 deInterlace, Nullable`1 requireNonAnamorphic, Nullable`1 transcodingMaxAudioChannels, Nullable`1 cpuCoreLimit, String liveStreamId, Nullable`1 enableMpegtsM2TsMode, String videoCodec, String subtitleCodec, String transcodeReasons, Nullable`1 audioStreamIndex, Nullable`1 videoStreamIndex, Nullable`1 context, Dictionary`2 streamOptions)
   at lambda_method1733(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[12:56:05] [INF] [82] Jellyfin.Api.Helpers.TranscodingJobHelper: Deleting partial stream file(s) /config/data/transcodes/b76b8d0928420f7ee43a42bd87e9b8d3.m3u8
github-actions[bot] commented 4 months ago

Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.

j0nnymoe commented 4 months ago

Does opensuse have SELinux? No issues using Nvidia with jellyfin here.

JurgenCruz commented 4 months ago

From what I can read it does have SELinux, but is there a command I can run to verify?

j0nnymoe commented 4 months ago

I believe sestatus will show it.

JurgenCruz commented 4 months ago

sestatus is not found. I do have AppGuard though. should I look into that?

Know that I think of it, I ran docker exec -it jellyfin ldconfig after reading the official docker instructions trying to troubleshoot this problem. Could that have impacted?

JurgenCruz commented 4 months ago

I just spawned an official jellyfin docker image and ther it is working. however the commands are different.

Official Image:

/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -fflags +genpts -i file:"/MediaCenter/media/movies/movie.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/transcodes/d4f88456e2df8a53fbc108a17da107f2%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/transcodes/d4f88456e2df8a53fbc108a17da107f2.m3u8"

linuxserver image: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -threads 1 -autorotate 0 -canvas_size 1920x800 -i file:"/MediaCenter/media/movies/movie.mkv" -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 h264_nvenc -preset p1 -b:v 11162772 -maxrate 11162772 -bufsize 22325544 -profile:v:0 high -g:v:0 72 -keyint_min:v:0 72 -filter_complex "[0:5]scale=s=1920x800:flags=fast_bilinear,format=yuva420p,hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=format=yuv420p[main];[main][sub]overlay_cuda=eof_action=endall:shortest=1:repeatlast=0" -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/6387e39cbb8b1411eb28a3a29fa9c0af%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/6387e39cbb8b1411eb28a3a29fa9c0af.m3u8"

not sure why there is a difference but the second one is trying to use Cuda.

j0nnymoe commented 4 months ago

Nvidia uses cuda for transcoding. The top command to me looks like it's not using your GPU.

j0nnymoe commented 4 months ago

It seems like something either opensuse is doing or you've done with the creation of the container is messing with the his. Realistically you shouldn't need to adjust permissions when adding Nvidia in as that handles it all for you.

JurgenCruz commented 4 months ago

Nvidia uses cuda for transcoding. The top command to me looks like it's not using your GPU.

I agree, I can confirm it is not using because nvidia-smi shows no usage. I won't be fiddling with the official image. The linuxserver's image does seem to be trying to use CUDA but not able to. the root user inside the container can execute nvidia-smi inside just fine. it is just the abc user that doesn't seem to have permissions.

my understanding is that PUID and PGID are just used for accessing the volumes with the right permissions, right? and in any case I added both users to the video group if that is relevant. not sure what to do. I'll try recreating the container from scratch and report back.

JurgenCruz commented 4 months ago

Ok, something even more weird. I created another container with linuxserver's image and this uses yet another ffmpeg command:

/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -fflags +genpts -f matroska,webm -i file:"/MediaCenter/media/movies/movie.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/4b86aa41bde3e2e2d2cf29b80bd59710%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/4b86aa41bde3e2e2d2cf29b80bd59710.m3u8"

No CUDA being used. I tried running nvidia-smi as root and it worked. Then as abc and same thing about permissions. So now I don't know what I did for the first container to enable CUDA. maybe the ldconfig?

j0nnymoe commented 4 months ago

Are you setting your transcoding settings within jellyfin? it won't use it by default.

JurgenCruz commented 4 months ago

Yes, I enabled Nvidia NVEC HW acceleration and enabled all codecs. Then, enabled NVDEC decoder and hardware encoding. Finally enabled tone mapping.

I also tried the ldconfig in second image and didn't change anything, so I don't think that is it.

j0nnymoe commented 4 months ago

[2024-03-10 21:20:47.925 +00:00] [INF] [35] Jellyfin.Api.Helpers.TranscodingJobHelper: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -threads 1 -autorotate 0 -i file:\"/data/media/tv/tvshow/Season 01/S01E01 - Episode 1.mp4\" -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_nvenc -preset p1 -b:v 1274180 -maxrate 1274180 -bufsize 2548360 -profile:v:0 high -g:v:0 75 -keyint_min:v:0 75 -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=w=720:h=404:format=yuv420p\" -codec:a:0 copy -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename \"/transcode/e06717188347f2383877c7b391c753fc%d.ts\" -hls_playlist_type vod -hls_list_size 0 -y \"/transcode/e06717188347f2383877c7b391c753fc.m3u8\""

This is working fine in my deployment of jellyfin. Maybe you're trying to run a codec that your gpu doesn't support? Unfortunately I can't replicate your issue.

JurgenCruz commented 4 months ago

Can you share your compose file? or how are you deploying your container?

j0nnymoe commented 4 months ago

Unfortunately it's on my test unraid system which has my nvidia card in. I can give you the docker run though (just ignore the unraid specific bits):


  -d
  --name='jellyfin'
  --net='proxy'
  --cpuset-cpus='1,2,3'
  -e TZ="Europe/London"
  -e HOST_OS="Unraid"
  -e HOST_HOSTNAME="Server"
  -e HOST_CONTAINERNAME="jellyfin"
  -e 'NVIDIA_VISIBLE_DEVICES'='all'
  -e 'PUID'='99'
  -e 'PGID'='100'
  -e 'UMASK'='022'
  -l net.unraid.docker.managed=dockerman
  -l net.unraid.docker.webui='http://[IP]:[PORT:8096]'
  -l net.unraid.docker.icon='https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jellyfin-logo.png'
  -p '8097:8096/tcp'
  -v '/mnt/user/data/media/':'/data/media':'rw'
  -v '/mnt/disks/ssd/.appdata/letsencrypt/keys/letsencrypt/':'/certs':'ro,slave'
  -v '/tmp/':'/transcode':'rw'
  -v '/mnt/disks/ssd/.appdata/jellyfin':'/config':'rw,slave'
  --device=/dev/dri
  --runtime=nvidia 'lscr.io/linuxserver/jellyfin' ```
JurgenCruz commented 4 months ago

Discovered why one was not using cuda and the other was. one was trying to load subtitles and the other one wasn't. I enabled subtitles in both and now both fail.

I ran ll /dev/nvidia* and found the following:

root@8d5ddf97fff3:/# ll /dev/nvidia*
crw-rw---- 1 root  484 195,   0 Mar 10 18:50 /dev/nvidia0
crw-rw---- 1 root  484 195, 255 Mar 10 18:50 /dev/nvidiactl
crw-rw---- 1 root  484 195, 254 Mar 10 18:50 /dev/nvidia-modeset
crw-rw-rw- 1 root root 235,   0 Mar 10 18:50 /dev/nvidia-uvm
crw-rw-rw- 1 root root 235,   1 Mar 10 18:50 /dev/nvidia-uvm-tools

/dev/nvidia-caps:
total 0
drwxr-xr-x 2 root root     80 Mar 10 19:26 ./
drwxr-xr-x 6 root root    460 Mar 10 19:26 ../
cr-------- 1 root root 238, 1 Mar 10 19:26 nvidia-cap1
cr--r--r-- 1 root root 238, 2 Mar 10 19:26 nvidia-cap2

gid 484 is the video group in the host machine. if I do a cat /etc/group I get:

root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:
fax:x:21:
voice:x:22:
cdrom:x:24:
floppy:x:25:
tape:x:26:
sudo:x:27:
audio:x:29:
dip:x:30:
www-data:x:33:
backup:x:34:
operator:x:37:
list:x:38:
irc:x:39:
src:x:40:
gnats:x:41:
shadow:x:42:
utmp:x:43:
video:x:44:jellyfin
sasl:x:45:
plugdev:x:46:
staff:x:50:
games:x:60:
users:x:100:abc
nogroup:x:65534:
crontab:x:101:
abc:x:472:
jellyfin:x:102:

From this I can see that:

  1. jellyfin user is in the video group inside the container, but the ids do not match
  2. abc user is just in the users group
  3. there is no group with id 484

Not sure if this is the problem, but looks like it. only the container's root will be able to access the gpus

j0nnymoe commented 4 months ago
root@jf:/# ll /dev/nvidia*
crw-rw-rw- 1 root root 195, 255 Mar 10 21:16 /dev/nvidiactl
crw-rw-rw- 1 root root 241,   0 Mar 10 21:16 /dev/nvidia-uvm
crw-rw-rw- 1 root root 241,   1 Mar 10 21:16 /dev/nvidia-uvm-tools

I don't believe this to be a container issue. If it was, we would have more reports of this (and I wouldn't be able to run it).

I believe there is something extra going on with either opensuse or how you've configured your users/groups with docker. Unfortunately I'm not in a position to spin up a test opensuse instance to look into this further.

j0nnymoe commented 4 months ago

Personally I would look further into if opensuse does have SELinux enabled by default and if so, try disabling it.

JurgenCruz commented 4 months ago

if I added the abc user to 484 group it was able to run the nvidia-smi. but yeah, that is not a solution that will persist. I also think it might be opensuse, will look into it and selinux. Thank you for your help so far :)

JurgenCruz commented 4 months ago

The only selinux package I have installed is libselinux1. and from the GRUB I can see that the "security=apparmor" parameter is set, not selinux. back to square one =(

JurgenCruz commented 4 months ago

So, I tried with the official image again after realizing the problem was not loading the subtitles. And this time it also failed. But as soon as I removed the user: 472:472 from the compose file, it actually worked just fine. It seems like the official image runs jellyfin with the root user inside the container unless you set the user. Setting the user breaks it.

I tried removing the PUID and PGID from the linuxserver's container but now the problem is it cannot read the movie files any more because of permissions. plus I really don't think it would solve anything since it is still using the abc user, just that it is no longer mapped with the PUID and PGID.

LinuxServer-CI commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity. This might be due to missing feedback from OP. It will be closed if no further activity occurs. Thank you for your contributions.