Seek in Sound File: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
(Sub-categorize) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Snippets]] | [[Category:Snippets::Misc]] | ||
[[Category:HowTo]] | [[Category:HowTo]] | ||
I tried to play a sound file not at the beginning but with an offset of 20 seconds. | 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''': | The following way of setting an offset '''fails''': | ||
<code>player = new QMediaPlayer(this); | |||
<code> | |||
player = new QMediaPlayer(this); | |||
player->setMedia(QUrl::fromLocalFile("myCoolSong.mp3")); | player->setMedia(QUrl::fromLocalFile("myCoolSong.mp3")); | ||
player->setVolume(50); | player->setVolume(50); | ||
player->play(); // music can be heard | player->play(); // music can be heard | ||
qDebug() << player->isSeekable(); // is always false | qDebug() << player->isSeekable(); // is always false | ||
player->setPosition ( 20*1000 ); //does not work</code> | player->setPosition ( 20*1000 ); //does not work | ||
</code> | |||
'''It does not work because QMediaPlayer works asynchronously.''' | |||
As soon as the seek operations are delayed everything works as intended. For example: | As soon as the seek operations are delayed everything works as intended. For example: | ||
<code>CoolPlayer::on_Button1_clicked() | <code> | ||
CoolPlayer::on_Button1_clicked() | |||
{ | { | ||
qDebug() << player->isSeekable(); // true | qDebug() << player->isSeekable(); // true | ||
player->setPosition ( 20*1000 ); | player->setPosition ( 20*1000 ); | ||
}</code> | } | ||
</code> | |||
To make my life easier I have derived a class MediaPlayer from QMediaPlayer and added a blocking load method: | To make my life easier I have derived a class MediaPlayer from QMediaPlayer and added a blocking load method: | ||
<code>void MediaPlayer::loadBlocking(const QString & | <code> | ||
void MediaPlayer::loadBlocking(const QString &file;) | |||
{ | { | ||
setMedia(QUrl::fromLocalFile(file)); | setMedia(QUrl::fromLocalFile(file)); | ||
Line 35: | Line 38: | ||
timer.setSingleShot(true); | timer.setSingleShot(true); | ||
timer.setInterval(2000); | timer.setInterval(2000); | ||
loop.connect(& | loop.connect(&timer;, SIGNAL (timeout()), &loop;, SLOT (quit()) ); | ||
loop.connect(this, SIGNAL (seekableChanged(bool)), & | loop.connect(this, SIGNAL (seekableChanged(bool)), &loop;, SLOT (quit())); | ||
loop.exec(); | loop.exec(); | ||
} | } | ||
}</code> | } | ||
</code> | |||
When files are loaded with this blocking load method <code>setPosition()</code> can be called right in the next source line. | When files are loaded with this blocking load method <code>setPosition()</code> can be called right in the next source line. | ||
<code>loadBlocking</code> blocks until signal <code>seekableChanged()</code> is emitted. To avoid a deadlock, maximum waiting time is 2 seconds. | <code>loadBlocking</code> blocks until signal <code>seekableChanged()</code> is emitted. To avoid a deadlock, maximum waiting time is 2 seconds. |
Latest revision as of 12:11, 28 November 2016
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:
player = new QMediaPlayer(this);
player->setMedia(QUrl::fromLocalFile("myCoolSong.mp3"));
player->setVolume(50);
player->play(); // music can be heard
qDebug() << player->isSeekable(); // is always false
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:
CoolPlayer::on_Button1_clicked()
{
qDebug() << player->isSeekable(); // true
player->setPosition ( 20*1000 );
}
To make my life easier I have derived a class MediaPlayer from QMediaPlayer and added a blocking load method:
void MediaPlayer::loadBlocking(const QString &file;)
{
setMedia(QUrl::fromLocalFile(file));
if(!isSeekable())
{
QEventLoop loop;
QTimer timer;
timer.setSingleShot(true);
timer.setInterval(2000);
loop.connect(&timer;, SIGNAL (timeout()), &loop;, SLOT (quit()) );
loop.connect(this, SIGNAL (seekableChanged(bool)), &loop;, SLOT (quit()));
loop.exec();
}
}
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.