Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Qt и Phonon  (Прочитано 3849 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Qt и Phonon
« : 03 Июня 2010, 15:11:48 »
здравствуйте, не знаю в чем ошибка, программа не возвращает теги ogg, но проигрывает трек, появляется просто пустое окно.
теги в файле присутствуют.
#include <QApplication>
#include <phonon>
#include <QtGui>
 
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication        app(argc, argv);
    app.setApplicationName("SimplePlayer");
    Phonon::MediaObject media;
    Phonon::AudioOutput ao(Phonon::MusicCategory);
 
    Phonon::createPath(&media, &ao);
 
    QObject::connect(&media, SIGNAL(finished()), &app, SLOT(quit()));
    media.setCurrentSource(Phonon::MediaSource("music/Morcheeba.ogg"));
 
    QStringList MetaData = media.metaData("ARTIST");
               MetaData = media.metaData("ALBUM");
               MetaData = media.metaData("TITLE");
               MetaData = media.metaData("DATE");
 
 
    QLabel lbl(MetaData.join(" "));
    lbl.show();
 
    media.play();
 
 
    return app.exec();
}
ПС: уже задавал этот вопрос на специализирующихся по Qt форумах, но либо там одни м..., или ни кто не знает тему.

Предупреждение за нецензурную лексику!
« Последнее редактирование: 09 Сентября 2010, 23:20:26 от sanb »
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #1 : 03 Июня 2010, 17:49:26 »
Цитировать
QStringList MetaData = media.metaData("ARTIST");
               MetaData = media.metaData("ALBUM");
               MetaData = media.metaData("TITLE");
               MetaData = media.metaData("DATE");
Это как понимать? Если буквально, то в итоге MetaData содержит только информацию о дате. Вернусь с работы попробую натравить твой код на какой нибудь ogg файл посмотрю что выйдет.

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #2 : 03 Июня 2010, 18:50:44 »
насколько я понимаю QStringList это список, можно записать и так:
QStringList MetaData;
               MetaData << media.metaData("ARTIST");
               MetaData << media.metaData("ALBUM");
               MetaData << media.metaData("TITLE");
               MetaData << media.metaData("DATE");
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #3 : 03 Июня 2010, 20:22:44 »
Так можно и в результате список действительно будет содержать всё, а вот в исходном варианте код выглядел странно.

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #4 : 03 Июня 2010, 22:29:04 »
но все равно программа ничего не выводит, просто пустое окно, а файлик проигрывается
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #5 : 03 Июня 2010, 23:07:34 »
Потому что документацию надо по методам которые используешь читать :)
Цитировать
Note that meta data is not resolved before the metaDataChanged() signal is emitted.

соответственно следующий кривой код достаёт мета данные:
#include <QtCore/QObject>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>

#include <QtCore/QtDebug>

#include <Phonon/MediaObject>
#include <Phonon/AudioOutput>
#include <Phonon/MediaSource>

int main(int argc, char** argv) {
    QCoreApplication app(argc, argv);
    app.setApplicationName("SimplePlayer");
    Phonon::MediaObject media;
    Phonon::AudioOutput ao(Phonon::MusicCategory);
 
    Phonon::createPath(&media, &ao);
 
    QObject::connect(&media, SIGNAL(metaDataChanged()), &app, SLOT(quit()));
    media.setCurrentSource(Phonon::MediaSource( app.arguments()[1] ));

    app.exec();
   
    QStringList MetaData = media.metaData(Phonon::ArtistMetaData);
    MetaData << media.metaData(Phonon::AlbumMetaData);
    MetaData << media.metaData(Phonon::TitleMetaData);
    MetaData << media.metaData(Phonon::DateMetaData);
 
    qDebug() << MetaData;
   
    return 0;
}

