mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-25 20:03:28 +00:00
fix quality switching bug
This commit is contained in:
parent
2f90617eee
commit
6331e69a2f
3 changed files with 46 additions and 12 deletions
|
|
@ -40,6 +40,7 @@ function useIsIosHls() {
|
||||||
export function QualityView({ id }: { id: string }) {
|
export function QualityView({ id }: { id: string }) {
|
||||||
const router = useOverlayRouter(id);
|
const router = useOverlayRouter(id);
|
||||||
const isIosHls = useIsIosHls();
|
const isIosHls = useIsIosHls();
|
||||||
|
const sourceType = usePlayerStore((s) => s.source?.type);
|
||||||
const availableQualities = usePlayerStore((s) => s.qualities);
|
const availableQualities = usePlayerStore((s) => s.qualities);
|
||||||
const currentQuality = usePlayerStore((s) => s.currentQuality);
|
const currentQuality = usePlayerStore((s) => s.currentQuality);
|
||||||
const switchQuality = usePlayerStore((s) => s.switchQuality);
|
const switchQuality = usePlayerStore((s) => s.switchQuality);
|
||||||
|
|
@ -50,14 +51,18 @@ export function QualityView({ id }: { id: string }) {
|
||||||
const setLastChosenQuality = useQualityStore((s) => s.setLastChosenQuality);
|
const setLastChosenQuality = useQualityStore((s) => s.setLastChosenQuality);
|
||||||
const autoQuality = useQualityStore((s) => s.quality.automaticQuality);
|
const autoQuality = useQualityStore((s) => s.quality.automaticQuality);
|
||||||
|
|
||||||
|
// Auto quality only makes sense for HLS sources
|
||||||
|
const supportsAutoQuality = sourceType === "hls";
|
||||||
|
|
||||||
const change = useCallback(
|
const change = useCallback(
|
||||||
(q: SourceQuality) => {
|
(q: SourceQuality) => {
|
||||||
setLastChosenQuality(q);
|
setLastChosenQuality(q);
|
||||||
setAutomaticQuality(false);
|
// Don't disable auto quality when manually selecting a quality
|
||||||
|
// Keep auto quality enabled by default unless user explicitly toggles it
|
||||||
switchQuality(q);
|
switchQuality(q);
|
||||||
router.close();
|
router.close();
|
||||||
},
|
},
|
||||||
[router, switchQuality, setLastChosenQuality, setAutomaticQuality],
|
[router, switchQuality, setLastChosenQuality],
|
||||||
);
|
);
|
||||||
|
|
||||||
const changeAutomatic = useCallback(() => {
|
const changeAutomatic = useCallback(() => {
|
||||||
|
|
@ -90,12 +95,18 @@ export function QualityView({ id }: { id: string }) {
|
||||||
{qualityToString(v)}
|
{qualityToString(v)}
|
||||||
</SelectableLink>
|
</SelectableLink>
|
||||||
))}
|
))}
|
||||||
<Menu.Divider />
|
{supportsAutoQuality && (
|
||||||
<Menu.Link
|
<>
|
||||||
rightSide={<Toggle onClick={changeAutomatic} enabled={autoQuality} />}
|
<Menu.Divider />
|
||||||
>
|
<Menu.Link
|
||||||
{t("player.menus.quality.automaticLabel")}
|
rightSide={
|
||||||
</Menu.Link>
|
<Toggle onClick={changeAutomatic} enabled={autoQuality} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("player.menus.quality.automaticLabel")}
|
||||||
|
</Menu.Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Menu.SmallText>
|
<Menu.SmallText>
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey={
|
i18nKey={
|
||||||
|
|
|
||||||
|
|
@ -313,9 +313,24 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]);
|
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]);
|
||||||
emit("changedquality", quality);
|
emit("changedquality", quality);
|
||||||
} else {
|
} else {
|
||||||
// When automatic quality is disabled, re-lock to preferred quality
|
// When automatic quality is disabled, check if current level matches preferred quality
|
||||||
// This prevents HLS.js from switching levels unexpectedly
|
const currentQuality = hlsLevelToQuality(
|
||||||
setupQualityForHls();
|
hls.levels[hls.currentLevel],
|
||||||
|
);
|
||||||
|
const preferredQualityLevel = getPreferredQuality(
|
||||||
|
hlsLevelsToQualities(hls.levels),
|
||||||
|
{
|
||||||
|
lastChosenQuality: preferenceQuality,
|
||||||
|
automaticQuality: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// Only re-lock if the current level doesn't match our preferred quality
|
||||||
|
if (currentQuality !== preferredQualityLevel) {
|
||||||
|
setupQualityForHls();
|
||||||
|
} else {
|
||||||
|
// Emit the quality change since we're now at the correct level
|
||||||
|
emit("changedquality", currentQuality);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, () => {
|
hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, () => {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,15 @@ export function selectQuality(
|
||||||
const availableQualities = Object.entries(source.qualities)
|
const availableQualities = Object.entries(source.qualities)
|
||||||
.filter((entry) => (entry[1].url.length ?? 0) > 0)
|
.filter((entry) => (entry[1].url.length ?? 0) > 0)
|
||||||
.map((entry) => entry[0]) as SourceQuality[];
|
.map((entry) => entry[0]) as SourceQuality[];
|
||||||
const quality = getPreferredQuality(availableQualities, qualityPreferences);
|
// For file sources (MP4), always use manual quality selection since they don't support switching
|
||||||
|
const manualQualityPreferences = {
|
||||||
|
...qualityPreferences,
|
||||||
|
automaticQuality: false,
|
||||||
|
};
|
||||||
|
const quality = getPreferredQuality(
|
||||||
|
availableQualities,
|
||||||
|
manualQualityPreferences,
|
||||||
|
);
|
||||||
if (quality) {
|
if (quality) {
|
||||||
const stream = source.qualities[quality];
|
const stream = source.qualities[quality];
|
||||||
if (stream) {
|
if (stream) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue