cleanup and fixes
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m15s
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m15s
This commit is contained in:
14
app.py
14
app.py
@@ -114,6 +114,15 @@ def process_video():
|
|||||||
# Build filter complex for crop and scale
|
# Build filter complex for crop and scale
|
||||||
filters = []
|
filters = []
|
||||||
|
|
||||||
|
# Add rotation filter if specified
|
||||||
|
rotation = data.get('rotation', 0)
|
||||||
|
if rotation == 90:
|
||||||
|
filters.append('transpose=1')
|
||||||
|
elif rotation == 180:
|
||||||
|
filters.append('transpose=2,transpose=2')
|
||||||
|
elif rotation == 270:
|
||||||
|
filters.append('transpose=2')
|
||||||
|
|
||||||
# Add crop filter if specified
|
# Add crop filter if specified
|
||||||
crop = data.get('crop')
|
crop = data.get('crop')
|
||||||
if crop:
|
if crop:
|
||||||
@@ -136,6 +145,11 @@ def process_video():
|
|||||||
if filters:
|
if filters:
|
||||||
cmd.extend(['-vf', ','.join(filters)])
|
cmd.extend(['-vf', ','.join(filters)])
|
||||||
|
|
||||||
|
# Handle audio
|
||||||
|
mute_audio = data.get('mute_audio', False)
|
||||||
|
if mute_audio:
|
||||||
|
cmd.extend(['-an']) # Remove audio
|
||||||
|
|
||||||
# Output settings for H.264 MP4
|
# Output settings for H.264 MP4
|
||||||
cmd.extend([
|
cmd.extend([
|
||||||
'-c:v', 'libx264',
|
'-c:v', 'libx264',
|
||||||
|
|||||||
@@ -123,8 +123,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.video-preview {
|
.video-preview {
|
||||||
margin: 20px 0;
|
margin: 20px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
@@ -217,6 +223,41 @@
|
|||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 15px 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-action-btn {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 150px;
|
||||||
|
padding: 10px 16px;
|
||||||
|
background: white;
|
||||||
|
color: #667eea;
|
||||||
|
border: 2px solid #667eea;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.3s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-action-btn:hover {
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-action-btn.active {
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.current-time-display {
|
.current-time-display {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
@@ -462,17 +503,58 @@
|
|||||||
<h2>2. Edit Video</h2>
|
<h2>2. Edit Video</h2>
|
||||||
|
|
||||||
<div class="video-preview">
|
<div class="video-preview">
|
||||||
<video id="video-preview" controls></video>
|
<div class="video-wrapper">
|
||||||
<canvas id="crop-canvas" class="crop-canvas"></canvas>
|
<video id="video-preview" controls></video>
|
||||||
</div>
|
<canvas id="crop-canvas" class="crop-canvas"></canvas>
|
||||||
|
</div>
|
||||||
<div class="video-controls">
|
|
||||||
<button class="crop-mode-btn" id="crop-mode-btn">🎯 Click to Draw Crop Area</button>
|
|
||||||
<p class="crop-hint" id="crop-hint" style="display: none;">Click and drag on the video to select crop area</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="video-info" id="video-info"></div>
|
<div class="video-info" id="video-info"></div>
|
||||||
|
|
||||||
|
<!-- Quick Actions -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>⚡ Quick Actions</label>
|
||||||
|
<div class="quick-actions">
|
||||||
|
<button class="quick-action-btn" id="mute-audio-btn" title="Remove audio track from video">
|
||||||
|
🔇 Mute Audio
|
||||||
|
</button>
|
||||||
|
<button class="quick-action-btn" id="rotate-btn" title="Rotate video 90° clockwise">
|
||||||
|
🔄 Rotate 90°
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Crop Controls -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>✂️ Crop Video</label>
|
||||||
|
<div class="video-controls">
|
||||||
|
<button class="crop-mode-btn" id="crop-mode-btn">🎯 Click to Draw Crop Area</button>
|
||||||
|
<p class="crop-hint" id="crop-hint" style="display: none;">Click and drag on the video to select crop area</p>
|
||||||
|
</div>
|
||||||
|
<div class="crop-controls">
|
||||||
|
<div class="form-row">
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: normal;">X Position</label>
|
||||||
|
<input type="number" id="crop-x" value="0" min="0">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: normal;">Y Position</label>
|
||||||
|
<input type="number" id="crop-y" value="0" min="0">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row" style="margin-top: 10px;">
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: normal;">Crop Width</label>
|
||||||
|
<input type="number" id="crop-width" placeholder="Full width" min="0">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: normal;">Crop Height</label>
|
||||||
|
<input type="number" id="crop-height" placeholder="Full height" min="0">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Trim Controls -->
|
<!-- Trim Controls -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>⏱️ Trim Video</label>
|
<label>⏱️ Trim Video</label>
|
||||||
@@ -523,33 +605,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Crop Controls -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label>✂️ Crop Video (optional)</label>
|
|
||||||
<div class="crop-controls">
|
|
||||||
<div class="form-row">
|
|
||||||
<div>
|
|
||||||
<label style="font-weight: normal;">X Position</label>
|
|
||||||
<input type="number" id="crop-x" value="0" min="0">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label style="font-weight: normal;">Y Position</label>
|
|
||||||
<input type="number" id="crop-y" value="0" min="0">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row" style="margin-top: 10px;">
|
|
||||||
<div>
|
|
||||||
<label style="font-weight: normal;">Crop Width</label>
|
|
||||||
<input type="number" id="crop-width" placeholder="Full width" min="0">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label style="font-weight: normal;">Crop Height</label>
|
|
||||||
<input type="number" id="crop-height" placeholder="Full height" min="0">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button class="btn" id="process-btn">🎬 Process Video</button>
|
<button class="btn" id="process-btn">🎬 Process Video</button>
|
||||||
<button class="btn btn-secondary" id="reset-btn">🔄 Start Over</button>
|
<button class="btn btn-secondary" id="reset-btn">🔄 Start Over</button>
|
||||||
@@ -579,6 +634,8 @@
|
|||||||
let cropStartY = 0;
|
let cropStartY = 0;
|
||||||
let cropRect = null;
|
let cropRect = null;
|
||||||
let scalePercentage = 100;
|
let scalePercentage = 100;
|
||||||
|
let rotationDegrees = 0;
|
||||||
|
let muteAudio = false;
|
||||||
|
|
||||||
// Upload area handling
|
// Upload area handling
|
||||||
const uploadArea = document.getElementById('upload-area');
|
const uploadArea = document.getElementById('upload-area');
|
||||||
@@ -808,6 +865,29 @@
|
|||||||
currentTimeDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}.${milliseconds}`;
|
currentTimeDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}.${milliseconds}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Quick actions
|
||||||
|
document.getElementById('mute-audio-btn').addEventListener('click', function() {
|
||||||
|
muteAudio = !muteAudio;
|
||||||
|
if (muteAudio) {
|
||||||
|
this.classList.add('active');
|
||||||
|
this.textContent = '🔇 Audio Muted';
|
||||||
|
} else {
|
||||||
|
this.classList.remove('active');
|
||||||
|
this.textContent = '🔇 Mute Audio';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('rotate-btn').addEventListener('click', function() {
|
||||||
|
rotationDegrees = (rotationDegrees + 90) % 360;
|
||||||
|
if (rotationDegrees === 0) {
|
||||||
|
this.classList.remove('active');
|
||||||
|
this.textContent = '🔄 Rotate 90°';
|
||||||
|
} else {
|
||||||
|
this.classList.add('active');
|
||||||
|
this.textContent = `🔄 Rotated ${rotationDegrees}°`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Set start time button
|
// Set start time button
|
||||||
setStartBtn.addEventListener('click', () => {
|
setStartBtn.addEventListener('click', () => {
|
||||||
const currentTime = videoPreview.currentTime;
|
const currentTime = videoPreview.currentTime;
|
||||||
@@ -883,7 +963,9 @@
|
|||||||
file_id: currentFileId,
|
file_id: currentFileId,
|
||||||
start_time: startTime,
|
start_time: startTime,
|
||||||
end_time: endTime,
|
end_time: endTime,
|
||||||
scale_percentage: scalePercentage
|
scale_percentage: scalePercentage,
|
||||||
|
rotation: rotationDegrees,
|
||||||
|
mute_audio: muteAudio
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cropWidth > 0 && cropHeight > 0) {
|
if (cropWidth > 0 && cropHeight > 0) {
|
||||||
@@ -944,6 +1026,8 @@
|
|||||||
videoInfo = null;
|
videoInfo = null;
|
||||||
cropMode = false;
|
cropMode = false;
|
||||||
cropRect = null;
|
cropRect = null;
|
||||||
|
rotationDegrees = 0;
|
||||||
|
muteAudio = false;
|
||||||
|
|
||||||
videoPreview.src = '';
|
videoPreview.src = '';
|
||||||
videoInput.value = '';
|
videoInput.value = '';
|
||||||
@@ -952,6 +1036,12 @@
|
|||||||
cropModeBtn.classList.remove('active');
|
cropModeBtn.classList.remove('active');
|
||||||
cropModeBtn.textContent = '🎯 Click to Draw Crop Area';
|
cropModeBtn.textContent = '🎯 Click to Draw Crop Area';
|
||||||
cropHint.style.display = 'none';
|
cropHint.style.display = 'none';
|
||||||
|
|
||||||
|
// Reset quick actions
|
||||||
|
document.getElementById('mute-audio-btn').classList.remove('active');
|
||||||
|
document.getElementById('mute-audio-btn').textContent = '🔇 Mute Audio';
|
||||||
|
document.getElementById('rotate-btn').classList.remove('active');
|
||||||
|
document.getElementById('rotate-btn').textContent = '🔄 Rotate 90°';
|
||||||
|
|
||||||
document.getElementById('upload-section').classList.remove('hidden');
|
document.getElementById('upload-section').classList.remove('hidden');
|
||||||
document.getElementById('edit-section').classList.add('hidden');
|
document.getElementById('edit-section').classList.add('hidden');
|
||||||
|
|||||||
Reference in New Issue
Block a user