jellyfin-android
jellyfin-android copied to clipboard
WebVTT subtitles not working in integrated player (ExoPlayer)
Describe the bug
When I add an external WebVTT subtitle file to any of my movies, i. e. "Example (1999).vtt", they work as expected in the web player and in the ExoPlayer-based player of the Android TV app, but they aren’t displayed in the ExoPlayer-based player of the Android app. There is an entry in the server logs (see below) that suggests that it attempts to load a file named "Stream.webvtt". When I attempt to open it in a web browser, it just shows "Error processing request.". However, when I replace .webvtt with .vtt, I can see the complete WebVTT file in the web browser (how it’s intended, I guess). So I think the error might be the wrong file extension. Strangely, my issue is quite similar to #1028 , but as stated there, it should already be resolved.
I don’t know if it has to do with this issue, but WebVTT subtitles embedded in a mkv container don’t work either in the integrated player of the Android app for me, but they do in the Android TV app and in the web player. The difference is that, in this case, the entry with the wrong file extension is not present in the server log, suggesting that the issue might not be exactly the same.
By the way, I’ve disabled video transcoding to guarantee that the subtitles are not just burned in.
EDIT: External WebVTT subtitles are indeed working with jellyfin/jellyfin/pull/9669, it just wasn’t present in my build. But WebVTT subtitles embedded with MKVToolNix or mkvmerge still aren’t rendered. When reproducing it, you need to make sure you see the correct subtitles (e. g. by editing the external .vtt file), because for some reason the external subtitles are displayed if both external and embedded subs are present for the same movie, even when you select the embedded subtitle track beforehand in the app or afterwards in the player. All of this is exclusively present in the Android app with ExoPlayer, it works as expected in the Android TV app, desktop and web client and Android app with web player.
Logs
EDIT: server log now irrelevant, see EDIT above.
/* server log, some information is redacted */
[2024-03-11 ...] [ERR] Error processing request. URL "GET" "/Videos/bb7ee354-e194-24ae-5b9e-8de8ce8dc72e/b...e/Subtitles/1/0/Stream.webvtt".
System.ArgumentException: Unsupported format: webvtt
at MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder.GetWriter(String format)
at MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder.ConvertSubtitles(Stream stream, String inputFormat, String outputFormat, Int64 startTimeTicks, Int64 endTimeTicks, Boolean preserveOriginalTimestamps, CancellationToken cancellationToken)
at MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder.MediaBrowser.Controller.MediaEncoding.ISubtitleEncoder.GetSubtitles(BaseItem item, String mediaSourceId, Int32 subtitleStreamIndex, String outputFormat, Int64 startTimeTicks, Int64 endTimeTicks, Boolean preserveOriginalTimestamps, CancellationToken cancellationToken)
at Jellyfin.Api.Controllers.SubtitleController.GetSubtitle(Guid routeItemId, String routeMediaSourceId, Int32 routeIndex, String routeFormat, Nullable`1 itemId, String mediaSourceId, Nullable`1 index, String format, Nullable`1 endPositionTicks, Boolean copyTimestamps, Boolean addVttTimeMap, Int64 startPositionTicks)
at lambda_method1600(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.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)
Application version
2.6.0
Where did you install the app from?
Google Play
Device information
Samsung Galaxy S21 FE
Android version
Android 14
Jellyfin server version
10.8.13
Which video player implementations does this bug apply to?
- [ ] Web player (default)
- [X] Integrated player (ExoPlayer)
- [ ] External player (VLC, mpv, MX Player)
Strangely, my issue is quite similar to #1028 , but as stated there, it should already be resolved.
It was fixed yes, but I don't think it was backported to the current Jellyfin 10.8 releases.
You’re completely right, your commit (thank you) isn’t present in the current server release (10.8.13). I should have checked that beforehand and not just looked at the release date, my bad. So I’m closing this issue and will maybe test a server build from the main branch soon. Just one question: If this is a server issue, why does WebVTT work flawlessly in the Android TV app? I would assume ExoPlayer in the Android app works similarly to ExoPlayer in the Android TV app.
Just one question: If this is a server issue, why does WebVTT work flawlessly in the Android TV app? I would assume ExoPlayer in the Android app works similarly to ExoPlayer in the Android TV app.
Not sure, maybe Android TV uses a different way to fetch the subtitles? I just know in this case the Android app was using the URL provided by the server, which turned out to be incorrect.
I’ve built a patched version of 10.8.13 with your commits and it solves the issue with external .vtt-files. No error in the server log anymore. Unfortunately, embedded WebVTT subtitles (embedded with mkvmerge/mkvtoolnixgui) still don’t render (it seemed to work after selecting them in ExoPlayer, but only the external subs are rendered even when never selected). This confirms my assumption that this is caused by something different, presumably not server related. I’m reopening this issue therefore.
This issue has gone 120 days without comment. To avoid abandoned issues, it will be closed in 21 days if there are no new comments.
If you're the original submitter of this issue, please comment confirming if this issue still affects you in the latest release or master branch, or close the issue if it has been fixed. If you're another user also affected by this bug, please comment confirming so. Either action will remove the stale label.
This bot exists to prevent issues from becoming stale and forgotten. Jellyfin is always moving forward, and bugs are often fixed as side effects of other changes. We therefore ask that bug report authors remain vigilant about their issues to ensure they are closed if fixed, or re-confirmed - perhaps with fresh logs or reproduction examples - regularly. If you have any questions you can reach us on Matrix or Social Media.