portalniy-dev commited on
Commit
ba96aa5
·
verified ·
1 Parent(s): 5af649f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -0
app.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ import subprocess
4
+ from tempfile import mkstemp
5
+ from telegram import Update
6
+ from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
7
+
8
+ # Настройки
9
+ TOKEN = "7709328099:AAHvvz2Dqkzb2c0lNh9OViTBnUoW6ZcpreA"
10
+ ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov', 'mkv'}
11
+ TEMP_DIR = "temp_files"
12
+
13
+ # Настройка логирования
14
+ logging.basicConfig(
15
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
16
+ level=logging.INFO
17
+ )
18
+
19
+ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
20
+ await update.message.reply_text(
21
+ "Привет! Отправь мне видео, и я интерполирую кадры до нужного FPS. "
22
+ "Используй команду /help для справки."
23
+ )
24
+
25
+ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
26
+ await update.message.reply_text(
27
+ "Как использовать бота:\n"
28
+ "1. Отправь мне видео файл\n"
29
+ "2. Укажи желаемый FPS (целое число)\n"
30
+ "3. Жди результат обработки\n\n"
31
+ "Ограничения: максимальный размер файла 20MB"
32
+ )
33
+
34
+ async def handle_video(update: Update, context: ContextTypes.DEFAULT_TYPE):
35
+ if not update.message.video:
36
+ await update.message.reply_text("Пожалуйста, отправьте видео файл")
37
+ return
38
+
39
+ # Создаем временную директорию
40
+ os.makedirs(TEMP_DIR, exist_ok=True)
41
+
42
+ # Сохраняем файл
43
+ video_file = await update.message.video.get_file()
44
+ ext = video_file.file_path.split('.')[-1] if video_file.file_path else 'mp4'
45
+ input_path = os.path.join(TEMP_DIR, f"input_{update.update_id}.{ext}")
46
+ await video_file.download_to_drive(input_path)
47
+
48
+ context.user_data['input_path'] = input_path
49
+ await update.message.reply_text("Видео получено. Теперь введите желаемый FPS:")
50
+
51
+ async def handle_fps(update: Update, context: ContextTypes.DEFAULT_TYPE):
52
+ try:
53
+ target_fps = int(update.message.text)
54
+ if target_fps <= 0:
55
+ raise ValueError
56
+ except ValueError:
57
+ await update.message.reply_text("Пожалуйста, введите корректное целое число FPS")
58
+ return
59
+
60
+ input_path = context.user_data.get('input_path')
61
+ if not input_path or not os.path.exists(input_path):
62
+ await update.message.reply_text("Ошибка: видео не найдено")
63
+ return
64
+
65
+ try:
66
+ # Получаем исходный FPS
67
+ cmd = f"ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 {input_path}"
68
+ original_fps = subprocess.check_output(cmd, shell=True).decode().strip().split('/')
69
+ original_fps = float(original_fps[0])/float(original_fps[1])
70
+
71
+ if target_fps <= original_fps:
72
+ await update.message.reply_text(f"Целевой FPS должен быть больше исходного ({original_fps:.2f})")
73
+ return
74
+ except Exception as e:
75
+ await update.message.reply_text("Ошибка при определении исходного FPS видео")
76
+ logging.error(e)
77
+ return
78
+
79
+ # Обработка видео
80
+ output_path = os.path.join(TEMP_DIR, f"output_{update.update_id}.mp4")
81
+
82
+ try:
83
+ cmd = [
84
+ 'ffmpeg',
85
+ '-i', input_path,
86
+ '-vf', f'minterpolate=fps={target_fps}',
87
+ '-c:v', 'libx264',
88
+ '-preset', 'medium',
89
+ '-crf', '23',
90
+ '-y',
91
+ output_path
92
+ ]
93
+
94
+ subprocess.run(cmd, check=True, timeout=300)
95
+
96
+ # Отправка результата
97
+ await update.message.reply_video(video=open(output_path, 'rb'))
98
+
99
+ except subprocess.TimeoutExpired:
100
+ await update.message.reply_text("Обработка заняла слишком много времени")
101
+ except Exception as e:
102
+ await update.message.reply_text("Ошибка при обработке видео")
103
+ logging.error(e)
104
+ finally:
105
+ # Удаление временных файлов
106
+ for path in [input_path, output_path]:
107
+ if path and os.path.exists(path):
108
+ os.remove(path)
109
+
110
+ def main():
111
+ application = Application.builder().token(TOKEN).build()
112
+
113
+ application.add_handler(CommandHandler("start", start))
114
+ application.add_handler(CommandHandler("help", help_command))
115
+ application.add_handler(MessageHandler(filters.VIDEO, handle_video))
116
+ application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_fps))
117
+
118
+ application.run_polling()
119
+
120
+ if __name__ == '__main__':
121
+ main()