Вопрос или проблема
WhisperDesktop — это модели Whisper от OpenAI для задач распознавания речи.
WhisperDeskTop.exe на Windows10
Используемый GPU
WhisperDeskTop.exe .mkv в .srt, но только один раз
Поэтому, если я хочу конвертировать все видео, мне нужно будет только нажимать. Тогда я решил написать скрипт.
В Power Shell установил python3.8, создал виртуальное окружение Python с помощью python -m venv thename
(‘thename’ — это просто имя окружения). Затем активировал окружение, использовал .\Scripts\Activate.ps1
. Как на картинке,
Я также установил NVIDIA CUDA, CUDNN, ffmpeg, pytorch, загрузил модели openAI, такие как large, medium, на свой ноутбук. Все они были проверены.
В чем проблема?
import os
import subprocess
import time
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
video_directory = ""
ffmpeg_command = 'ffmpeg -i "{}" -f wav -vn "{}"'
whisper_command = 'whispercli -gpu -nt -m "D:\\Whisper\\model\\ggml-large-v3-turbo.bin" -l en -nt -osrt -f "{}"'
def convert_video_to_audio(video_path, audio_path, video_name):
ffmpeg_output = subprocess.check_output(
ffmpeg_command.format(video_path, audio_path),
shell=True,
stderr=subprocess.DEVNULL,
)
def gen_audio_srt(audio_path, video_name):
whisper_output = subprocess.check_output(
whisper_command.format(audio_path), shell=True, encoding="utf-8"
)
def process_video(video_file):
video_path = os.path.join(video_directory, video_file)
video_name = os.path.splitext(video_file)[0]
audio_path = os.path.join(video_directory, video_name + ".wav")
srt_path = os.path.join(video_directory, video_name + ".srt")
if os.path.exists(srt_path):
print(f"srt уже существует.")
return 0
convert_video_to_audio(video_path, audio_path, video_name)
gen_audio_srt(audio_path, video_name)
os.remove(audio_path)
return 1
def process_videos():
start_time = time.time()
n = 0
video_files = [
f
for f in os.listdir(video_directory)
if f.endswith((".mp4", ".avi", ".mkv", ".flv", ".mov"))
]
with ThreadPoolExecutor() as executor:
results = list(tqdm(executor.map(process_video, video_files), total=len(video_files), desc="обработка... "))
n = sum(results)
end_time = time.time()
print("{:d} видео, время токена: {:.2f}с".format(n, end_time - start_time))
if __name__ == "__main__":
path = ""
while True:
path = input("директория: ")
if os.path.exists(path):
break
else:
print(f"{path} путь может быть неверным...")
video_directory = path
process_videos()
Пожалуйста, помогите мне завершить скрипт на Python. Спасибо всем.
Ответ или решение
Чтобы создать скрипт, который будет автоматически обрабатывать все видеофайлы в указанной директории с использованием WhisperDesktop, нам нужно внести некоторые изменения в ваш код. Основная проблема в вашем текущем скрипте заключается в том, что вы используете ThreadPoolExecutor
, что может вызвать конфликты из-за того, что WhisperDesktop может обрабатывать только один файл за раз. Следовательно, лучшим подходом будет использовать последовательное выполнение задач вместо многопоточности.
Вот исправленный и доработанный вариант вашего скрипта:
import os
import subprocess
import time
from tqdm import tqdm
video_directory = ""
ffmpeg_command = 'ffmpeg -i "{}" -f wav -vn "{}"'
whisper_command = 'whispercli -gpu -nt -m "D:\\Whisper\\model\\ggml-large-v3-turbo.bin" -l en -nt -osrt -f "{}"'
def convert_video_to_audio(video_path, audio_path):
try:
subprocess.check_output(
ffmpeg_command.format(video_path, audio_path),
shell=True,
stderr=subprocess.STDOUT,
)
return True
except subprocess.CalledProcessError as e:
print(f"Ошибка при конвертации {video_path}: {e.output.decode()}")
return False
def gen_audio_srt(audio_path):
try:
subprocess.check_output(
whisper_command.format(audio_path), shell=True, encoding="utf-8"
)
return True
except subprocess.CalledProcessError as e:
print(f"Ошибка при генерации .srt для {audio_path}: {e.output.decode()}")
return False
def process_video(video_file):
video_path = os.path.join(video_directory, video_file)
video_name = os.path.splitext(video_file)[0]
audio_path = os.path.join(video_directory, video_name + ".wav")
srt_path = os.path.join(video_directory, video_name + ".srt")
if os.path.exists(srt_path):
print(f"Файл srt для {video_name} уже существует.")
return 0
if convert_video_to_audio(video_path, audio_path):
if gen_audio_srt(audio_path):
os.remove(audio_path)
return 1
return 0
def process_videos():
start_time = time.time()
n = 0
video_files = [
f
for f in os.listdir(video_directory)
if f.endswith((".mp4", ".avi", ".mkv", ".flv", ".mov"))
]
for video_file in tqdm(video_files, desc="Обработка видео"):
n += process_video(video_file)
end_time = time.time()
print("{:d} видео(а) обработано, общее время: {:.2f} секунд.".format(n, end_time - start_time))
if __name__ == "__main__":
while True:
path = input("Введите путь к директории: ")
if os.path.exists(path) and os.path.isdir(path):
video_directory = path
break
else:
print(f"{path} неверный путь... Пожалуйста, попробуйте снова.")
process_videos()
Объяснение изменений:
-
Удаление многопоточности: Теперь обработка видео происходит последовательно. Это уменьшает риск конфликтов, связанных с одновременной обработкой нескольких файлов.
-
Обработка ошибок: Добавлены блоки
try-except
, чтобы обрабатывать возможные ошибки при выполнении командыsubprocess
. Это позволит вам понять, что пошло не так, если возникнут проблемы. -
Улучшенный вывод сообщений: Сообщения теперь передают более точную информацию о том, что происходит.
-
Условие для проверки директории: Мы убедились, что введённый путь является директорией, прежде чем продолжить выполнение.
Этот скрипт должен корректно обрабатывать все видеофайлы в указанной директории, конвертируя их в аудио и затем генерируя соответствующие .srt
файлы. Убедитесь, что все пути к исполняемым файлам и моделям установлены верно.