Russian Qt Forum
Сентябрь 24, 2024, 10:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Phonon не воспроизводит больше одного аудиофайла...  (Прочитано 5153 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Июнь 26, 2012, 16:38 »

Нужно в программе по событиям для определенных объектов воспроизводить заданные заранее звуки.
Звуки находятся в папке ~sounds (сейчас три wav и 1 mp3,но дальше будет намного больше).
Я хочу, что бы при загрузке создавались media объекты, привязывались к нужным файлам, а потом при возникновении нужного события они проигрывались.

Вот привожу код:
Код:
#ifndef CSOUNDSERVER_H
#define CSOUNDSERVER_H

#include <QObject>
#include <phonon>
#include "cec.h"
#include "csoundalertitem.h"

class CSoundServer : public QObject
{
    Q_OBJECT

    Phonon::AudioOutput *   audioOutput;                    //устройсто вывода звука
    QString ffilePath;                                      //путь к звуковым файлам
    QHash<QString,Phonon::MediaObject*> fsoundFileHash;     //хеш медиаобъектов (ссылки на файлы)
    QHash<QString,QString>              falertLinkToFileHash;   //хеш ссылок objectId:alertRole -> fileName

public:

    explicit    CSoundServer(QObject *parent = 0);
                ~CSoundServer();

    void        setAlerts(CEcMap    &ecMap, const CSoundAlertItemList & alerts);
    const   QString &   filePath()  const;

public slots:

    void        playAlert(QString alertRole);   //проиграть алерт
    void        clear();

private slots:

    void        stateChange(Phonon::State newstate, Phonon::State oldstate);
   
};

#endif // CSOUNDSERVER_H

Код:
#include "csoundserver.h"
#include "crailobject.h"
#include "cec.h"
#include <QDir>

static  const   QString linkTemplate = QString("%1:%2:%3");

CSoundServer::CSoundServer(QObject *parent) :
    QObject(parent)
{
    audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); //через это устройство будет звук

    QDir    dir = QDir::current();
    dir.cdUp();
    if(!dir.cd("sounds"))
    {
        dir = QDir::home();
        if(dir.cd("sounds"))
        {
            ffilePath = dir.absolutePath();
        }
    }
    else
        ffilePath = dir.absolutePath();

    if(ffilePath.isEmpty())
        qDebug("Dir 'sounds' not found. Sound alerts woun't works");
}

CSoundServer::~CSoundServer()
{
    clear();
}

void CSoundServer::setAlerts(CEcMap    &ecMap, const CSoundAlertItemList &alerts)
{
    clear();

    if(ecMap.isEmpty()) return;

    QString         fileName;
    QString         alertRole;
    CRailObject *   railObject;
    CEC         *   ec;
    QString         realFileName;
    QString         linkId;


    foreach(CSoundAlertItem alertItem, alerts)  //проходимся по всем алертам загруженым с файла
    {
        fileName = alertItem.fileName();
        alertRole = alertItem.alertRole();

        ec = ecMap.value(alertItem.ecId(),NULL);
        if(!ec) continue;

        railObject = ec->fieldObjectsHash().value(alertItem.objectId(),NULL);
        if(!railObject)
        continue;       //игнорируем алерт

        if(alertRole.isEmpty()) //если не указан алерт
        {
            qDebug("Alert role for %s:%s hasn't defined",
                   qPrintable(railObject->objectId()),
                   qPrintable(railObject->name));
            continue;       //игнорируем
        }

        if(fileName.isEmpty())  //если не указано имя файла
        {
            qDebug("Alert for %s:%s:%s has no sound filename",
                   qPrintable(railObject->objectId()),
                   qPrintable(railObject->name),
                   qPrintable(alertItem.alertRole()));
            continue;       //игнорируем
        }

        if(!fsoundFileHash.contains(fileName))
        {
            realFileName = ffilePath+"/"+fileName;  //создаем полный путь к файлу

            if(QFile::exists(realFileName)) //проверяем, существует ли такой файл вообще, если да, то:
            {
                Phonon::MediaObject *   mediaObject =   new Phonon::MediaObject;    //создаем медиа объект
                mediaObject->setCurrentSource(Phonon::MediaSource(realFileName));   //задаем имя файла
                Phonon::createPath(mediaObject, audioOutput);                       //соединяем с выходом
                fsoundFileHash.insert(fileName,mediaObject);                        //добавляем его в хеш
            }
            else    //иначе если файла нет
            {
                qDebug("File %s not found, ignoring",
                   qPrintable(realFileName));
            }
        }
        //создаем ссылку между алертом конкретного объекта и именем файла на который он указывает
        linkId = linkTemplate.arg(railObject->parentEC()->id).arg(railObject->objectId()).arg(alertItem.alertRole());
        falertLinkToFileHash.insert(linkId,fileName);
    }
}

const QString &CSoundServer::filePath() const
{
    return  ffilePath;
}

#if 0
void CSoundServer::playFile(QString fileName)
{
    mediaObject->setCurrentSource(Phonon::MediaSource(fileName));
    Phonon::createPath(mediaObject, audioOutput);
    mediaObject->play();
}

