Transcoding — процесс преобразования цифрового медиафайла из одного формата сжатия в другой с полным декодированием и повторным кодированием. В отличие от трансмодуляции (изменения только контейнера), транскодинг изменяет кодек, битрейт, разрешение и другие параметры сжатого потока. По данным Apple AVFoundation documentation (2026), транскодинг используется для адаптации контента под различные устройства и сетевые условия.
Главное
Transcoding — процесс преобразования медиафайла из одного формата сжатия в другой путём полного декодирования исходного потока в промежуточный несжатый PCM-формат и последующего кодирования с новыми параметрами. Если в исходном файле видео сжато кодеком H.264 с битрейтом 10 Мбит/с, а на выходе нужен H.265 с битрейтом 3 Мбит/с — это транскодинг.
Транскодинг отличается от простого перепаковывания (transmuxing), при котором меняется только контейнер (например, MP4 в MKV), а сам сжатый битовый поток остаётся неизменным. При транскодинге происходят вычислительно затратные преобразования: декодирование каждого кадра, применение фильтров (масштабирование, цветокоррекция, обрезка), повторное кодирование с новыми параметрами. Это делает транскодинг одной из самых ресурсоёмких операций при работе с медиа.
Транскодинг применяется в широком спектре задач: адаптация видео под ограничения пропускной способности сети, конвертация в формат с аппаратной поддержкой декодинга на целевом устройстве, создание нескольких версий для HLS/DASH-стриминга, извлечение аудиодорожек в отдельный файл. Сервисы OTT (Netflix, YouTube, Twitch) транскодируют каждый загруженный файл в десятки вариантов с разными битрейтами, разрешениями и кодеками для обеспечения адаптивного стриминга миллионам пользователей.
Процесс транскодинга состоит из трёх основных этапов: декодирование, обработка и кодирование. Каждый этап может быть выполнен как на CPU, так и на GPU/аппаратных блоках в зависимости от доступности и требуемой производительности.
Первый этап — декодирование исходного потока. Исходный файл читается из контейнера (MP4, MOV, MKV), после чего сжатые видеопакеты направляются в декодер. Декодирование может быть аппаратным (если кодек поддерживается) или программным через FFmpeg. На выходе декодирования получаются несжатые кадры в формате YUV420 или BGRA — именно с этой стадии транскодинг отличается от простого ремультиплексирования.
Второй этап — фильтрация и обработка. Декодированные кадры проходят через цепочку фильтров: масштабирование до целевого разрешения, изменение частоты кадров, цветокоррекция, наложение текста или графики. Цепочка фильтров FFmpeg строится как граф, где каждый фильтр — это отдельный модуль обработки. Например, фильтр scale=1280:720 меняет разрешение, fps=30 изменяет частоту кадров, а yadif выполняет деинтерлейсинг. Все операции выполняются над несжатыми кадрами, поэтому второй этап является самым ресурсоёмким.
Третий этап — кодирование в целевой формат. Обработанные кадры подаются на вход энкодеру, который сжимает их по алгоритму целевого кодека. Энкодер может быть аппаратным (VideoToolbox на iOS, MediaCodec на Android) или программным (libx264, libx265). Параметры кодирования: CRF (Constant Rate Factor) для constant quality, битрейт для CBR/VBR, профиль и уровень для совместимости с целевыми устройствами.
// Схема pipeline транскодинга на FFmpeg
AVFormatContext *inputCtx, *outputCtx;
AVCodecContext *decoderCtx, *encoderCtx;
AVFrame *frame = av_frame_alloc();
AVPacket packet;
while (av_read_frame(inputCtx, &packet) >= 0) {
// 1. Decode
avcodec_send_packet(decoderCtx, &packet);
avcodec_receive_frame(decoderCtx, frame);
// 2. Filter (scale + fps change)
sws_scale(swsCtx, frame->data, frame->linesize,
0, frame->height, scaledFrame->data,
scaledFrame->linesize);
// 3. Encode
avcodec_send_frame(encoderCtx, scaledFrame);
avcodec_receive_packet(encoderCtx, &outPacket);
av_interleaved_write_frame(outputCtx, &outPacket);
}
Приведённый pipeline демонстрирует классический цикл транскодинга. Функция av_read_frame читает сжатые пакеты из входного файла, avcodec_send_packet декодирует их в кадры, sws_scale выполняет масштабирование, и avcodec_send_frame кодирует обработанный кадр в выходной формат. Такой трёхэтапный цикл повторяется для каждого кадра или группы кадров (GOP), в зависимости от настроек энкодера.
Разница между транскодингом и трансмодуляцией — одна из самых частых точек путаницы в медиаинженерии. Понимание этой разницы критически важно для выбора правильной стратегии обработки медиа.
| Параметр | Транскодинг | Трансмодуляция |
|---|---|---|
| Что меняется | Кодек, битрейт, разрешение | Контейнер, метаданные |
| Вычислительная нагрузка | Высокая (декодинг + кодинг) | Минимальная (копирование пакетов) |
| Качество | Может ухудшиться (потери генерации) | Без потерь |
| Время выполнения | Минуты–часы для длинного видео | Секунды–минуты |
| Применение | Адаптация формата, сжатие | Изменение контейнера для совместимости |
Трансмодуляция — это перепаковка сжатого потока в другой контейнер без декодирования и повторного кодирования. Если видео уже сжато кодеком H.265 в контейнере MP4, и его нужно поместить в контейнер MOV или MKV — трансмодуляция просто копирует битовые пакеты из одного контейнера в другой. Качество не страдает, время обработки минимально, так как не требуется декодирование кадров. FFmpeg выполняет трансмодуляцию с флагом -codec copy.
Транскодинг же полностью расшифровывает и пересжимает медиапоток. Каждый раз, когда видео проходит через транскодинг, может возникнуть потеря поколения (generation loss) — незначительное ухудшение качества из-за повторного сжатия с потерями. Даже при одинаковом битрейте третье поколение транскодинга обычно хуже первого. Именно поэтому профессионалы рекомендуют хранить мастер-копии в несжатых или минимально сжатых форматах (ProRes, DNxHR) и транскодировать только финальные версии для доставки.
Выбор инструмента транскодинга зависит от платформы, требований к производительности и сценария использования. Для мобильной разработки доступны как нативные API, так и кроссплатформенные библиотеки.
FFmpeg — стандарт де-факто для транскодинга на всех платформах. Командная строка FFmpeg позволяет выполнять практически любые преобразования: смена кодека, изменение битрейта, обрезка, склейка, наложение фильтров. Для мобильных приложений FFmpeg интегрируется через библиотеку libavformat, libavcodec и libavfilter. Пример типичной команды транскодинга: ffmpeg -i input.mp4 -c:v libx265 -crf 23 -c:a aac -b:a 128k output.mp4.
На iOS транскодинг выполняется через AVAssetWriter и AVAssetReader. AVAssetReader декодирует исходный файл, читая несжатые кадры, а AVAssetWriter кодирует их в целевой формат. Этот подход использует аппаратные энкодеры VideoToolbox автоматически, что обеспечивает максимальную производительность. На Android аналогичная функциональность доступна через MediaCodec в паре с MediaExtractor и MediaMuxer — MediaExtractor извлекает сжатые пакеты, MediaCodec декодирует и кодирует, MediaMuxer записывает результат.
Для серверного транскодинга в production-среде используются облачные сервисы: AWS Elemental MediaConvert, Azure Media Services, Google Transcoder API. Эти сервисы автоматически масштабируются под нагрузку, поддерживают все популярные форматы и могут транскодировать один входной файл в десятки выходных вариантов для адаптивного стриминга (HLS, DASH). Для мобильных приложений облачный транскодинг — оптимальное решение, так как он не нагружает устройство пользователя и позволяет подготавливать контент асинхронно.
Рассмотрим практические примеры транскодинга на мобильных платформах с использованием аппаратного ускорения и настройкой ключевых параметров качества.
import AVFoundation
func transcodeVideo(sourceURL: URL, destURL: URL) {
let asset = AVAsset(url: sourceURL)
let preset = AVAssetExportPresetHEVCHighestQuality
AVAssetExportSession(asset: asset, presetName: preset)?
.exportAsynchronously {
switch assetExportSession?.status {
case .completed:
print("Transcoding finished")
case .failed:
print("Error: " + assetExportSession.error.localizedDescription)
default:
break
}
}
// Ручной транскодинг с AVAssetReader + AVAssetWriter
let reader = try AVAssetReader(asset: asset)
let writer = try AVAssetWriter(url: destURL,
fileType: .mp4)
let outputSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.hevc,
AVVideoWidthKey: 1920,
AVVideoHeightKey: 1080,
AVVideoCompressionPropertiesKey: [
AVVideoAverageBitRateKey: 4_000_000,
AVVideoProfileLevelKey: AVVideoProfileLevelH265Main10
]
]
let adaptor = AVAssetWriterInput(
mediaType: .video,
outputSettings: outputSettings
)
writer.add(adaptor)
}
В примере используются два подхода к транскодингу на iOS. AVAssetExportSession — простой способ с предустановками качества (HEVCHighestQuality для H.265). Ручной pipeline через AVAssetReader + AVAssetWriter даёт полный контроль над параметрами: битрейт, профиль, уровень. Параметр AVVideoProfileLevelH265Main10 включает HDR-профиль Main10 с глубиной цвета 10 бит, что важно для современного HDR-контента.
class Transcoder(private val context: Context) {
fun transcodeToHevc(inputUri: Uri, outputFile: File) {
val extractor = MediaExtractor()
extractor.setDataSource(context, inputUri, null)
val trackFormat = extractor.getTrackFormat(videoTrackIndex)
val mime = trackFormat.getString(MediaFormat.KEY_MIME)
val decoder = MediaCodec.createDecoderByType(mime!!)
val encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_HEVC)
val outputFormat = MediaFormat.createVideoFormat(
MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080
).apply {
setInteger(MediaFormat.KEY_BIT_RATE, 4_000_000)
setInteger(MediaFormat.KEY_FRAME_RATE, 30)
setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2)
}
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
encoder.start()
}
}
Код на Android создаёт pipeline из MediaExtractor — MediaCodec decoder — MediaCodec encoder — MediaMuxer. MediaExtractor определяет тип кодека из входного файла и выбирает соответствующий декодер. Энкодер настраивается на H.265 (HEVC) с битрейтом 4 Мбит/с и интервалом ключевых кадров 2 секунды, что оптимально для стриминга. Важно: MediaCodec encoder работает синхронно, поэтому для realtime-транскодинга требуется организовать цикл с корректной обработкой временных меток (PTS) для каждого кадра.
Транскодинг на мобильных устройствах — задача, требующая тщательной оптимизации из-за ограниченных ресурсов CPU, GPU и тепловых ограничений. Несколько стратегий помогают выполнять транскодинг эффективно.
Ключевой фактор производительности — аппаратный энкодер. На iOS VideoToolbox предоставляет аппаратное кодирование H.264 и H.265 со скоростью, в 5–10 раз превышающей программный libx264. На Android MediaCodec использует аппаратные OMX-компоненты, если они доступны. Включение аппаратного кодирования сокращает время транскодинга 10-минутного видео с 30–40 минут (программно) до 3–5 минут (аппаратно) на флагманском устройстве.
Для мобильного транскодинга критически важен баланс между качеством, размером и временем обработки. Для H.265 на мобильных устройствах рекомендуется битрейт 4–8 Мбит/с для 1080p видео с частотой кадров 30 FPS. CRF-режим (Constant Rate Factor) в libx265 позволяет задать качество напрямую, где 23–28 даёт хорошее визуальное качество при умеренном размере файла. Для аппаратных энкодеров используйте CBR-режим с целевым битрейтом, так как CRF аппаратно не поддерживается.
Непрерывный транскодинг на мобильном устройстве вызывает значительный нагрев. За 5–7 минут интенсивного кодирования 4K-видео температура процессора может достичь 50–55 градусов, после чего включается троттлинг. Решение — транскодинг с паузами или понижение частоты кадров до 30 FPS. Если приложение требует массового транскодинга (например, видеоредактор), лучше выполнять обработку батчами по 2–3 минуты с интервалами охлаждения. Для production-сценариев оптимально перенести транскодинг на серверную сторону и использовать облачные сервисы.
Часто задаваемые вопросы
Кодирование (encoding) — сжатие исходных несжатых данных в целевой кодек. Транскодинг включает и декодирование, и кодирование: сначала декодирует существующий сжатый поток, затем кодирует заново. Простое кодирование принимает на вход несжатые данные (например, с камеры), а транскодинг — уже сжатый файл.
Для максимальной совместимости — H.264. Для лучшего сжатия — H.265 (HEVC). Если устройство поддерживает аппаратное кодирование H.265 (iPhone 8+, Android с Snapdragon 845+), оно обеспечивает вдвое меньший размер файла при том же качестве. AV1-кодирование на мобильных устройствах пока слишком медленное даже с аппаратным ускорением.
Строго говоря, транскодинг без потерь невозможен при смене lossy-кодека. Если оба кодека сжаты с потерями, каждое поколение транскодинга ухудшает качество. Lossless-транскодинг возможен только между lossless-форматами (FFV1, H.264 Lossless) или при смене контейнера без перекодирования (transmuxing).
Да, если используются аппаратные декодер и энкодер, а целевое разрешение не превышает 1080p. На устройствах с VideoToolbox (iOS) или MediaCodec (Android) realtime-транскодинг H.264→H.265 возможен с задержкой 1–3 секунды. Для 4K realtime требуется мощный SoC Apple A17 Pro, Snapdragon 8 Gen 2 или выше.
Транскодинг с потерями накапливает артефакты сжатия. Если исходный файл уже был сильно сжат (битрейт 2–3 Мбит/с для 1080p), повторное сжатие удвоит потери. Рекомендуется транскодировать только из мастер-копий с высоким битрейтом (20+ Мбит/с) и использовать CRF 18–23 для минимальных потерь.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также