File size: 3,709 Bytes
11fa042
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
97
98
99
100
101
102
103
104
105
106
107
108
import os
import asyncio
import time
from pyrogram import Client, filters
from ..utils.helper import check_chat
from ..svcs.user_svc import add_user_if_new
from ..core.cfg import cfg
from ..core.log import log
from ..utils.display_progress import progress_for_pyrogram, humanbytes
from ..utils.encoding import get_duration

@Client.on_message(filters.command(['sample', 'preview']))
async def sample_handler(app, message):
    if not await check_chat(message, chat='Both'):
        return
    
    if not message.reply_to_message:
        await message.reply(
            "▸ <b>Sample</b>\n"
            "Status: ✗ Failed\n\n"
            "<blockquote>Reply to a video with this command to generate a preview sample.</blockquote>"
        )
        return
    
    reply = message.reply_to_message
    
    if not (reply.video or (reply.document and reply.document.mime_type and reply.document.mime_type.startswith('video/'))):
        await message.reply(
            "▸ <b>Sample</b>\n"
            "Status: ✗ Failed\n\n"
            "<blockquote>The replied message is not a video.</blockquote>"
        )
        return
    
    await add_user_if_new(app, message)
    
    duration = 30
    if len(message.command) > 1:
        try:
            duration = min(int(message.command[1]), 120)
        except:
            pass
    
    msg = await message.reply("▸ <b>Sample</b>\nStatus: ● Downloading video...")
    
    try:
        start_time = time.time()
        filepath = await reply.download(
            file_name=cfg.DOWNLOAD_DIR,
            progress=progress_for_pyrogram,
            progress_args=("▸ <b>Sample</b>\nStatus: ● Downloading...", msg, start_time)
        )
        
        if not filepath:
            await msg.edit("▸ <b>Sample</b>\nStatus: ✗ Download Failed")
            return
        
        await msg.edit("▸ <b>Sample</b>\nStatus: ● Generating preview...")
        
        video_duration = get_duration(filepath)
        if video_duration <= duration:
            start_time_sec = 0
            duration = video_duration
        else:
            start_time_sec = int(video_duration * 0.1)
        
        basename = os.path.basename(filepath)
        name, ext = os.path.splitext(basename)
        output_path = os.path.join(cfg.ENCODE_DIR, f"sample_{name}{ext}")
        
        cmd = [
            'ffmpeg', '-y', '-ss', str(start_time_sec),
            '-i', filepath, '-t', str(duration),
            '-c', 'copy', '-avoid_negative_ts', '1',
            output_path
        ]
        
        proc = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE
        )
        await proc.communicate()
        
        if proc.returncode != 0 or not os.path.exists(output_path):
            await msg.edit("▸ <b>Sample</b>\nStatus: ✗ Failed to generate sample")
            return
        
        await msg.edit("▸ <b>Sample</b>\nStatus: ● Uploading preview...")
        
        sample_size = os.path.getsize(output_path)
        await reply.reply_video(
            output_path,
            caption=f"▸ <b>Sample Preview</b>\nDuration: {duration}s | Size: {humanbytes(sample_size)}",
            supports_streaming=True
        )
        
        await msg.delete()
        
    except Exception as e:
        log.err("sample_error", error=str(e))
        await msg.edit(f"▸ <b>Sample</b>\nStatus: ✗ Error\n{str(e)[:100]}")
    finally:
        if 'filepath' in locals() and os.path.exists(filepath):
            os.remove(filepath)
        if 'output_path' in locals() and os.path.exists(output_path):
            os.remove(output_path)