add compression slider
This commit is contained in:
7
app.py
7
app.py
@@ -157,11 +157,16 @@ def process_video():
|
|||||||
if mute_audio:
|
if mute_audio:
|
||||||
cmd.extend(['-an']) # Remove audio
|
cmd.extend(['-an']) # Remove audio
|
||||||
|
|
||||||
|
# Get quality (CRF value)
|
||||||
|
quality = data.get('quality', 23)
|
||||||
|
# Ensure quality is within valid range (18-32)
|
||||||
|
quality = max(18, min(32, int(quality)))
|
||||||
|
|
||||||
# Output settings for H.264 MP4
|
# Output settings for H.264 MP4
|
||||||
cmd.extend([
|
cmd.extend([
|
||||||
'-c:v', 'libx264',
|
'-c:v', 'libx264',
|
||||||
'-preset', 'medium',
|
'-preset', 'medium',
|
||||||
'-crf', '23',
|
'-crf', str(quality),
|
||||||
'-c:a', 'aac',
|
'-c:a', 'aac',
|
||||||
'-b:a', '128k',
|
'-b:a', '128k',
|
||||||
'-movflags', '+faststart',
|
'-movflags', '+faststart',
|
||||||
|
|||||||
@@ -588,6 +588,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Compression Quality Controls -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>💾 Compression Quality</label>
|
||||||
|
<div class="scale-slider-container">
|
||||||
|
<div class="scale-display">
|
||||||
|
<span>Quality: <span class="scale-value" id="quality-value-display">High</span></span>
|
||||||
|
<span style="color: #6c757d;">CRF: <strong id="crf-value-display">23</strong></span>
|
||||||
|
</div>
|
||||||
|
<input type="range" class="scale-slider" id="quality-slider" min="18" max="32" value="23" step="1">
|
||||||
|
<div class="resolution-preview">
|
||||||
|
<p style="margin: 0;">💡 <strong>Lower CRF</strong> = Better quality, larger file. <strong>Higher CRF</strong> = More compressed, smaller file.</p>
|
||||||
|
</div>
|
||||||
|
<div class="preset-resolutions" style="margin-top: 15px;">
|
||||||
|
<button class="preset-btn" data-quality="18">Best Quality</button>
|
||||||
|
<button class="preset-btn" data-quality="21">High</button>
|
||||||
|
<button class="preset-btn" data-quality="23">Balanced</button>
|
||||||
|
<button class="preset-btn" data-quality="26">Low</button>
|
||||||
|
<button class="preset-btn" data-quality="30">Smallest File</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Quick Actions -->
|
<!-- Quick Actions -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>⚡ Quick Actions</label>
|
<label>⚡ Quick Actions</label>
|
||||||
@@ -632,6 +654,7 @@
|
|||||||
let scalePercentage = 100;
|
let scalePercentage = 100;
|
||||||
let rotationDegrees = 0;
|
let rotationDegrees = 0;
|
||||||
let muteAudio = false;
|
let muteAudio = false;
|
||||||
|
let compressionQuality = 23;
|
||||||
|
|
||||||
// Upload area handling
|
// Upload area handling
|
||||||
const uploadArea = document.getElementById('upload-area');
|
const uploadArea = document.getElementById('upload-area');
|
||||||
@@ -935,6 +958,9 @@
|
|||||||
const scaleSlider = document.getElementById('scale-slider');
|
const scaleSlider = document.getElementById('scale-slider');
|
||||||
const scaleValueDisplay = document.getElementById('scale-value-display');
|
const scaleValueDisplay = document.getElementById('scale-value-display');
|
||||||
const outputResolution = document.getElementById('output-resolution');
|
const outputResolution = document.getElementById('output-resolution');
|
||||||
|
const qualitySlider = document.getElementById('quality-slider');
|
||||||
|
const qualityValueDisplay = document.getElementById('quality-value-display');
|
||||||
|
const crfValueDisplay = document.getElementById('crf-value-display');
|
||||||
|
|
||||||
function updateScaleDisplay() {
|
function updateScaleDisplay() {
|
||||||
scalePercentage = parseInt(scaleSlider.value);
|
scalePercentage = parseInt(scaleSlider.value);
|
||||||
@@ -953,14 +979,40 @@
|
|||||||
|
|
||||||
scaleSlider.addEventListener('input', updateScaleDisplay);
|
scaleSlider.addEventListener('input', updateScaleDisplay);
|
||||||
|
|
||||||
|
// Quality slider
|
||||||
|
function updateQualityDisplay() {
|
||||||
|
compressionQuality = parseInt(qualitySlider.value);
|
||||||
|
crfValueDisplay.textContent = compressionQuality;
|
||||||
|
|
||||||
|
// Update quality label
|
||||||
|
let qualityLabel = 'Balanced';
|
||||||
|
if (compressionQuality <= 19) qualityLabel = 'Best Quality';
|
||||||
|
else if (compressionQuality <= 22) qualityLabel = 'High';
|
||||||
|
else if (compressionQuality <= 25) qualityLabel = 'Balanced';
|
||||||
|
else if (compressionQuality <= 28) qualityLabel = 'Low';
|
||||||
|
else qualityLabel = 'Smallest File';
|
||||||
|
|
||||||
|
qualityValueDisplay.textContent = qualityLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
qualitySlider.addEventListener('input', updateQualityDisplay);
|
||||||
|
updateQualityDisplay();
|
||||||
|
|
||||||
// Scale presets
|
// Scale presets
|
||||||
document.querySelectorAll('.preset-btn').forEach(btn => {
|
document.querySelectorAll('.preset-btn').forEach(btn => {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
const scale = btn.dataset.scale;
|
const scale = btn.dataset.scale;
|
||||||
|
const quality = btn.dataset.quality;
|
||||||
|
|
||||||
if (scale) {
|
if (scale) {
|
||||||
scaleSlider.value = scale;
|
scaleSlider.value = scale;
|
||||||
updateScaleDisplay();
|
updateScaleDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (quality) {
|
||||||
|
qualitySlider.value = quality;
|
||||||
|
updateQualityDisplay();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -984,7 +1036,8 @@
|
|||||||
end_time: endTime,
|
end_time: endTime,
|
||||||
scale_percentage: scalePercentage,
|
scale_percentage: scalePercentage,
|
||||||
rotation: rotationDegrees,
|
rotation: rotationDegrees,
|
||||||
mute_audio: muteAudio
|
mute_audio: muteAudio,
|
||||||
|
quality: compressionQuality
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cropWidth > 0 && cropHeight > 0) {
|
if (cropWidth > 0 && cropHeight > 0) {
|
||||||
@@ -1048,8 +1101,9 @@
|
|||||||
rotationDegrees = 0;
|
rotationDegrees = 0;
|
||||||
muteAudio = false;
|
muteAudio = false;
|
||||||
scalePercentage = 100;
|
scalePercentage = 100;
|
||||||
|
compressionQuality = 23;
|
||||||
|
|
||||||
videoPreview.src = '';
|
videoPreview.src = '';;
|
||||||
videoInput.value = '';
|
videoInput.value = '';
|
||||||
clearCropCanvas();
|
clearCropCanvas();
|
||||||
cropCanvas.classList.remove('active');
|
cropCanvas.classList.remove('active');
|
||||||
@@ -1065,6 +1119,8 @@
|
|||||||
document.getElementById('scale-value-display').textContent = '100%';
|
document.getElementById('scale-value-display').textContent = '100%';
|
||||||
document.getElementById('output-resolution').textContent = '--';
|
document.getElementById('output-resolution').textContent = '--';
|
||||||
document.getElementById('current-time-display').textContent = '0:00';
|
document.getElementById('current-time-display').textContent = '0:00';
|
||||||
|
document.getElementById('quality-slider').value = '23';
|
||||||
|
updateQualityDisplay();
|
||||||
|
|
||||||
// Reset quick actions
|
// Reset quick actions
|
||||||
document.getElementById('mute-audio-btn').classList.remove('active');
|
document.getElementById('mute-audio-btn').classList.remove('active');
|
||||||
|
|||||||
Reference in New Issue
Block a user