LINUX.ORG.RU

Как правильно использовать QMediaMetaData для определения параметров медиафайлов?

 , ,


0

1

Здравствуйте! Подскажите, как мне определить параметры аудиофайла без подключения внешних библиотек MediaInfo при помощи встроенных в Qt инструментов, таких, как QMediaMetaData: битрейт, частоту дискретизации, битовую глубину, формат. Мне нужно получить эти параметры из существующего файла для последующего перекодирования аудиофайла в другой формат. Я пытался использовать QMediaMetaData таким образом (при том не знаю правильно ли я использовал так же QMediaObject):

#include <QtMultimedia/QMediaMetaData>
#include <QtMultimedia/QMediaObject>
#include "mainwindow.h"
#include "ui_mainwindow.h"
.
.
.
void MainWindow::on_pushButton_1_clicked()
{
   QMediaObject mediafile; // Здесь определяю медиаобъект
   QString file_name = "/run/media/helg/WDC/test.aac"; // Путь к медиафайлу   
   mediafile.setMedia(QUrl(file_name));// Привязываю путь до медиаобъекта
   QString bitrate = mediafile.metaData(QMediaMetaData::AudioBitRate).toString(); // Определяю битрейт медиаобъекта
   // Далее идет обработка переменных bitrate и т.д.
   .
   .
}
.
.
.

На данном этапе программа естественно выдает ошибки на этапе компиляции, я даже не уверен на правильном ли я пути.



Последнее исправление: Oleg1980 (всего исправлений: 4)

QAudioDecoder decoder;
decoder.setSourceFilename("test.mp3");
if(decoder.isMetaDataAvailable())
{
  auto metaDataKeys=decoder.availableMetaData();
...
//проверить только доступные ключи
auto data=decoder.metaData(metaDataKeys[0]);

}

P.S Код не проверял, нет под рукой qt.Не забудь в проекте подключить QT += multimedia

CrazyAlex25 ★★★
()
Последнее исправление: CrazyAlex25 (всего исправлений: 2)
Ответ на: комментарий от Oleg1980

https://doc.qt.io/qt-5/qmediametadata.html decoder.metaData(QMediaMetaData::AudioBitRate);

decoder.availableMetaData() вернет только доступные значения QMediaMetaData. Например если у mp3 запросить VideoBitRate то я незнаю что будет (предположу что вернет 0).


 auto metaDataKeys=decoder.availableMetaData();
...
//проверить только доступные ключи
for(int i=0;i<metaDataKeys.size();i++)
{
  auto data=decoder.metaData(metaDataKeys[i]);
qDebug() << "param " << metaDataKeys[i] << "="<< data;

}

CrazyAlex25 ★★★
()
Последнее исправление: CrazyAlex25 (всего исправлений: 1)
Ответ на: комментарий от CrazyAlex25

Сейчас попробовал, почему-то нет доступных метаданных metaDataKeys.size() = 0 и условие не выполняется. Пробовал для нескольких аудио файлов. Не понимаю почему.

Может быть в этой строке собака зарыта: decoder.setSourceFilename(file_qstr); здесь у мня file_qstr имет тип QString.

Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 1)
Ответ на: комментарий от CrazyAlex25
decoder.setSourceFilename(file_qstr);
decoder.start();
int error = decoder.error();
auto metaDataKeys = decoder.availableMetaData();
std::cout << "MetaDataKeys size: " << metaDataKeys.size() << std::endl;
std::cout << "Decoder error: " << error << std::endl;

Вывод терминала:

MetaDataKeys size: 0
Decoder error: 0

Ничего понять не могу…

Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 3)
Ответ на: комментарий от CrazyAlex25

Попробовал так, но тоже выдает ноль при запросе количества элементов в списке метаданных:

#include <QtMultimedia/QMediaMetaData>
#include <QtMultimedia/QMediaPlayer>

auto media_info = new QMediaPlayer();
media_info->setMedia(QUrl::fromLocalFile(file_qstr)); // file_qstr это путь к файлу в формате QString
QStringList metadatalist = media_info->availableMetaData();
int list_size = metadatalist.size();
std::cout << "List size: " << list_size << std::endl;

Это уже верняк должен был быть, но почему-то не работает.

List size: 0
Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 4)
Ответ на: комментарий от Oleg1980

Единственое что я нашёл это https://doc.qt.io/qt-5/audiooverview.html

