videoconverter-worker 1.0.3__py3-none-any.whl → 1.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/METADATA +1 -1
- videoconverter_worker-1.0.4.dist-info/RECORD +10 -0
- worker.py +64 -27
- videoconverter_worker-1.0.3.dist-info/RECORD +0 -10
- {videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/WHEEL +0 -0
- {videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/entry_points.txt +0 -0
- {videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ffmpeg_runner.py,sha256=2sYugXkKp-NKj3ahxbwbhAo4G49FDu-0oze-cdJvcY0,12218
|
|
2
|
+
metadata.py,sha256=32zQn7jJ6XTHhunwTn5Xv0qmpjHnap_pkPxY0XI8MBs,3116
|
|
3
|
+
schema.py,sha256=3ILdGl5qSQOSvKfiKWcnaxdyHwV4rDvGnRZIparVp3o,4361
|
|
4
|
+
task_queue.py,sha256=sYQelPRuTbP9g_sPs69xOR3n5SIxGBFxY4EI5ueQrQs,11822
|
|
5
|
+
worker.py,sha256=7sp3Wn6qf2xFtsQpJZEhUXrvb6m8uSmCNbcE4ssapQI,21117
|
|
6
|
+
videoconverter_worker-1.0.4.dist-info/METADATA,sha256=0bWYbcY5_HuBpnwNILPdmRb5LBeNPAiP_rQRfrf4tDM,5139
|
|
7
|
+
videoconverter_worker-1.0.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
videoconverter_worker-1.0.4.dist-info/entry_points.txt,sha256=qedJjjix02n9Hz8adBioDIpGHghm8S3fQZdFwM5LV1A,83
|
|
9
|
+
videoconverter_worker-1.0.4.dist-info/top_level.txt,sha256=iamWyiqUZ4X0_2UZx6GEk9gsPmiI9qhse_15HqtzUj8,48
|
|
10
|
+
videoconverter_worker-1.0.4.dist-info/RECORD,,
|
worker.py
CHANGED
|
@@ -8,6 +8,7 @@ Python Worker:从 queue 目录读取任务并执行切分/去字幕/合成,
|
|
|
8
8
|
import argparse
|
|
9
9
|
import logging
|
|
10
10
|
import sys
|
|
11
|
+
import threading
|
|
11
12
|
import time
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
|
|
@@ -30,6 +31,19 @@ logging.basicConfig(
|
|
|
30
31
|
logger = logging.getLogger("worker")
|
|
31
32
|
|
|
32
33
|
|
|
34
|
+
def _desub_spinner(stop_event: threading.Event) -> None:
|
|
35
|
+
"""去字幕阶段同一行跑马灯,避免用户以为死机。"""
|
|
36
|
+
i = 0
|
|
37
|
+
while not stop_event.wait(0.25):
|
|
38
|
+
dots = "." * ((i % 3) + 1)
|
|
39
|
+
try:
|
|
40
|
+
sys.stderr.write("\r [INFO] worker: 去字幕中 " + dots + " ")
|
|
41
|
+
sys.stderr.flush()
|
|
42
|
+
except (OSError, UnicodeEncodeError):
|
|
43
|
+
break
|
|
44
|
+
i += 1
|
|
45
|
+
|
|
46
|
+
|
|
33
47
|
def process_split_task(store: QueueStore, task: dict) -> None:
|
|
34
48
|
task_id = task["task_id"]
|
|
35
49
|
input_file = task["input_file"]
|
|
@@ -167,7 +181,7 @@ def _format_duration(sec: float) -> str:
|
|
|
167
181
|
|
|
168
182
|
|
|
169
183
|
def _log_split_to_merge_duration(data: dict, task_id: str, store: QueueStore) -> None:
|
|
170
|
-
"""若 metadata 含 splitStartedAt
|
|
184
|
+
"""若 metadata 含 splitStartedAt,则计算并输出从切分到合成结束的总时长与产能预估。"""
|
|
171
185
|
s = data.get("splitStartedAt") or ""
|
|
172
186
|
if not s:
|
|
173
187
|
return
|
|
@@ -177,10 +191,16 @@ def _log_split_to_merge_duration(data: dict, task_id: str, store: QueueStore) ->
|
|
|
177
191
|
if ts.tzinfo is None:
|
|
178
192
|
ts = ts.replace(tzinfo=timezone.utc)
|
|
179
193
|
duration_sec = (datetime.now(timezone.utc) - ts).total_seconds()
|
|
180
|
-
if duration_sec
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
194
|
+
if duration_sec < 0:
|
|
195
|
+
return
|
|
196
|
+
msg = f"从切分到合成结束总时长: {_format_duration(duration_sec)}"
|
|
197
|
+
processed = get_processed_chunks(data)
|
|
198
|
+
if processed and duration_sec > 0:
|
|
199
|
+
src_duration_sec = processed[-1]["endTime"] - processed[0]["startTime"]
|
|
200
|
+
capacity = (src_duration_sec / 3600.0) / (duration_sec / 3600.0)
|
|
201
|
+
msg += f",产能预估: 约 {capacity:.2f} 原视频小时/小时"
|
|
202
|
+
logger.info("videoId=%s %s", data.get("videoId", ""), msg)
|
|
203
|
+
store.add_log(task_id, "INFO", msg)
|
|
184
204
|
except Exception:
|
|
185
205
|
pass
|
|
186
206
|
|
|
@@ -332,27 +352,39 @@ def run_simple_compose(
|
|
|
332
352
|
chunk_list = [c for c in (metadata.get("chunks") or []) if c.get("originalPath")]
|
|
333
353
|
logger.info("切分完成: %d 块,开始去字幕", len(chunk_list))
|
|
334
354
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
355
|
+
stop_spinner = threading.Event()
|
|
356
|
+
spinner = threading.Thread(target=_desub_spinner, args=(stop_spinner,), daemon=True)
|
|
357
|
+
spinner.start()
|
|
358
|
+
try:
|
|
359
|
+
for ch in chunk_list:
|
|
360
|
+
rel = ch.get("originalPath", "")
|
|
361
|
+
if not rel:
|
|
362
|
+
continue
|
|
363
|
+
chunk_path = Path(output_dir) / rel
|
|
364
|
+
if not chunk_path.exists():
|
|
365
|
+
continue
|
|
366
|
+
chunk_id = ch.get("chunkId", "")
|
|
367
|
+
out_dir_v = Path(output_dir) / video_id
|
|
368
|
+
out_dir_v.mkdir(parents=True, exist_ok=True)
|
|
369
|
+
output_file = out_dir_v / (Path(chunk_path).stem + "_desub.mp4")
|
|
370
|
+
cfg = dict(config)
|
|
371
|
+
cfg["inputPath"] = str(chunk_path)
|
|
372
|
+
cfg["outputPath"] = str(output_file)
|
|
373
|
+
cfg["startTime"] = 0
|
|
374
|
+
cfg["endTime"] = 0
|
|
375
|
+
cfg["forceKeyframeAtStart"] = True
|
|
376
|
+
run_desubtitle(cfg, str(chunk_path), str(output_file))
|
|
377
|
+
meta_path = Path(output_dir) / video_id / "metadata.json"
|
|
378
|
+
if meta_path.exists():
|
|
379
|
+
update_chunk_processed(str(meta_path), chunk_id, str(output_file))
|
|
380
|
+
finally:
|
|
381
|
+
stop_spinner.set()
|
|
382
|
+
spinner.join(timeout=1.0)
|
|
383
|
+
try:
|
|
384
|
+
sys.stderr.write("\n")
|
|
385
|
+
sys.stderr.flush()
|
|
386
|
+
except (OSError, UnicodeEncodeError):
|
|
387
|
+
pass
|
|
356
388
|
|
|
357
389
|
data = load_metadata(str(Path(output_dir) / video_id / "metadata.json"))
|
|
358
390
|
processed = get_processed_chunks(data)
|
|
@@ -363,7 +395,12 @@ def run_simple_compose(
|
|
|
363
395
|
out_file = Path(output_dir) / f"{video_id}_merged.mp4"
|
|
364
396
|
merge_chunks(data, start_t, end_t, str(out_file))
|
|
365
397
|
elapsed = time.time() - t0
|
|
366
|
-
|
|
398
|
+
src_duration_sec = end_sec - start_sec
|
|
399
|
+
capacity = (src_duration_sec / 3600.0) / (elapsed / 3600.0) if elapsed > 0 else 0
|
|
400
|
+
logger.info(
|
|
401
|
+
"简易模式完成: %s,从切分到合成结束总时长: %s,产能预估: 约 %.2f 原视频小时/小时",
|
|
402
|
+
out_file, _format_duration(elapsed), capacity,
|
|
403
|
+
)
|
|
367
404
|
return str(out_file)
|
|
368
405
|
|
|
369
406
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
ffmpeg_runner.py,sha256=2sYugXkKp-NKj3ahxbwbhAo4G49FDu-0oze-cdJvcY0,12218
|
|
2
|
-
metadata.py,sha256=32zQn7jJ6XTHhunwTn5Xv0qmpjHnap_pkPxY0XI8MBs,3116
|
|
3
|
-
schema.py,sha256=3ILdGl5qSQOSvKfiKWcnaxdyHwV4rDvGnRZIparVp3o,4361
|
|
4
|
-
task_queue.py,sha256=sYQelPRuTbP9g_sPs69xOR3n5SIxGBFxY4EI5ueQrQs,11822
|
|
5
|
-
worker.py,sha256=2t7mFIV2i_qJJxN55wNrU6ZmPbG4wT9YEjzECi04BR8,19664
|
|
6
|
-
videoconverter_worker-1.0.3.dist-info/METADATA,sha256=8qyb44UnKGgChp4v3F8SuHkL4EpK6IepBhdMLJ7UWTQ,5139
|
|
7
|
-
videoconverter_worker-1.0.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
-
videoconverter_worker-1.0.3.dist-info/entry_points.txt,sha256=qedJjjix02n9Hz8adBioDIpGHghm8S3fQZdFwM5LV1A,83
|
|
9
|
-
videoconverter_worker-1.0.3.dist-info/top_level.txt,sha256=iamWyiqUZ4X0_2UZx6GEk9gsPmiI9qhse_15HqtzUj8,48
|
|
10
|
-
videoconverter_worker-1.0.3.dist-info/RECORD,,
|
|
File without changes
|
{videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{videoconverter_worker-1.0.3.dist-info → videoconverter_worker-1.0.4.dist-info}/top_level.txt
RENAMED
|
File without changes
|