How to Seek in Sound File

I tried to play a sound file not at the beginning but with an offset of 20 seconds.

The following way of setting an offset fails:

  1. player = new QMediaPlayer(this);
  2. player->setMedia(QUrl::fromLocalFile("myCoolSong.mp3"));
  3. player->setVolume(50);
  4. player->play();  // music can be heard
  5. qDebug() << player->isSeekable();   // is always false
  6. player->setPosition ( 20*1000 );  //does not work

It does not work because QMediaPlayer works asynchronously.

As soon as the seek operations are delayed everything works as intended. For example:

  1. CoolPlayer::on_Button1_clicked()
  2. {
  3.     qDebug() << player->isSeekable();   // true
  4.     player->setPosition ( 20*1000 );  
  5. }

To make my life easier I have derived a class MediaPlayer from QMediaPlayer and added a blocking load method:

  1. void MediaPlayer::loadBlocking(const QString &file;)
  2. {
  3.     setMedia(QUrl::fromLocalFile(file));
  4.     if(!isSeekable())
  5.     {
  6.         QEventLoop loop;
  7.         QTimer timer;
  8.         timer.setSingleShot(true);
  9.         timer.setInterval(2000);
  10.         loop.connect(&timer;, SIGNAL(timeout()), &loop;, SLOT(quit()) );
  11.         loop.connect(this, SIGNAL(seekableChanged(bool)), &loop;, SLOT(quit()));
  12.         loop.exec();
  13.     }
  14. }

When files are loaded with this blocking load method setPosition() can be called right in the next source line.
loadBlocking blocks until signal seekableChanged() is emitted. To avoid a deadlock, maximum waiting time is 2 seconds.

Categories: