Введение
Статья 471 кратко использовала QMediaRecorder для записи видео — в этой статье разберём его подробнее, включая настройку конкретных кодеков и контейнерных форматов, а также общий принцип транскодирования (преобразования из одного формата/кодека в другой).
Концепция
QMediaRecorder отвечает за кодирование захватываемого аудио/видеопотока (от QMediaCaptureSession, статья 471) в конкретный, сжатый формат и сохранение результата в файл — настраивается через QMediaFormat, определяющий контейнер (контейнерный формат файла, например MP4 или WebM, определяющий, как разные потоки данных упаковываются вместе) и отдельно кодеки для видео- и аудиопотока (например, H.264 для видео, AAC для звука) внутри этого контейнера. Транскодирование — процесс преобразования уже существующего медиафайла из одного формата/кодека в другой (например, для совместимости с конкретным устройством или для уменьшения размера файла) — для Qt Multimedia это требует совмещения декодирования через QMediaPlayer с последующим повторным кодированием, либо использования внешнего инструмента (статья 477, FFmpeg) для более полного контроля над процессом.
Пример кода
// Настройка конкретного формата записи через QMediaFormat
#include <QMediaRecorder>
#include <QMediaFormat>
void configureRecorder(QMediaRecorder *recorder)
{
QMediaFormat format;
format.setFileFormat(QMediaFormat::MPEG4); // контейнер MP4
format.setVideoCodec(QMediaFormat::VideoCodec::H264);
format.setAudioCodec(QMediaFormat::AudioCodec::AAC);
recorder->setMediaFormat(format);
recorder->setQuality(QMediaRecorder::HighQuality);
recorder->setVideoResolution(1920, 1080);
recorder->setVideoFrameRate(30);
}
// Проверка реально поддерживаемых комбинаций контейнера/кодеков на конкретной системе
void printSupportedFormats(QMediaRecorder *recorder)
{
const QList<QMediaFormat::FileFormat> containers = recorder->mediaFormat().supportedFileFormats(QMediaFormat::Encode);
for (auto container : containers) {
QMediaFormat testFormat;
testFormat.setFileFormat(container);
qDebug() << "Контейнер:" << QMediaFormat::fileFormatName(container);
for (auto codec : testFormat.supportedVideoCodecs(QMediaFormat::Encode)) {
qDebug() << " Видеокодек:" << QMediaFormat::videoCodecName(codec);
}
}
}
Пояснения к коду
configureRecorder показывает явную настройку всех ключевых параметров записи — комбинация MP4-контейнера с H.264-видео и AAC-звуком выбрана как одна из наиболее широко поддерживаемых и совместимых комбинаций для большинства современных устройств воспроизведения, хотя конкретный выбор должен учитывать реальные требования совместимости приложения. printSupportedFormats показывает важный практический паттерн — перебор реально поддерживаемых на текущей, конкретной системе комбинаций контейнера и кодеков, что особенно важно, поскольку (аналогично подводному камню статьи 467 про аудиоформаты) реальная поддержка зависит от установленного мультимедийного бэкенда конкретной системы, и попытка использовать неподдерживаемую комбинацию без предварительной проверки может привести к неожиданной ошибке записи.
Подводные камни
- Жёсткая, не проверяемая программно настройка конкретного кодека без учёта возможного отсутствия его поддержки на целевой системе — приложение, протестированное на разработческой машине с полным набором установленных кодеков, может столкнуться с ошибкой записи на системе пользователя без поддержки выбранного, изначально захардкоженного кодека; для надёжного поведения стоит либо проверять поддержку через
supportedVideoCodecs()/supportedAudioCodecs()перед записью, либо предусмотреть осмысленную обратную связь пользователю при неудачной попытке. - Выбор избыточно высокого качества/битрейта записи без учёта реальных требований приложения и доступного места на диске —
QMediaRecorder::HighQualityдля длительной записи видео в высоком разрешении может генерировать файлы значительного размера за единицу времени, и для приложений с длительной записью (например, видеонаблюдение) выбор качества должен явно балансировать визуальное качество с практическими ограничениями по объёму сохраняемых данных. - Попытка транскодирования через простое декодирование
QMediaPlayerи повторное кодированиеQMediaRecorderбез понимания, что Qt Multimedia API не предназначен изначально именно для пакетного, программного транскодирования файлов — этот API ориентирован на запись в реальном времени от живого источника захвата (камеры/микрофона), и для надёжного, эффективного транскодирования уже существующих файлов специализированные инструменты (FFmpeg, статья 477) обычно дают значительно больший контроль и эффективность по сравнению с обходным путём через декодирование-перезахват-перекодирование средствами Qt Multimedia. - Игнорирование того, что некоторые комбинации кодеков лицензионно ограничены (особенно H.264 в некоторых юрисдикциях/конфигурациях для коммерческого использования без соответствующей лицензии) — перед выбором конкретного кодека для коммерческого, распространяемого приложения стоит проверить лицензионные условия использования этого кодека в конкретном юридическом и коммерческом контексте, особенно для кодеков, не являющихся полностью свободными от патентных ограничений (в отличие, например, от открытых, свободных от патентных проблем альтернатив, как VP9/AV1 для видео).