vestnik@vestnik-laptop:~/Development/tests/Qt4/phonon$ ./phonon "01 - The Illusionist.mp3"
("Scar Symmetry", "Pitch Black Progress", "The Illusionist", "")
vestnik@vestnik-laptop:~/Development/tests/Qt4/phonon$ ./phonon "04 - Natural Hight.ogg"
("HammerFall", "Threshold", "Natural Hight", "2006")

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #6 : 04 Июня 2010, 02:31:25 »
2VestniK:
спасибо большое, наконец получилось :D
Asus X50N Ubuntu 10.04

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #7 : 08 Июня 2010, 16:09:48 »
2VestniK: я не  понимаю когда сигнал metaDataChanged() отсылается???
если он отсылается когда media.metaData() возвратит данные, то зачем он нужен вообще и зачем коннектить его с app.quit()???
или вызывается при добавлении записи в QStringList MetaData....
« Последнее редактирование: 08 Июня 2010, 16:29:02 от HolyMacaroni »
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #8 : 08 Июня 2010, 17:00:00 »
Цитирую самого себя:
Цитировать
соответственно следующий КРИВОЙ код достаёт мета данные:
Я коннекчу metaDataChanged() с app.quit() чтобы задержать выполнение программы до тех пор пока метаданные не будут прочитанны. По хорошему тебе нужно написать класс у которого будет слот который ты законнектишь с этим сигналом и внутри этого слота ты будешь читать метаданные из Phonon::MediaObject и размещать оные на одном из виджов твоего приложения.

Вопрос: Почему метаданные не прочитанны сразу?
Ответ: Qt это в первую очередь библиотека создания графического интерфейса и она максимально заточенна под эти нужды. А хорошее GUI не должно зависать на несколько секунд при выполнении длительных фоновых задач (таких как разбор метаданных мультимедийного файла). Посему в Qt очень многие вещи сделанны асинхронно. Например setCurrentSource() создаёт новый поток в котором будет произведён разбор полётов, а сам мгновенно завершается. В отдельном потоке разбираются метаданные и делается другая необходимая работа, а твой графф интерфейс в своём потоке нормально реагирует на действия пользователя. Оповещения о важных этапах проделанной работы делается асинхронными сигналами. Доставка оных производится через Event Loop (который у каждого потока свой). Даже если метаданные прочитанны и сигнал metaDataChanged() испущен до того как в моём коде вызывается app.exec() на самом деле он лишь добавлен в очередь событий и будет реально доставлен только когда вызов app.exec() состоиться.

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

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #9 : 11 Июня 2010, 16:23:33 »
Цитировать
Посему в Qt очень многие вещи сделанны асинхронно. Например setCurrentSource() создаёт новый поток в котором будет произведён разбор полётов, а сам мгновенно завершается.
спасибо большое, я этого не знал.
Asus X50N Ubuntu 10.04

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #10 : 19 Июня 2010, 17:34:33 »
2VestniK:
я уже наверное тебя забодал со своими вопросами.

(Нажмите, чтобы показать/скрыть)
[/s]

Вот так всегда, формулируешь вопрос и почти на него отвечаешь. :)
« Последнее редактирование: 19 Июня 2010, 17:40:47 от HolyMacaroni »
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #11 : 19 Июня 2010, 18:06:35 »
ответ в документации по: QMetaObject::connectSlotsByName

Там описанна конвенция имёт для автоматического коннекта сигналов. Но лучше для этого случая руками законнекть. Код читабельней будет.

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #12 : 19 Июня 2010, 19:26:40 »
что то очень туго идет, вроде такая простая концепция, но на деле, что то очень сложно :'(

вот листинг, вроде и слот подсоединен к сигналу, но почему то не вызывается слот

mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <phonon>


namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    QStringList MetaData;
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void changeEvent(QEvent *e);

private:
    Ui::MainWindow *ui;

private slots:
    void on_pushButton_clicked();
    void Slot_MainWindow_metaDataChanged();

};

#endif // MAINWINDOW_H


main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setApplicationName("SimplePlayer");
    MainWindow w;

    w.show();
    return a.exec();
}


mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore/QtDebug>
#include <phonon>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::Slot_MainWindow_metaDataChanged()
{
    qDebug() << MetaData;
}

void MainWindow::on_pushButton_clicked()
{
    Phonon::MediaObject media;
    QObject::connect(&media, SIGNAL(metaDataChanged()), this, SLOT(Slot_MainWindow_metaDataChanged()));
    media.setCurrentSource(Phonon::MediaSource("morcheeba.ogg"));

    MetaData << media.metaData(Phonon::ArtistMetaData);
    MetaData << media.metaData(Phonon::AlbumMetaData);
    MetaData << media.metaData(Phonon::TitleMetaData);
    MetaData << media.metaData(Phonon::DateMetaData);

}