void CSoundServer::setFile(QString fileName)
{
    if(fileName.isEmpty())  return;
    if(ffileName!=fileName)
    {
        ffileName = fileName;
        mediaObject->setCurrentSource(Phonon::MediaSource(fileName));
        Phonon::createPath(mediaObject, audioOutput);
    }
}
#endif

void CSoundServer::playAlert(QString alertRole)
{
    CRailObject *   railObject = qobject_cast<CRailObject*>(sender());
    if(railObject)
    {
        QString linkId = linkTemplate.arg(railObject->parentEC()->id).arg(railObject->objectId()).arg(alertRole);
        QString fileName = falertLinkToFileHash.value(linkId);
        if(!fileName.isEmpty())
        {
            Phonon::MediaObject *   mediaObject = fsoundFileHash.value(fileName,NULL);
            if(mediaObject)
            {
                mediaObject->play();
            }
        }
    }
}

void CSoundServer::clear()
{
    foreach(Phonon::MediaObject *   mediaObject, fsoundFileHash.values())
    {
        delete  mediaObject;
    }
    fsoundFileHash.clear();
    falertLinkToFileHash.clear();
}

void CSoundServer::stateChange(Phonon::State newstate, Phonon::State oldstate)
{
    Q_UNUSED(newstate)
    Q_UNUSED(oldstate)
}

При загрузке когфигурации звуковых событий, проигрывается только первый загурженный файл, а в консоли пишется следующее:

Setting new source
New source:  QUrl( "file:///home/anton/sounds/federalg.mp3" ) 
Setting new source
New source:  QUrl( "file:///home/anton/sounds/ring.wav" ) 
WARNING: Phonon::createPath: Cannot connect  Phonon::MediaObject ( no objectName ) to  Phonon::AudioOutput ( no objectName ).
Setting new source
New source:  QUrl( "file:///home/anton/sounds/bigbell.wav" ) 
WARNING: Phonon::createPath: Cannot connect  Phonon::MediaObject ( no objectName ) to  Phonon::AudioOutput ( no objectName ).


Я так понимаю все файлы воспроизводить через одно QAudioDevice. Или для каждого файла нужна своя копия QAudioDevice?
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #1 : Июнь 26, 2012, 23:25 »

Код
C++ (Qt)
Phonon::MediaObject *   mediaObject =   new Phonon::MediaObject;    //создаем медиа объект
Phonon::createPath(mediaObject, audioOutput);                       //соединяем с выходом
из void CSoundServer::setAlerts(CEcMap    &ecMap, const CSoundAlertItemList &alerts) перенеси в конструктор, и соотеветственно Phonon::MediaObject *   mediaObject сделай закрытым членом класса. И, в теории, должно заработать.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Июнь 27, 2012, 13:34 »

у меня похоже утечка памяти при проигрывании файлов.
прога постепенно увеличивает потребление памяти, и за ночь съела почти всю. сейчас закомментировал проигрывание, и утечки уже нет.
как быть? звук позарез нужен
Записан
Bepec
Гость
« Ответ #3 : Июнь 27, 2012, 13:35 »

Я б вообще посоветовал QSound Веселый Если пара - тройка файлов на оповещение, то смысла в фононе не особо вижу.

Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #4 : Июнь 27, 2012, 14:15 »

у меня похоже утечка памяти при проигрывании файлов.
прога постепенно увеличивает потребление памяти, и за ночь съела почти всю. сейчас закомментировал проигрывание, и утечки уже нет.
как быть? звук позарез нужен
Минимально компилируемый проект с использованием CSoundServer предоставь. Либо действительно QSound или монстроиодный vlc используй.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Июнь 27, 2012, 14:19 »

QSound звука не выдает, я так понял нужно ставить Network Audio system?
на vlc ругается, и зука не дает
Записан
Bepec
Гость
« Ответ #6 : Июнь 27, 2012, 14:23 »

Кхм. Пожалуйте сюда и выложите как на духу - что за операционная система, какая версия у вас Qt и да, минимально компилируемый пример в студию.

PS QSound вообще примитив, если он не играет, значит у вас что-то где-то не того.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #7 : Июнь 27, 2012, 14:26 »

Вот что выдаёт.
Убунта 12.4 32бит, Qt 4.8.1
Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString)
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
QDBusConnection: session D-Bus connection created before QCoreApplication. Application may misbehave.
kbuildsycoca4 running...
WARNING: bool Phonon::FactoryPrivate::createBackend() phonon backend plugin could not be loaded
WARNING: bool Phonon::FactoryPrivate::createBackend() phonon backend plugin could not be loaded
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
ALSA lib pcm_dsnoop.c:551:(snd_pcm_dsnoop_open) The dsnoop plugin supports only capture stream
ALSA lib pcm_dsnoop.c:551:(snd_pcm_dsnoop_open) The dsnoop plugin supports only capture stream
ALSA lib pcm_dsnoop.c:612:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
ALSA lib pcm_dsnoop.c:551:(snd_pcm_dsnoop_open) The dsnoop plugin supports only capture stream
ALSA lib pcm_dsnoop.c:612:(snd_pcm_dsnoop_open) unable to open slave
WARNING: bool Phonon::FactoryPrivate::createBackend() phonon backend plugin could not be loaded
WARNING: Phonon::createPath: Cannot connect  Phonon::MediaObject ( no objectName ) to  Phonon::AudioOutput ( no objectName ).

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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