Вот мой модуль скачивания видео ютуб:
```py
import asyncio
from typing import AsyncGenerator, Optional, Dict, Any
from concurrent.futures import ThreadPoolExecutor
import yt_dlp
import os

class YoutubeDownloader:
    def __init__(self, max_workers: int = 15):
        """
        Инициализация YoutubeDownloader.

        :param max_workers: Максимальное количество одновременных скачиваний.
        """
        self.loop = asyncio.get_event_loop()
        self.executor = ThreadPoolExecutor(max_workers=max_workers)

    async def download(
        self,
        url: str,
        output_path: str,
        range_start: Optional[float] = None,  # Начало в секундах
        range_end: Optional[float] = None,    # Конец в секундах
    ) -> AsyncGenerator[Dict[str, Any], None]:
        """
        Асинхронный генератор для скачивания видео.

        :param url: URL видео на YouTube.
        :param output_path: Путь к файлу для сохранения видео.
        :param range_start: Начальное время скачивания в секундах.
        :param range_end: Конечное время скачивания в секундах.
        :yield: Словарь с прогрессом и путем к файлу при завершении.
        """
        queue: asyncio.Queue = asyncio.Queue()

        def progress_hook(d):
            if d['status'] == 'downloading':
                percent = d.get('_percent_str', '0.0').strip().replace('%', '')
                # Безопасно добавляем элемент в очередь из другого потока
                self.loop.call_soon_threadsafe(
                    queue.put_nowait, {"progress": percent, "filepath": None}
                )
            elif d['status'] == 'finished':
                self.loop.call_soon_threadsafe(
                    queue.put_nowait, {"progress": "100", "filepath": output_path}
                )

        ydl_opts = {
            'format': 'bestvideo+bestaudio/best',
            'outtmpl': output_path,
            'progress_hooks': [progress_hook],
            'noplaylist': True,
            # 'external_downloader': 'ffmpeg',  # Можно явно указать, если требуется
            # 'external_downloader_args': ['-nostdin'],  # Опции внешнего загрузчика, например, ffmpeg
            # Удалены некорректные параметры
        }

        # Настройка диапазона скачивания
        if range_start is not None or range_end is not None:
            sections = []
            from_sec = range_start if range_start is not None else 0
            # Преобразуем секунды в формат ЧЧ:ММ:СС
            def format_time(seconds: float) -> str:
                hours = int(seconds // 3600)
                minutes = int((seconds % 3600) // 60)
                secs = int(seconds % 60)
                return f"{hours:02}:{minutes:02}:{secs:02}"

            from_time = format_time(from_sec)
            if range_end is not None:
                to_time = format_time(range_end)
                section = f"{from_time}-{to_time}"
            else:
                section = f"{from_time}-"

            sections.append(f"*{section}")
            ydl_opts['download_sections'] = sections

        def run_download():
            try:
                with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                    ydl.download([url])
            except Exception as e:
                # Добавляем ошибку в очередь
                self.loop.call_soon_threadsafe(
                    queue.put_nowait, {"error": str(e)}
                )

        # Запуск скачивания в отдельном потоке
        self.loop.run_in_executor(self.executor, run_download)

        try:
            while True:
                progress = await queue.get()
                if "error" in progress:
                    yield progress
                    break
                yield progress
                if progress.get("progress") == "100":
                    break
        finally:
            # Опционально можно добавить очистку или закрытие ресурсов
            pass

    def close(self):
        """
        Закрытие ThreadPoolExecutor.
        """
        self.executor.shutdown(wait=True)


# Пример использования
async def main():
    downloader = YoutubeDownloader()

    # Замените на нужный URL
    url = "https://www.youtube.com/watch?v=FZHENc7i8KM"
    output = "video1233.mp4"
    start = 30  # Начало на 30-й секунде
    end = 60    # Конец на 60-й секунде

    try:
        async for progress in downloader.download(url, output, range_start=start, range_end=end):
            if "error" in progress:
                print(f"Ошибка: {progress['error']}")
            else:
                print(f"Прогресс: {progress['progress']}%")
                if progress.get("filepath"):
                    print(f"Файл сохранён по пути: {progress['filepath']}")
    finally:
        downloader.close()

# Запуск примера
if __name__ == "__main__":
    asyncio.run(main())
```
Исправь его, чтобы он мог скачивать фрагменты видео