Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to always burn in subtitles if transcoding is triggered #5906

Merged
merged 11 commits into from
Oct 9, 2024

Conversation

gnattu
Copy link
Member

@gnattu gnattu commented Aug 12, 2024

Changes

Subtitles often have synchronization issues after video transcoding. This option allows the client to opt-in to always burn in all subtitles, preventing out-of-sync subtitles at the cost of transcoding performance.

This also fixed the helper text for subtitle burn in as that option itself will trigger transcoding.

Issues

Depends on jellyfin/jellyfin#12430

@gnattu gnattu requested a review from a team as a code owner August 12, 2024 02:00
@thornbill thornbill added feature New feature or request backend Requires work on the server to finish labels Aug 12, 2024
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESLint doesn't pass. Please fix all ESLint issues.

src/components/playback/playbackmanager.js Outdated Show resolved Hide resolved
src/components/playback/playbackmanager.js Outdated Show resolved Hide resolved
src/components/playback/playbackmanager.js Outdated Show resolved Hide resolved
src/strings/en-us.json Outdated Show resolved Hide resolved
soultaco83 added a commit to soultaco83/jellyfin-web-requeststab that referenced this pull request Sep 15, 2024
@jellyfin-bot
Copy link
Collaborator

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@jellyfin-bot jellyfin-bot added the merge conflict Conflicts prevent merging label Sep 20, 2024
@jellyfin-bot jellyfin-bot removed the merge conflict Conflicts prevent merging label Sep 20, 2024
Copy link
Contributor

@dmitrylyzo dmitrylyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes requested below are not necessary - it works as is.

src/components/playback/playbackmanager.js Outdated Show resolved Hide resolved
@thornbill thornbill added playback This PR or issue mainly concerns playback and removed backend Requires work on the server to finish labels Sep 21, 2024
@thornbill thornbill added this to the v10.10.0 milestone Sep 21, 2024
@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

The logic is now reworked to reflect the transcoding behavior more accurately. Now depends on server PR #12676

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESLint doesn't pass. Please fix all ESLint issues.

src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
gnattu and others added 2 commits September 22, 2024 00:39
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@dmitrylyzo dmitrylyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick look.

I was also thinking that if we could get the current (sub)stream URL, we could get the "delivery mode" from there. But I'm not sure we can get such information from a native player.

src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

I was also thinking that if we could get the current (sub)stream URL, we could get the "delivery mode" from there.

Not going to work because there will be no change to that because the transcoding pipeline checking for copy codec happens way after that

@dmitrylyzo
Copy link
Contributor

Not going to work because there will be no change to that because the transcoding pipeline checking for copy codec happens way after that

Doing this in the master.m3u8 endpoint would be sufficient. What if streams (main.m3u8) will have an unambiguous set of parameters (1 video codec, 1 audio codec, subtitle delivery method, etc.)?
We are currently passing all possible options, which leads to ambiguity. Btw, transcoding jobs can be distinguished by these (strict) parameters.

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

What if streams (main.m3u8) will have an unambiguous set of parameters (1 video codec, 1 audio codec, subtitle delivery method, etc.)?

The transcoding pipeline needs to perform some sort of fallback due to reasons like encoders being unavailable iirc so we always have ambiguity because the actual codec also depends on the server configuration inside and outside jellyfin.

@dmitrylyzo
Copy link
Contributor

dmitrylyzo commented Sep 21, 2024

The transcoding pipeline needs to perform some sort of fallback due to reasons like encoders being unavailable iirc so we always have ambiguity because the actual codec also depends on the server configuration inside and outside jellyfin.

If we are not going to support changing the server configuration on the fly (during playback), we can "perform some sort of fallback due to reasons like encoders being unavailable" in the master.m3u8 endpoint and generate streams with concrete set of parameters.

Moreover, we can (should) probably account for "encoders being unavailable" in the PlaybackInfo endpoint.

@dmitrylyzo dmitrylyzo added the backend Requires work on the server to finish label Sep 21, 2024
@dmitrylyzo
Copy link
Contributor

In addition to Session promise refactoring:

#5906 (comment)
here and below

return Promise.resolve({
MediaSources: [item.PresetMediaSource]
});

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESLint doesn't pass. Please fix all ESLint issues.

src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@dmitrylyzo dmitrylyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried changing subtitles during playback (SRT -> ASS (burn) -> SRT). On the second change, it disables subtitles. Burn when transcoding is disabled.

It requests a session too early because PlaybackManager sets the subtitles right away.

