Запись видео с использованием Qt5.4

Я создаю кроссплатформенное приложение для записи мультимедийных файлов для постоянной обработки. Это основано на унаследованном приложении, и я не могу переписать его, используя альтернативные библиотеки.

Моя текущая проблема заключается в том, что QMediaRecorder явно не сохраняет видеофайл на локальный диск - я временно жестко запрограммировал файл для сохранения как banana.mov в корневую папку пользователя.

При выполнении выходной файл не сохраняется.

Я попытался принудительно установить разрешение, как было предложено здесь и видели, что у других были проблемы с записью из окон, но OSX был хорошо

Среда разработки OSX 10.10 с Qt5.4 (такая же проблема возникает и на компьютере с Windows 8.1, использующем Qt5.3)

Этот код на Github основан на примере с камерой, с дополнительным кодом отладки, добавленным при попытке определить и воспроизвести проблему.

В ходе расследования обнаружены QMediaRecorder::​supportedAudioCodecs и QMediaRecorder::supportedVideoCodecs возвращают пустые списки. Это происходит как в сборке OSX, так и в среде Windows.

Вывод отладки выглядит следующим образом:

Status change SIGNAL 'The recorder is initializing.'
Output location file:~/banana.mov
2015 01 05 14:59:58.111 Number of supported AUDIO Codecs 0
2015 01 05 14:59:58.111 Number of Audio sample rates 0
2015 01 05 14:59:58.111 Number of Video Codecs 0
2015 01 05 14:59:58.111 Number of Video Frame Rates 0
2015 01 05 14:59:58.111 Number of Containers 0
Location Changed SIGNAL 'file:~/banana.mov'
State change SIGNAL 'The recording is requested.'
Recording should have started
2015 01 05 14:59:58.111 Number of supported AUDIO Codecs 0
2015 01 05 14:59:58.111 Number of Audio sample rates 0
2015 01 05 14:59:58.111 Number of Video Codecs 0
2015 01 05 14:59:58.111 Number of Video Frame Rates 0
2015 01 05 14:59:58.111 Number of Containers 0
Status change SIGNAL 'Recording is requested but not active yet.'

У меня такое чувство, что я упускаю что-то действительно очевидное, я просто еще не заметил этого!

изменить 1 Очевидно, что статус Recording is requested but not active yet, а не Recording is active. Сейчас я пытаюсь понять, почему запись не началась.

изменить 2 Пример аудиорекордера записывает и сохраняет аудиофайл. Похоже, что QMediaRecorder не возвращает список доступных аудиокодеков, но QAudioRecorder возвращает список аудиокодеков. Я получаю одинаковые результаты как в Windows 8.1, используя Qt5.3, так и в OSX, используя Qt 5.4.


person Neil Stoker    schedule 05.01.2015    source источник
comment
Просто быстрый тест прямо у меня в голове, вместо того, чтобы использовать ~/blah, вы можете попробовать указать полный путь и посмотреть, что произойдет, например: /home/neil/blah.mov или c:\users\neil\blah.mov Я не знаю, имеет ли это значение, но есть что-то, не связанное с QT, пингующееся в глубине моего мозга по этому поводу.   -  person shawty    schedule 07.01.2015
comment
Это сделало свое дело в примере кода: причитается пинта. Если вы предложите в качестве ответа, я отмечу его как таковой.   -  person Neil Stoker    schedule 07.01.2015


Ответы (2)


Скорее всего, вы смотрите на артефакт, специфичный для ОС, а не на основную проблему с QT.

Я видел эту проблему так много раз в стольких наборах инструментов и фреймворках, что меня пугает, что никто еще не нашел элегантного решения.

Основа проблемы

В большинстве операционных систем реализована какая-то защита критически важных системных файлов.

Под *nix это система прав доступа пользователя/группы, под windows она аналогична, но с подсистемой UAC (User Access Control).

Это сводится к тому, что вы часто не можете просто выбрать произвольное место для записи файлов, не предварительно запросив для этого разрешение от различных API безопасности и механизмов в ОС.

Тогда вторая половина проблемы связана с расширением переменных.

В частности, в * nix символ тильды «~» расширяется оболочкой, чтобы обозначить домашний каталог пользователя.

Когда мы говорим оболочка, мы имеем в виду bash, tch, csh или любую другую среду, в которой вы запускаете приложение.

