File size: 2,851 Bytes
8f7c473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
Video Renderer
المحرك المشترك بين كل التمبلتس
بياخد التمبلت + البيانات → بيعمل الفيديو
"""

import os
import subprocess
import tempfile
import shutil
from PIL import Image
from templates.base import RenderRequest


def download_font():
    if not os.path.exists('/tmp/arabic.ttf'):
        print('📥 تحميل الخط العربي...')
        result = subprocess.run([
            'wget', '-q', '-O', '/tmp/arabic.ttf',
            'https://github.com/googlefonts/noto-fonts/raw/main/hinted/ttf/NotoNaskhArabic/NotoNaskhArabic-Bold.ttf'
        ], capture_output=True)
        if result.returncode == 0:
            print('✅ الخط جاهز')


def render_video(template, req: RenderRequest) -> str:
    """
    بياخد التمبلت + الـ request
    بيرجع مسار الفيديو النهائي
    """
    download_font()

    W, H   = req.width, req.height
    fps    = req.fps
    total  = req.duration * fps
    tmp    = tempfile.mkdtemp()

    # تحميل الصور
    product_img = None
    if req.image_path and os.path.exists(req.image_path):
        product_img = Image.open(req.image_path).convert('RGBA')

    logo_img = None

    # رسم الـ frames
    print(f'🎬 [{template.NAME}] بيرسم {total} frame...')
    for i in range(total):
        t = i / fps
        frame = template.make_frame(t, req, product_img, logo_img)
        frame.save(os.path.join(tmp, f'frame_{i:05d}.png'))
        if i % fps == 0:
            print(f'   {i//fps}/{req.duration} ثانية')

    # FFmpeg — بيعمل الفيديو
    video_raw = os.path.join(tmp, 'raw.mp4')
    print('🎞️  FFmpeg...')
    subprocess.run([
        'ffmpeg', '-y',
        '-framerate', str(fps),
        '-i', os.path.join(tmp, 'frame_%05d.png'),
        '-c:v', 'libx264',
        '-pix_fmt', 'yuv420p',
        '-crf', '18',
        '-movflags', '+faststart',
        video_raw
    ], capture_output=True)

    # إضافة الموسيقى
    final = req.output_path
    if req.music_path and os.path.exists(req.music_path):
        print('🎵 بيضيف الموسيقى...')
        result = subprocess.run([
            'ffmpeg', '-y',
            '-i', video_raw,
            '-i', req.music_path,
            '-filter_complex',
            f'[1:a]volume={req.music_volume},'
            f'afade=t=in:st=0:d=1,'
            f'afade=t=out:st=4:d=2[m];[m]apad[audio]',
            '-map', '0:v',
            '-map', '[audio]',
            '-shortest',
            '-c:v', 'copy',
            '-c:a', 'aac',
            '-b:a', '192k',
            final
        ], capture_output=True, text=True)

        if result.returncode != 0:
            shutil.copy(video_raw, final)
    else:
        shutil.copy(video_raw, final)

    shutil.rmtree(tmp)
    return final