-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_colab.py
More file actions
270 lines (266 loc) · 16.2 KB
/
Copy pathgenerate_colab.py
File metadata and controls
270 lines (266 loc) · 16.2 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
import json
notebook = {
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Video_Translator_Colab.ipynb",
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "intro"
},
"source": [
"# 🚀 NullOfflineVideoTranslator (Google Colab Edition)\n",
"Убедитесь, что вы включили видеокарту: `Среда выполнения` -> `Сменить среду выполнения` -> `T4 GPU`."
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {
"id": "setup_cell",
"cellView": "form"
},
"outputs": [],
"source": [
"# @title 🔧 Шаг 1. Подготовка системы (Запустите один раз!)\n",
"# @markdown Установка нейросетей через `uv` (ультрабыстрый пакетный менеджер на Rust) и обновление системных библиотек Colab.\n",
"import os\n",
"import sys\n",
"import subprocess\n",
"\n",
"print(\"📦 Установка uv...\")\n",
"!pip install -q uv\n",
"print(\"📦 Быстрое скачивание зависимостей (займет ~2-3 минуты из-за сборки шумодава)...\")\n",
"!apt-get install -yq rubberband-cli\n",
"print(\"⚙️ Установка компилятора Rust (нужен для крутого шумодава)...\")\n",
"!curl -sSf https://sh.rustup.rs > rustup.sh && sh rustup.sh -y -q > /dev/null 2>&1 && rm rustup.sh\n",
"import os\n",
"os.environ['PATH'] = f\"{os.environ.get('HOME', '/root')}/.cargo/bin:{os.environ['PATH']}\"\n",
"!uv pip uninstall --system onnxruntime onnxruntime-gpu\n",
"!uv pip install --system yt-dlp pydub ffmpeg-python demucs librosa python-dotenv google-generativeai onnx huggingface_hub pyrubberband hangul-romanize jamo cutlet fugashi unidecode g2p_en pypinyin num2words spacy numba git+https://github.com/m-bain/whisperx.git\n",
"!uv pip install --system onnxruntime-gpu==1.19.2\n",
"print(\"🧹 Сборка шумодава DeepFilterNet из исходников...\")\n",
"!uv pip install --system deepfilterlib loguru appdirs\n",
"!uv pip install --system --no-deps deepfilternet\n",
"\n",
"print(\"✅ Установка завершена!\")\n",
"try:\n",
" import numpy as np\n",
" if int(np.__version__.split('.')[0]) < 2:\n",
" print(\"🔄 Сброс кэша Colab для применения новых библиотек (автоматическая перезагрузка)...\")\n",
" print(\"➡️ После перезагрузки переходите сразу к Шагу 2!\")\n",
" os.kill(os.getpid(), 9)\n",
" else:\n",
" print(\"✅ Система готова! Переходите к Шагу 2.\")\n",
"except ImportError:\n",
" pass\n"
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {
"id": "main_cell",
"cellView": "form"
},
"outputs": [],
"source": [
"# @title ⚙️ Шаг 2. Интерактивная настройка и запуск\n",
"# @markdown Заполните поля ниже и нажмите кнопку Play слева (▶️).\n",
"\n",
"# @markdown --- \n",
"# @markdown **Настройки GitHub (обязательно)**\n",
"GITHUB_REPO = \"NullCoreDeveloper/NullOfflineVideoTranslator\" # @param {type:\"string\"}\n",
"GITHUB_TOKEN = \"\" # @param {type:\"string\"}\n",
"# @markdown *Если репозиторий публичный, оставьте GITHUB_TOKEN пустым. Если приватный — вставьте Personal Access Token (Classic).* \n",
"\n",
"# @markdown --- \n",
"# @markdown **Настройки нейросетей (обязательно)**\n",
"HF_TOKEN = \"\" # @param {type:\"string\"}\n",
"GEMINI_KEYS = \"\" # @param {type:\"string\"}\n",
"\n",
"# @markdown --- \n",
"# @markdown **Что переводим?**\n",
"INPUT_MODE = \"YouTube Link\" # @param [\"YouTube Link\", \"Local File\", \"Colab Server Path\"]\n",
"VIDEO_URL = \"https://youtu.be/XQcf7NVxcVA?si=g37mQ_vUWvIF59X8\" # @param {type:\"string\"}\n",
"# @markdown *Если 'Local File': появится кнопка загрузки с ПК. Если 'Colab Server Path': вставьте локальный путь к файлу в поле VIDEO_URL (полезно, если вы скачали видео вручную через терминал/yt-dlp).*\n",
"# @markdown \n",
"# @markdown **На какой язык перевести?**\n",
"TARGET_LANGUAGE = \"ru\" # @param [\"ru\", \"en\", \"es\", \"fr\", \"de\", \"it\", \"pt\", \"pl\", \"tr\", \"nl\", \"cs\", \"ar\", \"zh-cn\", \"ja\", \"hu\", \"ko\", \"hi\"]\n",
"\n",
"import os\n",
"import subprocess\n",
"import time\n",
"\n",
"start_time = time.time()\n",
"print(\"⏳ Подготовка окружения...\")\n",
"\n",
"# 0. Сброс директории (защита от матрешки при перезапуске)\n",
"os.chdir('/content')\n",
"\n",
"# 1. Клонирование репозитория\n",
"if not os.path.exists(\"video-translator\"):\n",
" if GITHUB_TOKEN:\n",
" repo_url = f\"https://{GITHUB_TOKEN}@github.com/{GITHUB_REPO}.git\"\n",
" else:\n",
" repo_url = f\"https://github.com/{GITHUB_REPO}.git\"\n",
" \n",
" !git clone {repo_url} video-translator\n",
"else:\n",
" !cd video-translator && git pull\n",
"\n",
"os.chdir(\"video-translator\")\n",
"\n",
"# 1.5 Подготовка видео (ранняя загрузка, чтобы не ждать установок)\n",
"LOCAL_FILE = None\n",
"if INPUT_MODE == 'Local File':\n",
" from google.colab import files\n",
" print(\"\\n👇 Пожалуйста, выберите видеофайл на вашем компьютере для загрузки:\")\n",
" uploaded = files.upload()\n",
" if not uploaded:\n",
" print(\"❌ Ошибка: Файл не был загружен! Остановка.\")\n",
" import sys; sys.exit(1)\n",
" LOCAL_FILE = list(uploaded.keys())[0]\n",
" print(f\"✅ Файл {LOCAL_FILE} успешно загружен! Начинаю установку нейросетей...\\n\")\n",
"elif INPUT_MODE == 'Colab Server Path':\n",
" if not os.path.exists(VIDEO_URL):\n",
" print(f\"❌ Ошибка: Файл по пути '{VIDEO_URL}' не найден на сервере!\")\n",
" import sys; sys.exit(1)\n",
" LOCAL_FILE = VIDEO_URL\n",
" print(f\"✅ Найден локальный файл: {LOCAL_FILE}. Начинаю установку нейросетей...\\n\")\n",
"elif INPUT_MODE == 'YouTube Link':\n",
" print(f\"\\n🎥 Пробуем скачать видео с YouTube: {VIDEO_URL}\")\n",
" !pip install -q yt-dlp\n",
" import subprocess, re\n",
" try:\n",
" raw_title = subprocess.check_output(['yt-dlp', '--print', '%(title)s', VIDEO_URL]).decode('utf-8').strip()\n",
" clean_title = re.sub(r'[^\\w\\s-]', '', raw_title).strip().replace(' ', '_')[:12]\n",
" if not clean_title: clean_title = 'video'\n",
" LOCAL_FILE = f'{clean_title}.mp4'\n",
" subprocess.run(['yt-dlp', '-f', 'bestvideo[height<=1080]+bestaudio/best', '--merge-output-format', 'mp4', '-o', LOCAL_FILE, VIDEO_URL], check=True)\n",
" if not os.path.exists(LOCAL_FILE): raise Exception('Файл не создался')\n",
" print(f\"✅ Видео успешно скачано: {LOCAL_FILE}. Начинаю установку нейросетей...\\n\")\n",
" except Exception as e:\n",
" print(\"\\n====================================================================\")\n",
" print(\"❌ КРИТИЧЕСКАЯ ОШИБКА: yt-dlp не смог скачать видео с YouTube!\")\n",
" print(\"Скорее всего, сработала защита от ботов на IP-адресах Google Colab.\")\n",
" print(\"💡 РЕШЕНИЕ 1: В меню Colab нажмите 'Среда выполнения' -> 'Отключиться и удалить среду', затем запустите ячейку заново.\")\n",
" print(\"💡 РЕШЕНИЕ 2: Скачайте видео на ПК, выберите выше 'INPUT_MODE = Local File' и загрузите его вручную.\")\n",
" print(\"====================================================================\\n\")\n",
" import sys; sys.exit(1)\n",
"\n",
"# 2. Создание .env файла\n",
"with open('.env', 'w') as f:\n",
" f.write(f\"HF_TOKEN={HF_TOKEN}\\n\")\n",
" f.write(f\"GEMINI_API_KEYS={GEMINI_KEYS}\\n\")\n",
" f.write(\"PROXY_URL=\\n\")\n",
"print(\"✅ Ключи загружены!\")\n",
"\n",
"# 3. Скачивание моделей XTTS\n",
"print(\"📥 Скачивание и подготовка моделей XTTS...\")\n",
"import sys\n",
"sys.path.append('.')\n",
"import install\n",
"install.download_and_quantize_xtts(HF_TOKEN)\n",
"print(\"🔧 Включение GPU ускорения для XTTS...\")\n",
"orch_path = 'xtts_models/xtts_onnx_orchestrator.py'\n",
"if os.path.exists(orch_path):\n",
" with open(orch_path, 'r') as f:\n",
" code = f.read()\n",
" code = code.replace('[\"CPUExecutionProvider\"]', '[\"CUDAExecutionProvider\", \"CPUExecutionProvider\"]')\n",
" with open(orch_path, 'w') as f:\n",
" f.write(code)\n",
" print(\"✅ CUDA Execution Provider активирован!\")\n",
"\n",
"# 4. Запуск перевода\n",
"print(f\"🎥 Обработка файла: {LOCAL_FILE} -> {TARGET_LANGUAGE}\")\n",
"!python3 main.py \"{LOCAL_FILE}\" --target_lang \"{TARGET_LANGUAGE}\"\n",
"\n",
"import glob\n",
"result_files = glob.glob(\"*_translated_*/*.mp4\")\n",
"if result_files:\n",
" latest_file = max(result_files, key=os.path.getctime)\n",
" elapsed = time.time() - start_time\n",
" print(f\"\\n🎉 Готово! Видео переведено и сохранено.\")\n",
" print(f\"⏱️ Общее время обработки: {int(elapsed // 60)} мин {int(elapsed % 60)} сек\")\n",
" from google.colab import output, files\n",
" from IPython.display import HTML, display\n",
" import base64\n",
" \n",
" def download_video():\n",
" files.download(latest_file)\n",
" \n",
" output.register_callback('notebook.download_video', download_video)\n",
" \n",
" html = '''\n",
" <br><br>\n",
" <button id=\"download_btn\" style=\"\n",
" background-color: #4CAF50; border: none; color: white;\n",
" padding: 15px 32px; text-align: center; text-decoration: none;\n",
" display: inline-block; font-size: 16px; margin: 4px 2px;\n",
" cursor: pointer; border-radius: 12px; font-weight: bold;\n",
" box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\">\n",
" 📥 СКАЧАТЬ ВИДЕО\n",
" </button>\n",
" <p style=\"color: #666; font-size: 14px; margin-top: 10px;\">\n",
" ℹ️ <b>Особенность Colab:</b> При нажатии появится кружок загрузки. Colab сначала копирует файл в кэш вашего браузера. Стандартное окно сохранения файла откроется только когда кружок дойдет до 100%.<br>\n",
" <i>Альтернативный способ: Нажмите на иконку папки 📁 в левом меню экрана, найдите ваш .mp4 файл, нажмите на него правой кнопкой мыши -> Скачать (Download).</i>\n",
" </p>\n",
" <script>\n",
" document.querySelector(\"#download_btn\").onclick = function() {\n",
" google.colab.kernel.invokeFunction('notebook.download_video', [], {});\n",
" };\n",
" </script>\n",
" '''\n",
" display(HTML(html))\n",
"else:\n",
" print(\"\\n⚠️ Итоговое видео не найдено. Возможно, произошла ошибка.\")"
]
}
]
}
# Добавляем ячейку-справку в конец блокнота
help_cell = {
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"# 📖 Справка: Где взять токены и ключи?\n",
"\n",
"### 1. Как получить `HF_TOKEN` (HuggingFace)\n",
"Этот токен нужен для скачивания мощных нейросетей озвучки (XTTSv2) и разделения голосов (Pyannote).\n",
"1. Зарегистрируйтесь на сайте [Hugging Face](https://huggingface.co/join).\n",
"2. Перейдите в настройки токенов: [Settings -> Access Tokens](https://huggingface.co/settings/tokens).\n",
"3. Нажмите `New token`, дайте ему любое имя (например, `colab`), выберите роль `Read` и создайте.\n",
"4. Скопируйте длинный ключ (начинается на `hf_...`) и вставьте в поле `HF_TOKEN`.\n",
"5. **ВАЖНО:** Для работы моделей вам может потребоваться принять их лицензионные соглашения. Обязательно перейдите по всем трем ссылкам и нажмите **Agree and access repository** (если такая кнопка есть):\n",
" * [XTTSv2 ONNX](https://huggingface.co/pltobing/XTTSv2-Streaming-ONNX)\n",
" * [Pyannote Diarization](https://huggingface.co/pyannote/speaker-diarization-3.1)\n",
" * [Pyannote Segmentation](https://huggingface.co/pyannote/segmentation-3.0)\n",
"\n",
"### 2. Как получить `GEMINI_KEYS`\n",
"Этот ключ нужен для перевода субтитров с учетом контекста и геймерского сленга.\n",
"1. Перейдите в [Google AI Studio](https://aistudio.google.com/app/apikey).\n",
"2. Нажмите `Create API key`.\n",
"3. Скопируйте полученный ключ.\n",
"4. Вы можете создать несколько ключей на разных аккаунтах и перечислить их через запятую в поле `GEMINI_KEYS` (например: `AIzaSy..., AIzaBf...`). Скрипт будет автоматически переключаться между ними, если один закончится.\n"
]
}
notebook["cells"].append(help_cell)
with open("NullOfflineVideoTranslator.ipynb", "w", encoding="utf-8") as f:
json.dump(notebook, f, indent=2, ensure_ascii=False)
print("Playbook generated successfully: NullOfflineVideoTranslator.ipynb")