Seek in Sound File: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=How to Seek in Sound File=
[[Category:Snippets]]<br />[[Category:HowTo]]
 
= How to Seek in Sound File =


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''':<br />
The following way of setting an offset '''fails''':<br /><code>player = new QMediaPlayer(this);<br />player-&gt;setMedia(QUrl::fromLocalFile&amp;amp;#40;&quot;myCoolSong.mp3&amp;quot;&amp;#41;&amp;#41;;<br />player-&gt;setVolume(50);<br />player-&gt;play(); // music can be heard<br />qDebug() &lt;&lt; player-&gt;isSeekable(); // is always false<br />player-&gt;setPosition ( 20*1000 ); //does not work</code>


'''''It does not work because QMediaPlayer works asynchronously.'''''
'''''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()<br />{<br /> qDebug() &lt;&lt; player-&gt;isSeekable(); // true<br /> player-&gt;setPosition ( 20*1000 );<br />}</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:


When files are loaded with this blocking load method <code>setPosition()</code> can be called right in the next source line.<br /><code>loadBlocking</code> blocks until signal <code>seekableChanged()</code> is emitted. To avoid a deadlock, maximum waiting time is 2 seconds.
<code>void MediaPlayer::loadBlocking(const QString &amp;file;)<br />{<br /> setMedia(QUrl::fromLocalFile&amp;amp;#40;file&amp;amp;#41;);<br /> if(!isSeekable())<br /> {<br /> QEventLoop loop;<br /> QTimer timer;<br /> timer.setSingleShot(true);<br /> timer.setInterval(2000);<br /> loop.connect(&amp;timer;, SIGNAL (timeout()), &amp;loop;, SLOT (quit()) );<br /> loop.connect(this, SIGNAL (seekableChanged(bool)), &amp;loop;, SLOT (quit()));<br /> loop.exec&amp;amp;#40;&amp;#41;;<br /> }<br />}</code>
 
===Categories:===


* [[:Category:HowTo|HowTo]]
When files are loaded with this blocking load method &lt;code&amp;gt;setPosition()&lt;/code&amp;gt; can be called right in the next source line.<br />&lt;code&amp;gt;loadBlocking&amp;lt;/code&amp;gt; blocks until signal &lt;code&amp;gt;seekableChanged()&lt;/code&amp;gt; is emitted. To avoid a deadlock, maximum waiting time is 2 seconds.
* [[:Category:snippets|snippets]]

Revision as of 11:24, 24 February 2015


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:

player = new QMediaPlayer(this);<br />player-&gt;setMedia(QUrl::fromLocalFile&amp;amp;#40;&quot;myCoolSong.mp3&amp;quot;&amp;#41;&amp;#41;;<br />player-&gt;setVolume(50);<br />player-&gt;play(); // music can be heard<br />qDebug() &lt;&lt; player-&gt;isSeekable(); // is always false<br />player-&gt;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()<br />{<br /> qDebug() &lt;&lt; player-&gt;isSeekable(); // true<br /> player-&gt;setPosition ( 20*1000 );<br />}

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

void MediaPlayer::loadBlocking(const QString &amp;file;)<br />{<br /> setMedia(QUrl::fromLocalFile&amp;amp;#40;file&amp;amp;#41;);<br /> if(!isSeekable())<br /> {<br /> QEventLoop loop;<br /> QTimer timer;<br /> timer.setSingleShot(true);<br /> timer.setInterval(2000);<br /> loop.connect(&amp;timer;, SIGNAL (timeout()), &amp;loop;, SLOT (quit()) );<br /> loop.connect(this, SIGNAL (seekableChanged(bool)), &amp;loop;, SLOT (quit()));<br /> loop.exec&amp;amp;#40;&amp;#41;;<br /> }<br />}

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