Audio duration for file manager



  • Hello!
    I tried to get audio data (duration) for my file manager without using phonon. It is possible to write only for one file. However in console I get all durations from directory.

    Here is the part of my code where I am trying to get the data. How to get those datas for all files in the directory?

      void MainWindow::CreateTable(const QString & p) {
      filemodel->removeRows( 0, filemodel->rowCount() );
    
    
    filemodelcurrentdir = QDir(p).path();
    files = QDir(p).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    foreach(const QFileInfo &fi, files) {
        QString name = QString("%0").arg(fi.fileName());
        filemodel->insertRow(0);
        if (fi.isDir()) {
            filemodel->setData(filemodel->index(0, 0), name);
            filemodel->setData(filemodel->index(0, 0), dirIcon, Qt::DecorationRole);
        } else {
            filemodel->setData(filemodel->index(0, 0), name);
            filemodel->setData(filemodel->index(0, 0), fileIcon, Qt::DecorationRole);
            }
        filemodel->setData(filemodel->index(0, 1), size_human(fi.size()));
    
       QMediaPlayer* player = new QMediaPlayer();
    
        player->setMedia(QUrl::fromLocalFile(filemodelcurrentdir + "/" + name));
    
        double dura;
    
        connect(player, &QMediaPlayer::durationChanged, this, [&](qint64 dur) {
            dura = static_cast<double>(dur)/60000.0;
                  qDebug() << "duration = " << dura;
        });
    
        filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));
        delete player;
    
    
    }
    
    
    filemodel->setHeaderData(0,Qt::Horizontal,QObject::tr("Name" ));
    filemodel->setHeaderData(1,Qt::Horizontal,QObject::tr("Size" ));
    filemodel->setHeaderData(2,Qt::Horizontal,QObject::tr("Duration" ));
    
    pTreeView2->setSortingEnabled(true);
    pTreeView2->setColumnWidth(0, 300);
    pTreeView2->setColumnWidth(1, 100);
    pTreeView2->setColumnWidth(2, 100);
    
      }
    

    Thank you very much!


  • Lifetime Qt Champion

    Hi,

    Something is not clear with your question. On one side you state that you want to do it for only one file and then for all files in a folder.

    What is the case that you want to achieve ?



  • I want to do this for all files in the folder. I want to see in the 3rd column the duration of the audio files. The written code only does this for 1 file (added to the 3rd column). The duration of the remaining files in this column is 0. The console shows the duration of all files. I need the result not in the console but in the 3rd column.


  • Qt Champions 2018

    @Nemooo said in Audio duration for file manager:

    filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));

    You you should do this inside lambda connected to durationChanged, else dura will be 0.0 when you do:

    filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));
    

    dura is changed when the slot is called, but you already use it just after calling connect.

    You have a memory leak (you don't delete QMediaPlayer instances you're creating in a loop!).



  • @jsulm said in Audio duration for file manager:

    @Nemooo said in Audio duration for file manager:

    filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));

    You you should do this inside lambda connected to durationChanged, else dura will be 0.0 when you do:

    filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));
    

    dura is changed when the slot is called, but you already use it just after calling connect.

    You have a memory leak (you don't delete QMediaPlayer instances you're creating in a loop!).

    Thank you!
    I did this file inside lambda

    filemodel->setData(filemodel->index(0, 2), QString().setNum(dura));
    

    and still it doesn't work. I deleted QMediaPlayer, just erased this line by accident.


  • Qt Champions 2018

    @Nemooo said in Audio duration for file manager:

    and still it doesn't work

    Probably because when the slot is called you already added another line on top...



  • @jsulm said in Audio duration for file manager:

    @Nemooo said in Audio duration for file manager:

    and still it doesn't work

    Probably because when the slot is called you already added another line on top...

    I tried to change the order. First I called the slot, then I added lines. Still doesn't work.


  • Qt Champions 2018

    @Nemooo said in Audio duration for file manager:

    First I called the slot

    You don't call the slot, the slot is called when the signal is emitted...



  • @jsulm
    Ok! Yes, emitted signal - > slot called - > still doesn't work


  • Qt Champions 2018

    @Nemooo Just to clarify: you don't know when exactly the signal will be emitted. This is done by QMediaPlayer, not by you. So, you do not know in which order the signals will be emitted. It can work like you're doing. You should pass an additional parameter to the slot to tell it which line/index to update.



  • @jsulm said in Audio duration for file manager:

    @Nemooo Just to clarify: you don't know when exactly the signal will be emitted. This is done by QMediaPlayer, not by you. So, you do not know in which order the signals will be emitted. It can work like you're doing. You should pass an additional parameter to the slot to tell it which line/index to update.

    Thank you! Could you please show me the example how to do it. I am new in Qt so I don't know how to do it.
    Thank you!


  • Qt Champions 2018

    @Nemooo Something like (not really Qt specific):

    auto index = filemodel->index(0, 2);
    connect(player, &QMediaPlayer::durationChanged, this, [this, index](qint64 dur) {
            dura = static_cast<double>(dur)/60000.0;
            qDebug() << "duration = " << dura;
            filemodel->setData(index, QString().setNum(dura));
        });
    


  • @jsulm said in Audio duration for file manager:

    @Nemooo Something like (not really Qt specific):

    auto index = filemodel->index(0, 2);
    connect(player, &QMediaPlayer::durationChanged, this, [this, index](qint64 dur) {
            dura = static_cast<double>(dur)/60000.0;
            qDebug() << "duration = " << dura;
            filemodel->setData(index, QString().setNum(dura));
        });
    

    Now I understand what you mean but it still doesn't work


  • Qt Champions 2018

    @Nemooo said in Audio duration for file manager:

    Now I understand what you mean but it still doesn't work

    Then please debug the code and find out where the problem is.


  • Qt Champions 2018

    @Nemooo I think the problem is that index changes as you're inserting new rows. You need to find a way to make sure you're using the correct index. Or you first fill in all rows into your model and then use QMediaPlayer.



  • @jsulm said in Audio duration for file manager:

    @Nemooo I think the problem is that index changes as you're inserting new rows. You need to find a way to make sure you're using the correct index. Or you first fill in all rows into your model and then use QMediaPlayer.

    Yes, I feel, that mistake is somewhere in wrong index but I cannot catch how.
    I did in a different ways. No chance.

    May be you know how can I get information about duration in mp3 file in different ways?


  • Qt Champions 2018

    @Nemooo "Or you first fill in all rows into your model and then use QMediaPlayer." - what about this suggestion?



  • @jsulm said in Audio duration for file manager:

    @Nemooo "Or you first fill in all rows into your model and then use QMediaPlayer." - what about this suggestion?

    Tried to do this way

    void MainWindow::CreateTable(const QString & p) {
    filemodel->removeRows( 0, filemodel->rowCount() );
    
    
    filemodelcurrentdir = QDir(p).path();
    files = QDir(p).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    foreach(const QFileInfo &fi, files) {
        QString name = QString("%0").arg(fi.fileName());
    
    
    
        filemodel->insertRow(0);
        if (fi.isDir()) {
            filemodel->setData(filemodel->index(0, 0), name);
            filemodel->setData(filemodel->index(0, 0), dirIcon, Qt::DecorationRole);
        } else {
            filemodel->setData(filemodel->index(0, 0), name);
            filemodel->setData(filemodel->index(0, 0), fileIcon, Qt::DecorationRole);
    
        filemodel->setData(filemodel->index(0, 1), size_human(fi.size()));
     }
     }
    
    
        foreach(const QFileInfo &fi, files) {
        QString name = QString("%0").arg(fi.fileName());
    
        if (!fi.isDir()) {
       QMediaPlayer* player = new QMediaPlayer();
        player->setMedia(QUrl::fromLocalFile(filemodelcurrentdir + "/" + name));
    
               auto index = filemodel->index(0, 2);
        connect(player, &QMediaPlayer::durationChanged, this, [this, index](qint64 dur) {
    
                filemodel->setData(index, QString().setNum(static_cast<double>(dur)/60000.0));
            });
    
        delete player;}
    }
    
    
    filemodel->setHeaderData(0,Qt::Horizontal,QObject::tr("Name" ));
    filemodel->setHeaderData(1,Qt::Horizontal,QObject::tr("Size" ));
    filemodel->setHeaderData(2,Qt::Horizontal,QObject::tr("Duration" ));
    
    pTreeView2->setSortingEnabled(true);
    pTreeView2->setColumnWidth(0, 300);
    pTreeView2->setColumnWidth(1, 100);
    pTreeView2->setColumnWidth(2, 100);
    }
    

    The result is the same - doesn't fill the last column


  • Qt Champions 2018

    @Nemooo said in Audio duration for file manager:

    The result is the same - doesn't fill the last column

    Yes, because you need to take the correct index now instead of 0.



  • @jsulm said in Audio duration for file manager:

    @Nemooo said in Audio duration for file manager:

    The result is the same - doesn't fill the last column

    Yes, because you need to take the correct index now instead of 0.

    May be this way?

      void MainWindow::CreateTable(const QString & p) {
      filemodel->removeRows( 0, filemodel->rowCount() );
    filemodelcurrentdir = QDir(p).path();
    files = QDir(p).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    int in = 0;
    foreach(const QFileInfo &fi, files) {
        QString name = QString("%0").arg(fi.fileName());
        filemodel->insertRow(in);
        if (fi.isDir()) {
            filemodel->setData(filemodel->index(in, 0), name);
            filemodel->setData(filemodel->index(in, 0), dirIcon, Qt::DecorationRole);
        } else {
            filemodel->setData(filemodel->index(in, 0), name);
            filemodel->setData(filemodel->index(in, 0), fileIcon, Qt::DecorationRole);
    
        filemodel->setData(filemodel->index(in, 1), size_human(fi.size()));
        }
       ++in;
       }
    
    in = 0;
    foreach(const QFileInfo &fi, files) {
        QString name = QString("%0").arg(fi.fileName());
        if (!fi.isDir()) {
       QMediaPlayer* player = new QMediaPlayer();
        player->setMedia(QUrl::fromLocalFile(filemodelcurrentdir + "/" + name));
    
    
        auto index = filemodel->index(in, 2);
        connect(player, &QMediaPlayer::durationChanged, this, [this, index](qint64 dur) {
    
                filemodel->setData(index, QString().setNum(static_cast<double>(dur)/60000.0));
            });
    
        delete player;}
        ++in;
    }
    
    
    filemodel->setHeaderData(0,Qt::Horizontal,QObject::tr("Name" ));
    filemodel->setHeaderData(1,Qt::Horizontal,QObject::tr("Size" ));
    filemodel->setHeaderData(2,Qt::Horizontal,QObject::tr("Duration" ));
    
    pTreeView2->setSortingEnabled(true);
    pTreeView2->setColumnWidth(0, 300);
    pTreeView2->setColumnWidth(1, 100);
    pTreeView2->setColumnWidth(2, 100);
     }

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.