Пользователь решил продолжить мысль 19 Июня 2010, 21:06:21:
черт возьми :idiot2: что то сделал, видимо добавил в редакторе ресурсов сигнал и стал вызываться слот,....но только один раз, первый, и когда еще список не заполнен, но он почему то заполняется после, а уже тогда слот не вызывается. Сума сойти можно :idiot2:, не понимаю в чем может быть косяк.

Пользователь решил продолжить мысль 20 Июня 2010, 01:27:05:
сотворил наконец, но что я сделал, иначе как шаманством не назовешь, все равно нуждаюсь в ответе:)
Это кусок кода, on_ScanThisPath_clicked()-слот нажатия кнопочки, MainWindow_slot_MediaData()- слот соединенный с сигналом metaDataChanged()
void MainWindow::on_ScanThisPath_clicked()
{

    media.setCurrentSource(Phonon::MediaSource("morcheeba.ogg"));
    if(MetaData.size()==0)
    {
        MetaData << media.metaData(Phonon::ArtistMetaData);
        MetaData << media.metaData(Phonon::AlbumMetaData);
        MetaData << media.metaData(Phonon::TitleMetaData);
        MetaData << media.metaData(Phonon::DateMetaData);
    }


    if(MetaData.size()!=0) MyPrintMetaData();
}

void MainWindow::MyPrintMetaData(){qDebug() << MetaData;};
void MainWindow::MainWindow_slot_MediaData()
{
GettingMetaDataYesNo=1;
on_ScanThisPath_clicked();
}

« Последнее редактирование: 20 Июня 2010, 03:29:34 от HolyMacaroni »
Asus X50N Ubuntu 10.04

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #13 : 20 Июня 2010, 15:23:45 »
Цитировать
void MainWindow::on_pushButton_clicked()
{
    Phonon::MediaObject media;
    QObject::connect(&media, SIGNAL(metaDataChanged()), this, SLOT(Slot_MainWindow_metaDataChanged()));
    media.setCurrentSource(Phonon::MediaSource("morcheeba.ogg"));

    MetaData << media.metaData(Phonon::ArtistMetaData);
    MetaData << media.metaData(Phonon::AlbumMetaData);
    MetaData << media.metaData(Phonon::TitleMetaData);
    MetaData << media.metaData(Phonon::DateMetaData);
}
Переменная media локальная в этой функции и будет уничтожена по выходу из неё, заведомо до того как метаданные будут прочитанны. Это раз.

Ты опять читаешь мета данные сразу же после media.setCurrentSource(Phonon::MediaSource("morcheeba.ogg")); а не в void MainWindow::Slot_MainWindow_metaDataChanged(). Поэтому ты ничего не получаешь. Это два.

Возьми исходный вариант, добавь в класс приватную переменную "Phonon::MediaObject media" (хотя, судя по последующему куску кода это ты уже сделал). Потом этот блок:
    MetaData << media.metaData(Phonon::ArtistMetaData);
    MetaData << media.metaData(Phonon::AlbumMetaData);
    MetaData << media.metaData(Phonon::TitleMetaData);
    MetaData << media.metaData(Phonon::DateMetaData);
перенеси в Slot_MainWindow_metaDataChanged(). и всё будет работать как положенно.
« Последнее редактирование: 20 Июня 2010, 15:28:53 от VestniK »

Оффлайн HolyMacaroni

  • Автор темы
  • Участник
  • *
  • Сообщений: 210
  • мегавольт
    • Просмотр профиля
Re: Qt и Phonon
« Ответ #14 : 21 Июня 2010, 02:08:53 »
VestniK миллион извинений, я тугоум.
а как же дождаться сигнала после media.setCurrentSource(Phonon::MediaSource("morcheeba.ogg"));, если например я хочу в цикле получать метаданные

Пользователь решил продолжить мысль 21 Июня 2010, 12:22:07:
Получилось с помощью QEventLoop::exec()/quit(), но не совсем понимаю механизм работы :) шито пугает
« Последнее редактирование: 21 Июня 2010, 14:24:25 от HolyMacaroni »
Asus X50N Ubuntu 10.04

 

Страница сгенерирована за 0.07 секунд. Запросов: 25.