mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(core): auto-unmute on volume change and restore volume on unmute (#752)
This commit is contained in:
@@ -78,6 +78,39 @@ describe('volumeFeature', () => {
|
||||
|
||||
expect(video.volume).toBe(1);
|
||||
});
|
||||
|
||||
it('unmutes when setting volume above 0 while muted', async () => {
|
||||
const video = createMockVideo({ muted: true, volume: 0.5 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.setVolume(0.7);
|
||||
|
||||
expect(video.volume).toBe(0.7);
|
||||
expect(video.muted).toBe(false);
|
||||
});
|
||||
|
||||
it('does not unmute when setting volume to 0', async () => {
|
||||
const video = createMockVideo({ muted: true, volume: 0.5 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.setVolume(0);
|
||||
|
||||
expect(video.volume).toBe(0);
|
||||
expect(video.muted).toBe(true);
|
||||
});
|
||||
|
||||
it('does not change muted when already unmuted', async () => {
|
||||
const video = createMockVideo({ muted: false, volume: 0.5 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.setVolume(0.8);
|
||||
|
||||
expect(video.volume).toBe(0.8);
|
||||
expect(video.muted).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggleMuted', () => {
|
||||
@@ -102,6 +135,39 @@ describe('volumeFeature', () => {
|
||||
expect(video.muted).toBe(false);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('restores volume to 0.25 when unmuting at volume 0', async () => {
|
||||
const video = createMockVideo({ muted: true, volume: 0 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.toggleMuted();
|
||||
|
||||
expect(video.muted).toBe(false);
|
||||
expect(video.volume).toBe(0.25);
|
||||
});
|
||||
|
||||
it('preserves volume when unmuting with volume > 0', async () => {
|
||||
const video = createMockVideo({ muted: true, volume: 0.6 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.toggleMuted();
|
||||
|
||||
expect(video.muted).toBe(false);
|
||||
expect(video.volume).toBe(0.6);
|
||||
});
|
||||
|
||||
it('does not change volume when muting', async () => {
|
||||
const video = createMockVideo({ muted: false, volume: 0.8 });
|
||||
const store = createStore<PlayerTarget>()(volumeFeature);
|
||||
store.attach({ media: video, container: null });
|
||||
|
||||
await store.toggleMuted();
|
||||
|
||||
expect(video.muted).toBe(true);
|
||||
expect(video.volume).toBe(0.8);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,9 @@ import { listen } from '@videojs/utils/dom';
|
||||
import type { MediaFeatureAvailability, MediaVolumeState } from '../../../core/media/state';
|
||||
import { definePlayerFeature } from '../../feature';
|
||||
|
||||
/** Volume to restore when unmuting at zero. */
|
||||
const UNMUTE_VOLUME = 0.25;
|
||||
|
||||
export const volumeFeature = definePlayerFeature({
|
||||
name: 'volume',
|
||||
state: ({ target }): MediaVolumeState => ({
|
||||
@@ -12,13 +15,27 @@ export const volumeFeature = definePlayerFeature({
|
||||
|
||||
setVolume(volume: number) {
|
||||
const { media } = target();
|
||||
media.volume = Math.max(0, Math.min(1, volume));
|
||||
const clamped = Math.max(0, Math.min(1, volume));
|
||||
|
||||
// Auto-unmute when raising volume above zero.
|
||||
if (clamped > 0 && media.muted) {
|
||||
media.muted = false;
|
||||
}
|
||||
|
||||
media.volume = clamped;
|
||||
return media.volume;
|
||||
},
|
||||
|
||||
toggleMuted() {
|
||||
const { media } = target();
|
||||
const willUnmute = media.muted;
|
||||
media.muted = !media.muted;
|
||||
|
||||
// Restore a sensible volume when unmuting at zero.
|
||||
if (willUnmute && media.volume === 0) {
|
||||
media.volume = UNMUTE_VOLUME;
|
||||
}
|
||||
|
||||
return media.muted;
|
||||
},
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user