Files
adaptive-video-converter/docs/api/convert.md
2025-12-03 22:46:15 +03:00

9.8 KiB
Raw Blame History

convertToDash()

Главная функция для конвертации видео в адаптивные форматы DASH и HLS.

Сигнатура

async function convertToDash(
  options: DashConvertOptions
): Promise<DashConvertResult>

Параметры

DashConvertOptions

Параметр Тип Обязательный По умолчанию Описание
input string - Путь к входному видео файлу
outputDir string - Директория для выходных файлов
segmentDuration number 2 Длительность сегмента в секундах
profiles VideoProfile[] автовыбор Массив профилей качества
customProfiles string[] автовыбор Профили как строки (например, ['720', '1080@60'])
codec CodecType 'dual' Кодек: 'h264', 'av1' или 'dual'
format StreamingFormat 'both' Формат: 'dash', 'hls' или 'both'
useNvenc boolean auto Использовать NVENC (автоопределение)
quality QualitySettings auto Настройки качества (CQ/CRF)
generateThumbnails boolean true Генерировать превью-спрайт
thumbnailConfig ThumbnailConfig см. ниже Конфигурация превью
generatePoster boolean true Генерировать постер
posterTimecode string '00:00:01' Таймкод постера
parallel boolean true Параллельное кодирование
onProgress function - Колбэк для прогресса

Возвращаемое значение

DashConvertResult

interface DashConvertResult {
  manifestPath: string;       // Путь к DASH манифесту
  hlsManifestPath?: string;   // Путь к HLS манифесту (если format='hls' или 'both')
  segments: string[];         // Пути к сегментам
  thumbnailPath?: string;     // Путь к спрайту превью
  posterPath?: string;        // Путь к постеру
}

Примеры

Базовое использование

import { convertToDash } from '@grom13/adaptive-video-converter';

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output'
});

console.log('DASH манифест:', result.manifestPath);
console.log('HLS манифест:', result.hlsManifestPath);

С кастомными профилями

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  customProfiles: ['360', '720', '1080']
});

С высоким FPS

const result = await convertToDash({
  input: './gameplay.mp4',
  outputDir: './output',
  customProfiles: ['720@60', '1080@60', '1440@120']
});

Выбор кодека

// Только H.264
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  codec: 'h264'
});

// Только AV1
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  codec: 'av1'
});

// Оба кодека (по умолчанию)
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  codec: 'dual'
});

Выбор формата

// Только DASH
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  format: 'dash'
});

// Только HLS
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  format: 'hls',
  codec: 'h264'  // HLS лучше работает с H.264
});

// Оба формата (по умолчанию)
await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  format: 'both'
});

С отслеживанием прогресса

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  onProgress: (progress) => {
    console.log(`Прогресс: ${progress.percent}%`);
    console.log(`Этап: ${progress.stage}`);
    console.log(`Профиль: ${progress.currentProfile}`);
    console.log(`ETA: ${progress.eta}s`);
  }
});

С настройками качества

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  quality: {
    h264: {
      cq: 28,   // CQ для GPU
      crf: 23   // CRF для CPU (фоллбек)
    },
    av1: {
      cq: 35,
      crf: 35
    }
  }
});

С кастомной конфигурацией превью

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  thumbnailConfig: {
    width: 320,         // Ширина превью
    height: 180,        // Высота превью
    interval: 2,        // Интервал в секундах
    columns: 10,        // Колонок в спрайте
    rows: 10           // Строк в спрайте
  }
});

С кастомным постером

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  posterTimecode: '00:02:30'  // Постер с 2:30
});

Без превью и постера

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  generateThumbnails: false,
  generatePoster: false
});

С предварительной проверкой системы

import {
  convertToDash,
  checkFFmpeg,
  checkMP4Box,
  checkNvenc
} from '@grom13/adaptive-video-converter';

// Проверки перед конвертацией
try {
  await checkFFmpeg();
  await checkMP4Box();
  const hasNvenc = await checkNvenc();

  const result = await convertToDash({
    input: './video.mp4',
    outputDir: './output',
    useNvenc: hasNvenc  // Явное указание
  });

  console.log('Успешно!', result.manifestPath);
} catch (error) {
  console.error('Ошибка:', error.message);
}

Последовательное кодирование (без параллелизма)

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  parallel: false  // Медленнее, но меньше нагрузка
});

С кастомными профилями (объектами)

import type { VideoProfile } from '@grom13/adaptive-video-converter';

const customProfiles: VideoProfile[] = [
  {
    name: '720p',
    width: 1280,
    height: 720,
    videoBitrate: '2500k',
    audioBitrate: '128k',
    fps: 30
  },
  {
    name: '1080p',
    width: 1920,
    height: 1080,
    videoBitrate: '5000k',
    audioBitrate: '192k',
    fps: 30
  }
];

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  profiles: customProfiles
});

Обработка ошибок

try {
  const result = await convertToDash({
    input: './video.mp4',
    outputDir: './output'
  });

  console.log('✅ Успешно');
} catch (error) {
  if (error.message.includes('FFmpeg not found')) {
    console.error('FFmpeg не установлен');
  } else if (error.message.includes('MP4Box not found')) {
    console.error('MP4Box не установлен');
  } else if (error.message.includes('File not found')) {
    console.error('Входной файл не найден');
  } else {
    console.error('Ошибка конвертации:', error.message);
  }
}

Поведение по умолчанию

Если не указаны параметры:

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output'
});

Эквивалентно:

const result = await convertToDash({
  input: './video.mp4',
  outputDir: './output',
  segmentDuration: 2,
  codec: 'dual',
  format: 'both',
  useNvenc: true,  // если доступен
  generateThumbnails: true,
  generatePoster: true,
  posterTimecode: '00:00:01',
  parallel: true,
  customProfiles: автовыбор на основе исходного видео
});

Автовыбор профилей

Если profiles и customProfiles не указаны:

Исходное разрешение Выбранные профили
≤ 720p 360p, 480p, 720p
1080p 360p, 720p, 1080p
1440p 720p, 1080p, 1440p
2160p (4K) 1080p, 1440p, 2160p

FPS профилей соответствует исходному видео (максимум 120fps).

Структура вывода

После вызова convertToDash() создается следующая структура:

output/
└── video/
    ├── manifest.mpd          # DASH манифест
    ├── master.m3u8           # HLS мастер-плейлист (если format='hls' или 'both')
    ├── 720p-h264/            # Сегменты профиля
    │   ├── 720p-h264_init.mp4
    │   ├── 720p-h264_1.m4s
    │   └── ...
    ├── 720p-av1/
    ├── 1080p-h264/
    ├── 1080p-av1/
    ├── thumbnails.jpg        # Спрайт превью
    ├── thumbnails.vtt        # WebVTT метки
    ├── poster.jpg            # Постер
    └── conversion.log        # Лог конвертации

См. также