QAudioFormat desiredFormat;
desiredFormat.setChannelCount(2);
desiredFormat.setCodec("audio/x-raw");
desiredFormat.setSampleType(QAudioFormat::UnSignedInt);
desiredFormat.setSampleRate(48000);
desiredFormat.setSampleSize(16);

QAudioDecoder *decoder = new QAudioDecoder(this);
decoder->setAudioFormat(desiredFormat);
decoder->setSourceFilename("level1.mp3");

connect(decoder, SIGNAL(bufferReady()), this, SLOT(readBuffer()));
decoder->start();

// Now wait for bufferReady() signal and call decoder->read()

Но докуметация на QAudioDecoder говорит что если не указывать формат, то он будет взят из файла. А вот почему доступная метадата пустая вот это вопрос. Может в файле её и нет?

CrazyAlex25 ★★★
()
Ответ на: комментарий от CrazyAlex25
#include <QtMultimedia/QAudioDecoder>
#include <QtMultimedia/QMediaMetaData>
.
.
.
QAudioDecoder *decoder = new QAudioDecoder(this);
decoder->setSourceFilename(file_qstr);
decoder->start();
int error = decoder->error();
auto metaDataKeys = decoder->availableMetaData();
std::cout << "MetaDataKeys size: " << metaDataKeys.size() << std::endl;
std::cout << "Decoder error: " << error << std::endl;

То же самое, по нулям выдает:

MetaDataKeys size: 0
Decoder error: 0

почему доступная метадата пустая вот это вопрос. Может в файле её и нет?

Я уже разые файлы пробовал

Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 3)
Ответ на: комментарий от CrazyAlex25

Сегодня с форума Qt мне сказали, что надо через сигналы ‘mediaStatus()’ и ‘error()’ о завершении загрузки и через слоты подключаться, ну это полная засада конечно… У меня там может не один, а сразу несколько файлов загружаться и для каждого нужны сведения о метаданных, а если через сигналы это делать, то не знаю. Может через что-то другое тогда проще реализовать это.

Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 2)
Ответ на: комментарий от CrazyAlex25

В итоге решил через MediaInfo делать, но тоже началось:

#include <MediaInfo/MediaInfo.h>   
#define MediaInfoNameSpace MediaInfoLib;   
#define _itot itoa   
#include "mainwindow.h"   
#include "ui_mainwindow.h"   

using namespace MediaInfoNameSpace;
.
.
.   

MediaInfoLib::MediaInfo MI;   
MI.Open(file_str);   
auto codec=MI.Get(stream_t::Stream_Audio, 0, "Format");
std::cout << "Codec :" << codec << std::endl;   
MI.Close();
.
.
.

На этот раз при компиляции вылетает ошибка: error: undefined reference to `MediaInfoLib::MediaInfo::MediaInfo()’

Oleg1980
() автор топика
Последнее исправление: Oleg1980 (всего исправлений: 2)
Ответ на: комментарий от Oleg1980

А сколько минут ты пробовал искать ответ сам?

P.S. Есть как бы сакральные знания редких или плохо документированных технологий, и есть базовые, которые необходимо знать и понимать разработчику. Твой вопрос касается второго.

anonymous8 ★★
()
Последнее исправление: anonymous8 (всего исправлений: 1)
Ответ на: комментарий от Oleg1980

Всё правильно тебе говорят. Прочитай школьный учебник по С++.

Решение на

undefined reference to `MediaInfoLib::MediaInfo::MediaInfo()’

это добавить -lmediainfo

g++ test.cpp -lmediainfo -DUNICODE

https://sourceforge.net/p/mediainfo/discussion/297610/thread/93fc6cd8/

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)
Ответ на: комментарий от anonymous8

Глупый ты. Драйвера в виде устанавливаются без мс-учетки, да и для обновлений регистрация не нужна.

anonymous
()
Ответ на: комментарий от anonymous

Так мне оффтопик, кроме как для гамесов, и не интересен вовсе. Я не работаю с ней. А еула там такая огороженная, что я не можу её принять. Я ж не могу себе врать.

anonymous8 ★★
()
26 октября 2021 г.
Ответ на: комментарий от Oleg1980

В итоге решил через MediaInfo делать

На мой взгляд, если ты уже используешь в проекте Qt, тащить туда ещё и стороннюю библиотеку для того, что в Qt есть — это перебор. Разобрался бы всё-таки с исходным вариантом.

Что тебе с сигналами и слотами не понравилось?

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

Упс, не заметил, что уже месяц прошёл, а автор давно не появлялся на ЛОРе. Тем не менее, посоветовал бы подумать над написанным выше.

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.