В этот микс мы также поместим среду рабочего стола, так как большинство вещей, таких как Kde, Gnome, Unity или что-либо еще, имеют какой-то вызов операционной системы, который, когда ему передается «~», знает чтобы преобразовать его в '/home/neil/' или что-то еще, что тоже нужно расширить.

В Windows также есть аналогичная функция, с помощью которой вы можете сделать вызов ОС и сказать: «Привет, мистер операционная система, где хранятся мои пользовательские папки», на что она с радостью ответит чем-то вроде «c:\users\».

Почему проблема проявляется именно так

Просто потому, что, когда вы сами создаете строки пути в своем собственном приложении, вещи часто не передаются этим различным вызовам ОС для расширения и проверки безопасности, вам в значительной степени нужно убедиться, что вы тот, кто их вызывает.

Исключением из этого правила является использование философии *nix небольших инструментов, объединенных для выполнения одной работы. В этом случае вы часто будете передавать результат программе на основе оболочки, которая, поскольку она работает через оболочку, знает, что если она увидит «~», она должна расширить ее.

Поскольку вы используете прямой доступ к файлам, управляя своими собственными путями к файлам, когда вы думали, что пишете в «\home\neil\file.mov», на самом деле вы пытаетесь записать файл с именем «file.mov» в текущую папку, где ваше приложение запускается из папки с именем «~», которой я хочу быть, не существует.

Добавьте к этому тот факт, что многие из этих фреймворков (QT не является исключением) предназначены для того, чтобы скрыть и абстрагироваться от всех уродливых деталей, есть большая вероятность, что они использовали исключение ОС, которое было сгенерировано, когда вы на самом деле пытались записать файл, если бы это было не так, то ваше приложение, скорее всего, рухнуло бы с каким-то диалоговым окном исключений.

Как решить проблему

Есть 3 подхода, которые вы можете предпринять, чтобы смягчить это.

  • 1) Вы можете жестко закодировать пути, то есть вы можете явно сказать, что приложение всегда хранит ваш файл в «/home/neil/videos/blah.mov», однако у этого есть недостаток, заключающийся в том, что каждому пользователю приложения понадобится пользовательская сборка, так как маловероятно, что «person2» будет иметь права на запись в домашнем каталоге «neil».

  • 2) Вы можете встроить функциональность, которая дает пользователю диалоговое окно и спрашивает их, где они хотели бы сохранить файл. Поскольку вы используете что-то вроде QT, это должно быть очень просто, большинство этих наборов инструментов пользовательского интерфейса имеют встроенную функциональность, позволяющую легко представить пользователю такой опыт.

  • 3) Вы можете узнать, есть ли у вашей платформы или базовой ОС какие-либо вызовы для вас, чтобы спросить, кто является текущим пользователем и где находится их домашний каталог, затем вы можете использовать возвращенную информацию для динамического создания статического патча, аналогичного тому, что в вариант 1. Такой подход гарантирует, что приложение автоматически адаптируется к среде независимо от пользователя.

Лично я обычно использую вариант 1 во время разработки, затем, когда разработка завершена, я переключаюсь на номер 2, очень редко я использую номер 3 в программном обеспечении для настольных компьютеров.

Вариант 3 для меня часто используется, когда рассматриваемое приложение предназначено для выполнения одной задачи, такой как преобразование файла для работы с другим процессом или создание некоторого вывода для сервера для отображения на веб-странице и т. д.

Однако для вас прямо сейчас в качестве решения этого вопроса лучше всего подходит вариант 1.

person shawty    schedule 07.01.2015

Чтобы добавить к отличному ответу Шоути, я обнаружил, что Qt не поддерживает запись в Windows http://doc.qt.io/qt-5/qtmultimedia-windows.html

Это может быть полезно https://github.com/kibsoft/QtMEL.

person Fortune    schedule 22.10.2015
comment
Когда вы рекомендуете библиотеку, то вам нужно показать пример кода, как ее можно применить в данном случае. Пожалуйста, отредактируйте свой ответ, включив его. - person Artjom B.; 22.10.2015
comment
Как ни странно, у нас не было проблем с записью в Windows, проблемы вызывала именно OSX. С тех пор проект был отложен, поэтому я не знаю, улучшили ли проблему какие-либо обновления библиотек. (и побочный вопрос заключался в том, что я только что получил уведомление о том, что эта тема была обновлена) -- отредактируйте, чтобы исправить орфографию. На днях я внимательно прочитаю, прежде чем нажать «Сохранить». - person Neil Stoker; 23.01.2016