Compare commits
13 Commits
ad84469037
...
1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| d737177eab | |||
| 6420a02090 | |||
| 2be19ee02c | |||
| 98613a0002 | |||
| 501c45cad7 | |||
| 0fd0cda460 | |||
| dd4f9fc51c | |||
| 6288d77d46 | |||
|
|
8f5934d576 | ||
|
|
a941eb6b98 | ||
|
|
503f2817d2 | ||
|
|
85b5717595 | ||
|
|
9c626a1e4a |
@@ -6,9 +6,35 @@ from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip
|
|||||||
from moviepy import TextClip
|
from moviepy import TextClip
|
||||||
|
|
||||||
font = "./Montserrat.ttf"
|
font = "./Montserrat.ttf"
|
||||||
|
font_size = 70
|
||||||
|
video_codec = "libx264"
|
||||||
|
|
||||||
|
def auto_wrap_text(text, max_width):
|
||||||
|
if not text:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
words = text.split()
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
line = ""
|
||||||
|
for word in words:
|
||||||
|
test_line = f"{line} {word}".strip()
|
||||||
|
test_clip = TextClip(text=test_line, font=font, font_size=font_size, color='white', method='label')
|
||||||
|
|
||||||
|
if test_clip.w > max_width and line != "":
|
||||||
|
lines.append(line)
|
||||||
|
line = word
|
||||||
|
else:
|
||||||
|
line = test_line
|
||||||
|
|
||||||
|
test_clip.close()
|
||||||
|
|
||||||
|
lines.append(line)
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
def cut_video_new_clip(input_path: str, start: float, end: float, output_path: str):
|
def cut_video_new_clip(input_path: str, start: float, end: float, output_path: str):
|
||||||
video_codec = "libx264"
|
|
||||||
|
|
||||||
with VideoFileClip(input_path) as clip:
|
with VideoFileClip(input_path) as clip:
|
||||||
segment = clip.subclipped(start, end)
|
segment = clip.subclipped(start, end)
|
||||||
@@ -19,6 +45,7 @@ def cut_video_new_clip(input_path: str, start: float, end: float, output_path: s
|
|||||||
codec=video_codec,
|
codec=video_codec,
|
||||||
remove_temp=True,
|
remove_temp=True,
|
||||||
fps=fps,
|
fps=fps,
|
||||||
|
bitrate="3000k",
|
||||||
ffmpeg_params=[
|
ffmpeg_params=[
|
||||||
"-preset", "ultrafast",
|
"-preset", "ultrafast",
|
||||||
"-tune", "zerolatency",
|
"-tune", "zerolatency",
|
||||||
@@ -37,25 +64,26 @@ def process_segment(input_path: str, top_text: str = "", bottom_text: str = "",
|
|||||||
|
|
||||||
with VideoFileClip(input_path) as clip:
|
with VideoFileClip(input_path) as clip:
|
||||||
dur = clip.duration
|
dur = clip.duration
|
||||||
bg = ColorClip(size=(final_width, final_height), color=(255, 255, 255), duration=dur)
|
bg = ColorClip(size=(final_width, final_height), color=(0, 0, 0), duration=dur)
|
||||||
video_resized = clip.resized(width=final_width)
|
video_resized = clip.resized(width=final_width)
|
||||||
y = top_h + (middle_h - video_resized.h) // 2
|
y = top_h + (middle_h - video_resized.h) // 2
|
||||||
video_resized = video_resized.with_position((0, y))
|
video_resized = video_resized.with_position((0, y))
|
||||||
video_codec = "libx264"
|
wrapped_top_text = auto_wrap_text(top_text, final_width - 40)
|
||||||
|
wrapped_bottom_text = auto_wrap_text(bottom_text, final_width - 40)
|
||||||
|
|
||||||
txt_top = TextClip(
|
txt_top = TextClip(
|
||||||
text=top_text,
|
text=wrapped_top_text,
|
||||||
font_size=70,
|
font_size=70,
|
||||||
color="black",
|
color="white",
|
||||||
font=font,
|
font=font,
|
||||||
method="label",
|
method="label",
|
||||||
size=(final_width, top_h)
|
size=(final_width, top_h)
|
||||||
).with_duration(dur).with_position((0, 0))
|
).with_duration(dur).with_position((0, 0))
|
||||||
|
|
||||||
txt_bot = TextClip(
|
txt_bot = TextClip(
|
||||||
text=bottom_text,
|
text=wrapped_bottom_text,
|
||||||
font_size=70,
|
font_size=70,
|
||||||
color="black",
|
color="white",
|
||||||
font=font,
|
font=font,
|
||||||
method="label",
|
method="label",
|
||||||
size=(final_width, bottom_h),
|
size=(final_width, bottom_h),
|
||||||
@@ -69,6 +97,8 @@ def process_segment(input_path: str, top_text: str = "", bottom_text: str = "",
|
|||||||
output_path,
|
output_path,
|
||||||
codec=video_codec,
|
codec=video_codec,
|
||||||
remove_temp=True,
|
remove_temp=True,
|
||||||
|
fps=30,
|
||||||
|
bitrate="3000k",
|
||||||
ffmpeg_params=[
|
ffmpeg_params=[
|
||||||
"-preset", "ultrafast",
|
"-preset", "ultrafast",
|
||||||
"-tune", "zerolatency",
|
"-tune", "zerolatency",
|
||||||
@@ -107,8 +137,6 @@ def process_full_video(filename: str, times: list = None) -> list:
|
|||||||
video_path = f"videos/{filename}"
|
video_path = f"videos/{filename}"
|
||||||
processed = []
|
processed = []
|
||||||
|
|
||||||
video_codec = "libx264"
|
|
||||||
|
|
||||||
print(f"Total de trechos: {len(times)}")
|
print(f"Total de trechos: {len(times)}")
|
||||||
print(f"Codec de render: {video_codec}")
|
print(f"Codec de render: {video_codec}")
|
||||||
|
|
||||||
|
|||||||
116
main.py
116
main.py
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import pika
|
import pika
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
from components.video import process_full_video
|
from components.video import process_full_video
|
||||||
|
|
||||||
RABBITMQ_HOST = os.environ.get('RABBITMQ_HOST', 'rabbitmq')
|
RABBITMQ_HOST = os.environ.get('RABBITMQ_HOST', 'rabbitmq')
|
||||||
@@ -13,13 +14,33 @@ RABBITMQ_UPLOAD_QUEUE = os.environ.get('RABBITMQ_UPLOAD_QUEUE', 'to-upload')
|
|||||||
if not RABBITMQ_PASS:
|
if not RABBITMQ_PASS:
|
||||||
raise RuntimeError("RABBITMQ_PASS não definido no ambiente")
|
raise RuntimeError("RABBITMQ_PASS não definido no ambiente")
|
||||||
|
|
||||||
|
def get_next_message():
|
||||||
|
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
|
||||||
|
parameters = pika.ConnectionParameters(
|
||||||
|
host=RABBITMQ_HOST,
|
||||||
|
port=RABBITMQ_PORT,
|
||||||
|
credentials=credentials,
|
||||||
|
heartbeat=60,
|
||||||
|
blocked_connection_timeout=300
|
||||||
|
)
|
||||||
|
connection = pika.BlockingConnection(parameters)
|
||||||
|
channel = connection.channel()
|
||||||
|
method_frame, header_frame, body = channel.basic_get(RABBITMQ_QUEUE)
|
||||||
|
if method_frame:
|
||||||
|
channel.basic_ack(method_frame.delivery_tag)
|
||||||
|
connection.close()
|
||||||
|
return body
|
||||||
|
else:
|
||||||
|
connection.close()
|
||||||
|
return None
|
||||||
|
|
||||||
def publish_to_queue(payload):
|
def publish_to_queue(payload):
|
||||||
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
|
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
|
||||||
parameters = pika.ConnectionParameters(
|
parameters = pika.ConnectionParameters(
|
||||||
host=RABBITMQ_HOST,
|
host=RABBITMQ_HOST,
|
||||||
port=RABBITMQ_PORT,
|
port=RABBITMQ_PORT,
|
||||||
credentials=credentials,
|
credentials=credentials,
|
||||||
heartbeat=600,
|
heartbeat=60,
|
||||||
blocked_connection_timeout=300
|
blocked_connection_timeout=300
|
||||||
)
|
)
|
||||||
connection = pika.BlockingConnection(parameters)
|
connection = pika.BlockingConnection(parameters)
|
||||||
@@ -35,61 +56,48 @@ def publish_to_queue(payload):
|
|||||||
)
|
)
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
def callback(ch, method, properties, body):
|
|
||||||
try:
|
|
||||||
data = json.loads(body)
|
|
||||||
filename = data.get("filename")
|
|
||||||
times = data.get("times", [])
|
|
||||||
url = data.get("url")
|
|
||||||
video_id = data.get("videoId")
|
|
||||||
|
|
||||||
print(f"Processando vídeo: {filename}")
|
|
||||||
|
|
||||||
processed_files = process_full_video(filename, times)
|
|
||||||
|
|
||||||
payload = {
|
|
||||||
"videosProcessedQuantity": len(processed_files),
|
|
||||||
"filename": filename,
|
|
||||||
"processedFiles": processed_files,
|
|
||||||
"url": url,
|
|
||||||
"videoId": video_id,
|
|
||||||
"error": False,
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
payload = {
|
|
||||||
"videosProcessedQuantity": 0,
|
|
||||||
"filename": filename if 'filename' in locals() else None,
|
|
||||||
"processedFiles": [],
|
|
||||||
"url": url if 'url' in locals() else None,
|
|
||||||
"videoId": video_id if 'video_id' in locals() else None,
|
|
||||||
"error": str(e),
|
|
||||||
}
|
|
||||||
print(f"Erro no processamento: {e}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
publish_to_queue(payload)
|
|
||||||
print(f"Mensagem publicada na fila '{RABBITMQ_UPLOAD_QUEUE}'.")
|
|
||||||
except Exception as publish_err:
|
|
||||||
print(f"Erro ao publicar na fila '{RABBITMQ_UPLOAD_QUEUE}': {publish_err}")
|
|
||||||
|
|
||||||
ch.basic_ack(delivery_tag=method.delivery_tag)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
|
|
||||||
parameters = pika.ConnectionParameters(
|
|
||||||
host=RABBITMQ_HOST,
|
|
||||||
port=RABBITMQ_PORT,
|
|
||||||
credentials=credentials,
|
|
||||||
heartbeat=600,
|
|
||||||
blocked_connection_timeout=300
|
|
||||||
)
|
|
||||||
connection = pika.BlockingConnection(parameters)
|
|
||||||
channel = connection.channel()
|
|
||||||
channel.queue_declare(queue=RABBITMQ_QUEUE, durable=True)
|
|
||||||
channel.basic_qos(prefetch_count=1)
|
|
||||||
channel.basic_consume(queue=RABBITMQ_QUEUE, on_message_callback=callback)
|
|
||||||
print(' [*] Esperando mensagens. Para sair: CTRL+C')
|
print(' [*] Esperando mensagens. Para sair: CTRL+C')
|
||||||
channel.start_consuming()
|
while True:
|
||||||
|
body = get_next_message()
|
||||||
|
if body is None:
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = json.loads(body)
|
||||||
|
filename = data.get("filename")
|
||||||
|
times = data.get("times", [])
|
||||||
|
url = data.get("url")
|
||||||
|
video_id = data.get("videoId")
|
||||||
|
print(f"Processando vídeo: {filename}")
|
||||||
|
|
||||||
|
processed_files = process_full_video(filename, times)
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"videosProcessedQuantity": len(processed_files),
|
||||||
|
"filename": filename,
|
||||||
|
"processedFiles": processed_files,
|
||||||
|
"url": url,
|
||||||
|
"videoId": video_id,
|
||||||
|
"error": False,
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
payload = {
|
||||||
|
"videosProcessedQuantity": 0,
|
||||||
|
"filename": filename if 'filename' in locals() else None,
|
||||||
|
"processedFiles": [],
|
||||||
|
"url": url if 'url' in locals() else None,
|
||||||
|
"videoId": video_id if 'video_id' in locals() else None,
|
||||||
|
"error": str(e),
|
||||||
|
}
|
||||||
|
print(f"Erro no processamento: {e}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
publish_to_queue(payload)
|
||||||
|
print(f"Mensagem publicada na fila '{RABBITMQ_UPLOAD_QUEUE}'.")
|
||||||
|
except Exception as publish_err:
|
||||||
|
print(f"Erro ao publicar na fila '{RABBITMQ_UPLOAD_QUEUE}': {publish_err}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user