Spaces:
Sleeping
Sleeping
Commit
·
d0ff525
1
Parent(s):
d31b48e
debug 2 patch
Browse files- app/services/encoder_service.py +30 -12
app/services/encoder_service.py
CHANGED
|
@@ -5,15 +5,24 @@ from pathlib import Path
|
|
| 5 |
import logging
|
| 6 |
import json
|
| 7 |
from datetime import datetime
|
| 8 |
-
import re
|
| 9 |
import threading
|
| 10 |
import signal
|
| 11 |
import time
|
|
|
|
| 12 |
|
| 13 |
# Configure logging
|
| 14 |
logging.basicConfig(level=logging.INFO)
|
| 15 |
logger = logging.getLogger(__name__)
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
class EncoderService:
|
| 18 |
def __init__(self):
|
| 19 |
self.jobs = {}
|
|
@@ -139,7 +148,7 @@ class EncoderService:
|
|
| 139 |
})
|
| 140 |
output_file = output_dir / f"{output_name}_{quality}.mp4"
|
| 141 |
|
| 142 |
-
# FFmpeg command
|
| 143 |
cmd = [
|
| 144 |
'ffmpeg', '-y',
|
| 145 |
'-i', str(input_file),
|
|
@@ -173,23 +182,32 @@ class EncoderService:
|
|
| 173 |
)
|
| 174 |
self.active_processes[job_id] = process
|
| 175 |
|
| 176 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
last_output_time = time.time()
|
| 178 |
while True:
|
| 179 |
-
|
| 180 |
-
|
|
|
|
| 181 |
last_output_time = time.time()
|
| 182 |
-
|
| 183 |
-
if
|
| 184 |
-
quality_progress = ((completed_steps +
|
| 185 |
self.jobs[job_id]['progress'] = quality_progress
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
|
|
|
| 190 |
if process.poll() is not None:
|
| 191 |
break
|
| 192 |
|
|
|
|
|
|
|
| 193 |
if process.returncode == 0:
|
| 194 |
logger.info(f"Encoding successful for quality {quality} on attempt {attempts+1} for job {job_id}")
|
| 195 |
outputs.append({
|
|
|
|
| 5 |
import logging
|
| 6 |
import json
|
| 7 |
from datetime import datetime
|
|
|
|
| 8 |
import threading
|
| 9 |
import signal
|
| 10 |
import time
|
| 11 |
+
import queue
|
| 12 |
|
| 13 |
# Configure logging
|
| 14 |
logging.basicConfig(level=logging.INFO)
|
| 15 |
logger = logging.getLogger(__name__)
|
| 16 |
|
| 17 |
+
def _read_pipe(pipe, q):
|
| 18 |
+
"""Read lines from a pipe and put them into a queue."""
|
| 19 |
+
try:
|
| 20 |
+
with pipe:
|
| 21 |
+
for line in iter(pipe.readline, ''):
|
| 22 |
+
q.put(line)
|
| 23 |
+
except Exception as e:
|
| 24 |
+
logger.error(f"Error reading pipe: {str(e)}")
|
| 25 |
+
|
| 26 |
class EncoderService:
|
| 27 |
def __init__(self):
|
| 28 |
self.jobs = {}
|
|
|
|
| 148 |
})
|
| 149 |
output_file = output_dir / f"{output_name}_{quality}.mp4"
|
| 150 |
|
| 151 |
+
# Build the FFmpeg command
|
| 152 |
cmd = [
|
| 153 |
'ffmpeg', '-y',
|
| 154 |
'-i', str(input_file),
|
|
|
|
| 182 |
)
|
| 183 |
self.active_processes[job_id] = process
|
| 184 |
|
| 185 |
+
# Use a queue and separate thread to read stdout
|
| 186 |
+
q = queue.Queue()
|
| 187 |
+
reader_thread = threading.Thread(target=_read_pipe, args=(process.stdout, q))
|
| 188 |
+
reader_thread.daemon = True
|
| 189 |
+
reader_thread.start()
|
| 190 |
+
|
| 191 |
last_output_time = time.time()
|
| 192 |
while True:
|
| 193 |
+
try:
|
| 194 |
+
# Wait up to 5 seconds for a line
|
| 195 |
+
line = q.get(timeout=5)
|
| 196 |
last_output_time = time.time()
|
| 197 |
+
prog = self._parse_ffmpeg_progress(line, duration)
|
| 198 |
+
if prog is not None:
|
| 199 |
+
quality_progress = ((completed_steps + prog / 100) / total_steps) * 100
|
| 200 |
self.jobs[job_id]['progress'] = quality_progress
|
| 201 |
+
except queue.Empty:
|
| 202 |
+
# If no output in 5 seconds, check if process is still alive
|
| 203 |
+
if time.time() - last_output_time > 30:
|
| 204 |
+
logger.warning(f"No ffmpeg output for 30 seconds on quality {quality}, attempt {attempts+1} for job {job_id}")
|
| 205 |
+
break
|
| 206 |
if process.poll() is not None:
|
| 207 |
break
|
| 208 |
|
| 209 |
+
reader_thread.join(timeout=5)
|
| 210 |
+
# Check if process completed successfully
|
| 211 |
if process.returncode == 0:
|
| 212 |
logger.info(f"Encoding successful for quality {quality} on attempt {attempts+1} for job {job_id}")
|
| 213 |
outputs.append({
|