mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 03:39:26 +00:00
Remove mute
This commit is contained in:
@@ -187,7 +187,7 @@ public class ChannelDirectoryService {
|
|||||||
asset.setAudioPitch(request.getAudioPitch());
|
asset.setAudioPitch(request.getAudioPitch());
|
||||||
}
|
}
|
||||||
if (request.getAudioVolume() != null && request.getAudioVolume() >= 0) {
|
if (request.getAudioVolume() != null && request.getAudioVolume() >= 0) {
|
||||||
double clamped = Math.max(0.0, Math.min(1.0, request.getAudioVolume()));
|
double clamped = Math.max(0.0, Math.min(2.0, request.getAudioVolume()));
|
||||||
asset.setAudioVolume(clamped);
|
asset.setAudioVolume(clamped);
|
||||||
}
|
}
|
||||||
assetRepository.save(asset);
|
assetRepository.save(asset);
|
||||||
|
|||||||
@@ -24,16 +24,22 @@ let interactionState = null;
|
|||||||
let lastSizeInputChanged = null;
|
let lastSizeInputChanged = null;
|
||||||
const HANDLE_SIZE = 10;
|
const HANDLE_SIZE = 10;
|
||||||
const ROTATE_HANDLE_OFFSET = 32;
|
const ROTATE_HANDLE_OFFSET = 32;
|
||||||
|
const MAX_VOLUME = 2;
|
||||||
|
const VOLUME_SLIDER_MAX = 200;
|
||||||
|
const VOLUME_CURVE_STRENGTH = -0.6;
|
||||||
|
|
||||||
|
|
||||||
const controlsPanel = document.getElementById('asset-controls');
|
const controlsPanel = document.getElementById('asset-controls');
|
||||||
const widthInput = document.getElementById('asset-width');
|
const widthInput = document.getElementById('asset-width');
|
||||||
const heightInput = document.getElementById('asset-height');
|
const heightInput = document.getElementById('asset-height');
|
||||||
const aspectLockInput = document.getElementById('maintain-aspect');
|
const aspectLockInput = document.getElementById('maintain-aspect');
|
||||||
const speedInput = document.getElementById('asset-speed');
|
const speedInput = document.getElementById('asset-speed');
|
||||||
const muteInput = document.getElementById('asset-muted');
|
|
||||||
const speedLabel = document.getElementById('asset-speed-label');
|
const speedLabel = document.getElementById('asset-speed-label');
|
||||||
|
const volumeInput = document.getElementById('asset-volume');
|
||||||
|
const volumeLabel = document.getElementById('asset-volume-label');
|
||||||
const selectedZLabel = document.getElementById('asset-z-level');
|
const selectedZLabel = document.getElementById('asset-z-level');
|
||||||
const playbackSection = document.getElementById('playback-section');
|
const playbackSection = document.getElementById('playback-section');
|
||||||
|
const volumeSection = document.getElementById('volume-section');
|
||||||
const audioSection = document.getElementById('audio-section');
|
const audioSection = document.getElementById('audio-section');
|
||||||
const layoutSection = document.getElementById('layout-section');
|
const layoutSection = document.getElementById('layout-section');
|
||||||
const audioLoopInput = document.getElementById('asset-audio-loop');
|
const audioLoopInput = document.getElementById('asset-audio-loop');
|
||||||
@@ -41,7 +47,6 @@ const audioDelayInput = document.getElementById('asset-audio-delay');
|
|||||||
const audioSpeedInput = document.getElementById('asset-audio-speed');
|
const audioSpeedInput = document.getElementById('asset-audio-speed');
|
||||||
const audioSpeedLabel = document.getElementById('asset-audio-speed-label');
|
const audioSpeedLabel = document.getElementById('asset-audio-speed-label');
|
||||||
const audioPitchInput = document.getElementById('asset-audio-pitch');
|
const audioPitchInput = document.getElementById('asset-audio-pitch');
|
||||||
const audioVolumeInput = document.getElementById('asset-audio-volume');
|
|
||||||
const controlsPlaceholder = document.getElementById('asset-controls-placeholder');
|
const controlsPlaceholder = document.getElementById('asset-controls-placeholder');
|
||||||
const fileNameLabel = document.getElementById('asset-file-name');
|
const fileNameLabel = document.getElementById('asset-file-name');
|
||||||
const assetInspector = document.getElementById('asset-inspector');
|
const assetInspector = document.getElementById('asset-inspector');
|
||||||
@@ -167,6 +172,38 @@ function setAudioSpeedLabel(percentValue) {
|
|||||||
audioSpeedLabel.textContent = `${formatted}x`;
|
audioSpeedLabel.textContent = `${formatted}x`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clamp(value, min, max) {
|
||||||
|
return Math.min(max, Math.max(min, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function sliderToVolume(sliderValue) {
|
||||||
|
const normalized = clamp(sliderValue, 0, VOLUME_SLIDER_MAX) / VOLUME_SLIDER_MAX;
|
||||||
|
const curved = normalized + VOLUME_CURVE_STRENGTH * normalized * (1 - normalized) * (1 - 2 * normalized);
|
||||||
|
return clamp(curved * MAX_VOLUME, 0, MAX_VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
function volumeToSlider(volumeValue) {
|
||||||
|
const target = clamp(volumeValue ?? 1, 0, MAX_VOLUME) / MAX_VOLUME;
|
||||||
|
let low = 0;
|
||||||
|
let high = VOLUME_SLIDER_MAX;
|
||||||
|
for (let i = 0; i < 24; i += 1) {
|
||||||
|
const mid = (low + high) / 2;
|
||||||
|
const midNormalized = sliderToVolume(mid) / MAX_VOLUME;
|
||||||
|
if (midNormalized < target) {
|
||||||
|
low = mid;
|
||||||
|
} else {
|
||||||
|
high = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.round(high);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVolumeLabel(sliderValue) {
|
||||||
|
if (!volumeLabel) return;
|
||||||
|
const volumePercent = Math.round(sliderToVolume(sliderValue) * 100);
|
||||||
|
volumeLabel.textContent = `${volumePercent}%`;
|
||||||
|
}
|
||||||
|
|
||||||
function queueAudioForUnlock(controller) {
|
function queueAudioForUnlock(controller) {
|
||||||
if (!controller) return;
|
if (!controller) return;
|
||||||
pendingAudioUnlock.add(controller);
|
pendingAudioUnlock.add(controller);
|
||||||
@@ -185,12 +222,11 @@ if (widthInput) widthInput.addEventListener('change', () => commitSizeChange());
|
|||||||
if (heightInput) heightInput.addEventListener('input', () => handleSizeInputChange('height'));
|
if (heightInput) heightInput.addEventListener('input', () => handleSizeInputChange('height'));
|
||||||
if (heightInput) heightInput.addEventListener('change', () => commitSizeChange());
|
if (heightInput) heightInput.addEventListener('change', () => commitSizeChange());
|
||||||
if (speedInput) speedInput.addEventListener('input', updatePlaybackFromInputs);
|
if (speedInput) speedInput.addEventListener('input', updatePlaybackFromInputs);
|
||||||
if (muteInput) muteInput.addEventListener('change', updateMuteFromInput);
|
if (volumeInput) volumeInput.addEventListener('input', updateVolumeFromInput);
|
||||||
if (audioLoopInput) audioLoopInput.addEventListener('change', updateAudioSettingsFromInputs);
|
if (audioLoopInput) audioLoopInput.addEventListener('change', updateAudioSettingsFromInputs);
|
||||||
if (audioDelayInput) audioDelayInput.addEventListener('change', updateAudioSettingsFromInputs);
|
if (audioDelayInput) audioDelayInput.addEventListener('change', updateAudioSettingsFromInputs);
|
||||||
if (audioSpeedInput) audioSpeedInput.addEventListener('change', updateAudioSettingsFromInputs);
|
if (audioSpeedInput) audioSpeedInput.addEventListener('change', updateAudioSettingsFromInputs);
|
||||||
if (audioPitchInput) audioPitchInput.addEventListener('change', updateAudioSettingsFromInputs);
|
if (audioPitchInput) audioPitchInput.addEventListener('change', updateAudioSettingsFromInputs);
|
||||||
if (audioVolumeInput) audioVolumeInput.addEventListener('change', updateAudioSettingsFromInputs);
|
|
||||||
if (selectedVisibilityBtn) {
|
if (selectedVisibilityBtn) {
|
||||||
selectedVisibilityBtn.addEventListener('click', () => {
|
selectedVisibilityBtn.addEventListener('click', () => {
|
||||||
const asset = getSelectedAsset();
|
const asset = getSelectedAsset();
|
||||||
@@ -796,7 +832,7 @@ function applyAudioSettings(controller, asset, resetPosition = false) {
|
|||||||
const speed = Math.max(0.25, asset.audioSpeed || 1);
|
const speed = Math.max(0.25, asset.audioSpeed || 1);
|
||||||
const pitch = Math.max(0.5, asset.audioPitch || 1);
|
const pitch = Math.max(0.5, asset.audioPitch || 1);
|
||||||
controller.element.playbackRate = speed * pitch;
|
controller.element.playbackRate = speed * pitch;
|
||||||
const volume = Math.max(0, Math.min(1, asset.audioVolume ?? 1));
|
const volume = clamp(asset.audioVolume ?? 1, 0, MAX_VOLUME);
|
||||||
controller.element.volume = volume;
|
controller.element.volume = volume;
|
||||||
if (resetPosition) {
|
if (resetPosition) {
|
||||||
controller.element.currentTime = 0;
|
controller.element.currentTime = 0;
|
||||||
@@ -871,7 +907,9 @@ function ensureMedia(asset) {
|
|||||||
element.crossOrigin = 'anonymous';
|
element.crossOrigin = 'anonymous';
|
||||||
if (isVideoElement(element)) {
|
if (isVideoElement(element)) {
|
||||||
element.loop = true;
|
element.loop = true;
|
||||||
element.muted = asset.muted ?? true;
|
const volume = clamp(asset.audioVolume ?? 1, 0, MAX_VOLUME);
|
||||||
|
element.muted = volume === 0;
|
||||||
|
element.volume = Math.min(volume, 1);
|
||||||
element.playsInline = true;
|
element.playsInline = true;
|
||||||
element.autoplay = false;
|
element.autoplay = false;
|
||||||
element.preload = 'metadata';
|
element.preload = 'metadata';
|
||||||
@@ -972,26 +1010,19 @@ function applyMediaSettings(element, asset) {
|
|||||||
}
|
}
|
||||||
const nextSpeed = asset.speed ?? 1;
|
const nextSpeed = asset.speed ?? 1;
|
||||||
const effectiveSpeed = Math.max(nextSpeed, 0.01);
|
const effectiveSpeed = Math.max(nextSpeed, 0.01);
|
||||||
const wasMuted = element.muted;
|
|
||||||
if (element.playbackRate !== effectiveSpeed) {
|
if (element.playbackRate !== effectiveSpeed) {
|
||||||
element.playbackRate = effectiveSpeed;
|
element.playbackRate = effectiveSpeed;
|
||||||
}
|
}
|
||||||
const shouldMute = asset.muted ?? true;
|
const volume = clamp(asset.audioVolume ?? 1, 0, MAX_VOLUME);
|
||||||
if (element.muted !== shouldMute) {
|
element.muted = volume === 0;
|
||||||
element.muted = shouldMute;
|
element.volume = Math.min(volume, 1);
|
||||||
}
|
|
||||||
if (nextSpeed === 0) {
|
if (nextSpeed === 0) {
|
||||||
element.pause();
|
element.pause();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const playPromise = element.play();
|
const playPromise = element.play();
|
||||||
if (playPromise?.catch) {
|
if (playPromise?.catch) {
|
||||||
playPromise.catch(() => {
|
playPromise.catch(() => { });
|
||||||
if (!shouldMute && wasMuted) {
|
|
||||||
element.muted = true;
|
|
||||||
element.play().catch(() => { });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1426,15 +1457,24 @@ function updateSelectedAssetControls(asset = getSelectedAsset()) {
|
|||||||
playbackSection.classList.toggle('hidden', !shouldShowPlayback);
|
playbackSection.classList.toggle('hidden', !shouldShowPlayback);
|
||||||
speedInput?.classList?.toggle('disabled', !shouldShowPlayback);
|
speedInput?.classList?.toggle('disabled', !shouldShowPlayback);
|
||||||
}
|
}
|
||||||
if (muteInput) {
|
if (volumeSection) {
|
||||||
muteInput.checked = !!asset.muted;
|
const showVolume = isAudioAsset(asset) || isVideoAsset(asset);
|
||||||
muteInput.disabled = !isVideoAsset(asset);
|
volumeSection.classList.toggle('hidden', !showVolume);
|
||||||
muteInput.parentElement?.classList.toggle('disabled', !isVideoAsset(asset));
|
const volumeControls = volumeSection.querySelectorAll('input');
|
||||||
|
volumeControls.forEach((control) => {
|
||||||
|
control.disabled = !showVolume;
|
||||||
|
control.classList.toggle('disabled', !showVolume);
|
||||||
|
});
|
||||||
|
if (showVolume && volumeInput) {
|
||||||
|
const sliderValue = volumeToSlider(asset.audioVolume ?? 1);
|
||||||
|
volumeInput.value = sliderValue;
|
||||||
|
setVolumeLabel(sliderValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (audioSection) {
|
if (audioSection) {
|
||||||
const showAudio = isAudioAsset(asset);
|
const showAudio = isAudioAsset(asset);
|
||||||
audioSection.classList.toggle('hidden', !showAudio);
|
audioSection.classList.toggle('hidden', !showAudio);
|
||||||
const audioInputs = [audioLoopInput, audioDelayInput, audioSpeedInput, audioPitchInput, audioVolumeInput];
|
const audioInputs = [audioLoopInput, audioDelayInput, audioSpeedInput, audioPitchInput];
|
||||||
audioInputs.forEach((input) => {
|
audioInputs.forEach((input) => {
|
||||||
if (!input) return;
|
if (!input) return;
|
||||||
input.disabled = !showAudio;
|
input.disabled = !showAudio;
|
||||||
@@ -1446,7 +1486,6 @@ function updateSelectedAssetControls(asset = getSelectedAsset()) {
|
|||||||
audioSpeedInput.value = Math.round(Math.max(0.25, asset.audioSpeed ?? 1) * 100);
|
audioSpeedInput.value = Math.round(Math.max(0.25, asset.audioSpeed ?? 1) * 100);
|
||||||
setAudioSpeedLabel(audioSpeedInput.value);
|
setAudioSpeedLabel(audioSpeedInput.value);
|
||||||
audioPitchInput.value = Math.round(Math.max(0.5, asset.audioPitch ?? 1) * 100);
|
audioPitchInput.value = Math.round(Math.max(0.5, asset.audioPitch ?? 1) * 100);
|
||||||
audioVolumeInput.value = Math.round(Math.max(0, Math.min(1, asset.audioVolume ?? 1)) * 100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1544,16 +1583,22 @@ function updatePlaybackFromInputs() {
|
|||||||
drawAndList();
|
drawAndList();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMuteFromInput() {
|
function updateVolumeFromInput() {
|
||||||
const asset = getSelectedAsset();
|
const asset = getSelectedAsset();
|
||||||
if (!asset || !isVideoAsset(asset)) return;
|
if (!asset || !(isVideoAsset(asset) || isAudioAsset(asset))) return;
|
||||||
asset.muted = !!muteInput?.checked;
|
const sliderValue = Math.max(0, Math.min(VOLUME_SLIDER_MAX, parseFloat(volumeInput?.value) || 100));
|
||||||
updateRenderState(asset);
|
const volumeValue = sliderToVolume(sliderValue);
|
||||||
persistTransform(asset);
|
setVolumeLabel(sliderValue);
|
||||||
|
asset.audioVolume = volumeValue;
|
||||||
const media = mediaCache.get(asset.id);
|
const media = mediaCache.get(asset.id);
|
||||||
if (media) {
|
if (media) {
|
||||||
applyMediaSettings(media, asset);
|
applyMediaSettings(media, asset);
|
||||||
}
|
}
|
||||||
|
if (isAudioAsset(asset)) {
|
||||||
|
const controller = ensureAudioController(asset);
|
||||||
|
applyAudioSettings(controller, asset);
|
||||||
|
}
|
||||||
|
persistTransform(asset);
|
||||||
drawAndList();
|
drawAndList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1566,7 +1611,6 @@ function updateAudioSettingsFromInputs() {
|
|||||||
setAudioSpeedLabel(nextAudioSpeedPercent);
|
setAudioSpeedLabel(nextAudioSpeedPercent);
|
||||||
asset.audioSpeed = Math.max(0.25, (nextAudioSpeedPercent / 100));
|
asset.audioSpeed = Math.max(0.25, (nextAudioSpeedPercent / 100));
|
||||||
asset.audioPitch = Math.max(0.5, (parseInt(audioPitchInput?.value || '100', 10) / 100));
|
asset.audioPitch = Math.max(0.5, (parseInt(audioPitchInput?.value || '100', 10) / 100));
|
||||||
asset.audioVolume = Math.max(0, Math.min(1, (parseInt(audioVolumeInput?.value || '100', 10) / 100)));
|
|
||||||
const controller = ensureAudioController(asset);
|
const controller = ensureAudioController(asset);
|
||||||
applyAudioSettings(controller, asset);
|
applyAudioSettings(controller, asset);
|
||||||
persistTransform(asset);
|
persistTransform(asset);
|
||||||
@@ -1876,7 +1920,6 @@ function persistTransform(asset, silent = false) {
|
|||||||
height: asset.height,
|
height: asset.height,
|
||||||
rotation: asset.rotation,
|
rotation: asset.rotation,
|
||||||
speed: asset.speed,
|
speed: asset.speed,
|
||||||
muted: asset.muted,
|
|
||||||
zIndex: asset.zIndex,
|
zIndex: asset.zIndex,
|
||||||
audioLoop: asset.audioLoop,
|
audioLoop: asset.audioLoop,
|
||||||
audioDelayMillis: asset.audioDelayMillis,
|
audioDelayMillis: asset.audioDelayMillis,
|
||||||
|
|||||||
@@ -387,8 +387,20 @@ function applyAudioElementSettings(element, asset) {
|
|||||||
const speed = Math.max(0.25, asset.audioSpeed || 1);
|
const speed = Math.max(0.25, asset.audioSpeed || 1);
|
||||||
const pitch = Math.max(0.5, asset.audioPitch || 1);
|
const pitch = Math.max(0.5, asset.audioPitch || 1);
|
||||||
element.playbackRate = speed * pitch;
|
element.playbackRate = speed * pitch;
|
||||||
const volume = Math.max(0, Math.min(1, asset.audioVolume ?? 1));
|
const volume = Math.max(0, Math.min(2, asset.audioVolume ?? 1));
|
||||||
element.volume = volume;
|
element.volume = Math.min(volume, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAssetVolume(asset) {
|
||||||
|
return Math.max(0, Math.min(2, asset?.audioVolume ?? 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMediaVolume(element, asset) {
|
||||||
|
if (!element) return 1;
|
||||||
|
const volume = getAssetVolume(asset);
|
||||||
|
element.muted = volume === 0;
|
||||||
|
element.volume = Math.min(volume, 1);
|
||||||
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAudioEnded(assetId) {
|
function handleAudioEnded(assetId) {
|
||||||
@@ -510,7 +522,7 @@ function ensureMedia(asset) {
|
|||||||
element.crossOrigin = 'anonymous';
|
element.crossOrigin = 'anonymous';
|
||||||
if (isVideoElement(element)) {
|
if (isVideoElement(element)) {
|
||||||
element.loop = true;
|
element.loop = true;
|
||||||
element.muted = asset.muted ?? true;
|
applyMediaVolume(element, asset);
|
||||||
element.playsInline = true;
|
element.playsInline = true;
|
||||||
element.autoplay = true;
|
element.autoplay = true;
|
||||||
element.onloadeddata = draw;
|
element.onloadeddata = draw;
|
||||||
@@ -618,7 +630,7 @@ function applyVideoSource(element, objectUrl, asset) {
|
|||||||
if (playback === 0) {
|
if (playback === 0) {
|
||||||
element.pause();
|
element.pause();
|
||||||
} else {
|
} else {
|
||||||
element.play().catch(() => {});
|
element.play().catch(() => queueAudioForUnlock({ element }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,25 +682,16 @@ function applyMediaSettings(element, asset) {
|
|||||||
}
|
}
|
||||||
const nextSpeed = asset.speed ?? 1;
|
const nextSpeed = asset.speed ?? 1;
|
||||||
const effectiveSpeed = Math.max(nextSpeed, 0.01);
|
const effectiveSpeed = Math.max(nextSpeed, 0.01);
|
||||||
const wasMuted = element.muted;
|
|
||||||
if (element.playbackRate !== effectiveSpeed) {
|
if (element.playbackRate !== effectiveSpeed) {
|
||||||
element.playbackRate = effectiveSpeed;
|
element.playbackRate = effectiveSpeed;
|
||||||
}
|
}
|
||||||
const shouldMute = asset.muted ?? true;
|
applyMediaVolume(element, asset);
|
||||||
if (element.muted !== shouldMute) {
|
|
||||||
element.muted = shouldMute;
|
|
||||||
}
|
|
||||||
if (nextSpeed === 0) {
|
if (nextSpeed === 0) {
|
||||||
element.pause();
|
element.pause();
|
||||||
} else {
|
} else {
|
||||||
const playPromise = element.play();
|
const playPromise = element.play();
|
||||||
if (playPromise?.catch) {
|
if (playPromise?.catch) {
|
||||||
playPromise.catch(() => {
|
playPromise.catch(() => queueAudioForUnlock({ element }));
|
||||||
if (!shouldMute && wasMuted) {
|
|
||||||
element.muted = true;
|
|
||||||
element.play().catch(() => {});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,9 @@
|
|||||||
<iframe th:src="${'https://player.twitch.tv/?channel=' + broadcaster + '&parent=localhost'}" allowfullscreen></iframe>
|
<iframe th:src="${'https://player.twitch.tv/?channel=' + broadcaster + '&parent=localhost'}" allowfullscreen></iframe>
|
||||||
<canvas id="admin-canvas"></canvas>
|
<canvas id="admin-canvas"></canvas>
|
||||||
</section>
|
</section>
|
||||||
<section class="controls assets-panel">
|
<section class="controls-full panel">
|
||||||
<div class="controls-full panel">
|
<h3>Overlay assets</h3>
|
||||||
<h3>Overlay assets</h3>
|
<p>Upload overlay visuals and adjust them inline.</p>
|
||||||
<p>Upload overlay visuals and adjust them inline.</p>
|
|
||||||
<div class="asset-management">
|
<div class="asset-management">
|
||||||
<div class="asset-column">
|
<div class="asset-column">
|
||||||
<div class="upload-row">
|
<div class="upload-row">
|
||||||
@@ -105,7 +104,6 @@
|
|||||||
<div class="panel-section" id="playback-section">
|
<div class="panel-section" id="playback-section">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h5>Playback</h5>
|
<h5>Playback</h5>
|
||||||
<p class="field-note">Video-only controls.</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="stacked-field">
|
<div class="stacked-field">
|
||||||
<div class="label-row">
|
<div class="label-row">
|
||||||
@@ -115,14 +113,19 @@
|
|||||||
<input id="asset-speed" class="range-input" type="range" min="0" max="1000" step="10" value="100" />
|
<input id="asset-speed" class="range-input" type="range" min="0" max="1000" step="10" value="100" />
|
||||||
<div class="range-meta"><span>0%</span><span>1000%</span></div>
|
<div class="range-meta"><span>0%</span><span>1000%</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-grid condensed split-row">
|
</div>
|
||||||
<label class="checkbox-inline toggle inline-toggle">
|
|
||||||
<input id="asset-muted" type="checkbox" />
|
<div class="panel-section" id="volume-section">
|
||||||
<span class="toggle-track" aria-hidden="true">
|
<div class="section-header">
|
||||||
<span class="toggle-thumb"></span>
|
<h5>Volume</h5>
|
||||||
</span>
|
</div>
|
||||||
<span class="toggle-label">Mute video</span>
|
<div class="stacked-field">
|
||||||
</label>
|
<div class="label-row">
|
||||||
|
<span>Playback volume</span>
|
||||||
|
<span class="value-hint" id="asset-volume-label">100%</span>
|
||||||
|
</div>
|
||||||
|
<input id="asset-volume" class="range-input" type="range" min="0" max="200" step="1" value="100" />
|
||||||
|
<div class="range-meta"><span>0%</span><span>200%</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -157,10 +160,7 @@
|
|||||||
Pitch (%)
|
Pitch (%)
|
||||||
<input id="asset-audio-pitch" class="range-input" type="range" min="50" max="200" step="5" value="100" />
|
<input id="asset-audio-pitch" class="range-input" type="range" min="50" max="200" step="5" value="100" />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<div></div>
|
||||||
Volume (%)
|
|
||||||
<input id="asset-audio-volume" class="range-input" type="range" min="0" max="100" step="1" value="100" />
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -168,7 +168,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user