player.setSubtitleStreamIndex(selectedTrackElementIndex);

changeStream (video element/hls.js) doesn't have enough time to update the session on the server.

We could delay changing subtitles in the player and call setSubtitleStreamIndex in onStartedAndNavigatedToOsd (it's already there).

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

Burn when transcoding is disabled.

Then nothing should be requested, why it behaves differently?

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

I really cannot reproduce this behavior with current implementation. Nothing is requested when you turned that option off so even if you set it right away it should not disable the srt subtitle.

@dmitrylyzo
Copy link
Contributor

dmitrylyzo commented Sep 21, 2024

I really cannot reproduce this behavior with current implementation. Nothing is requested when you turned that option off so even if you set it right away it should not disable the srt subtitle.

At first I tested with this feature enabled, and the session was requested before the player changed the video.
I then disabled it, but the issue (disabling subtitles) remained. Perhaps it is not related.

There may be something wrong with this code and #subtitleTrackIndexToSetOnPlaying becomes -1:

this.#subtitleTrackIndexToSetOnPlaying = options.mediaSource.DefaultSubtitleStreamIndex == null ? -1 : options.mediaSource.DefaultSubtitleStreamIndex;
if (this.#subtitleTrackIndexToSetOnPlaying != null && this.#subtitleTrackIndexToSetOnPlaying >= 0) {
const initialSubtitleStream = options.mediaSource.MediaStreams[this.#subtitleTrackIndexToSetOnPlaying];
if (!initialSubtitleStream || initialSubtitleStream.DeliveryMethod === 'Encode') {
this.#subtitleTrackIndexToSetOnPlaying = -1;
secondaryTrackValid = false;
}
// secondary track should not be shown if primary track is no longer a valid pair
if (initialSubtitleStream && !playbackManager.trackHasSecondarySubtitleSupport(initialSubtitleStream, this)) {
secondaryTrackValid = false;
}
} else {
secondaryTrackValid = false;
}

@dmitrylyzo
Copy link
Contributor

Then nothing should be requested, why it behaves differently?

Btw, we hide it, so it can be enabled but hidden.

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

Btw, we hide it, so it can be enabled but hidden.

No, if you select the subtitle again you can show it. You disabled that option, nothing will be hidden

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

I can confirm what you found is not related to this change. You can even reproduce the index reverted to -1 behavior on current master.

It still looks like some kind of racing issue, but not related to session. The subtitle is loaded on current video stream and then the video stream is reloaded because transcode -> remux change, and then the index is reset to -1 during this reload.

@dmitrylyzo
Copy link
Contributor

No, if you select the subtitle again you can show it. You disabled that option, nothing will be hidden

I mean that alwaysBurnInSubtitleWhenTranscoding remains enabled (but hidden) when you change burn-in option.

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

I mean that alwaysBurnInSubtitleWhenTranscoding remains enabled (but hidden) when you change burn-in option.

WTF, that is so wrong. We need to always show that.

@gnattu
Copy link
Member Author

gnattu commented Sep 21, 2024

Wait, it does not hide? the one becomes hidden is the PGS one not the burn in one

@dmitrylyzo
Copy link
Contributor

WTF, that is so wrong. We need to always show that.

Oh, sorry - false alarm. I looked at the PGS one. 😅

src/plugins/htmlVideoPlayer/plugin.js Outdated Show resolved Hide resolved
}

const player = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, arrow function saves the original this by itself.
But using a helper variable with a meaningful name is clearer. 🤷‍♂️

@dmitrylyzo dmitrylyzo removed the backend Requires work on the server to finish label Sep 26, 2024
@jellyfin-bot jellyfin-bot added the merge conflict Conflicts prevent merging label Oct 8, 2024
@jellyfin-bot
Copy link
Collaborator

This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.

@jellyfin-bot jellyfin-bot removed the merge conflict Conflicts prevent merging label Oct 8, 2024
Copy link

sonarcloud bot commented Oct 8, 2024

@jellyfin-bot
Copy link
Collaborator

Cloudflare Pages deployment

Latest commit da4265eb4685363fbfc07cdc3f20fb525da2cba8
Status ✅ Deployed!
Preview URL https://b87b54e3.jellyfin-web.pages.dev
Type 🔀 Preview

@thornbill thornbill merged commit 52d4919 into jellyfin:master Oct 9, 2024
12 checks passed
@gnattu gnattu deleted the burn-subtitle-transcoding branch October 9, 2024 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request playback This PR or issue mainly concerns playback
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants