1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-18 03:41:27 +02:00

More track duration calculation and seeking

This commit is contained in:
dridri
2014-09-30 01:30:44 +02:00
committed by Uwe L. Korn
parent 5daca7f0e7
commit ce3d372749
6 changed files with 93 additions and 13 deletions

View File

@@ -109,9 +109,9 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu
case AudioOutput::Paused:
{
if ( audioOutput && currentTrack )
{/* TODO
{
qint64 duration = audioOutput->totalTime() > 0 ? audioOutput->totalTime() : currentTrack->track()->duration() * 1000;
stopped = ( duration - 1000 < audioOutput->currentTime() ); */
stopped = ( duration - 1000 < audioOutput->currentTime() );
}
else
stopped = true;
@@ -133,7 +133,7 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu
if ( stopped && expectStop )
{
expectStop = false;
tDebug( LOGVERBOSE ) << "Finding next track.";
tDebug() << "Finding next track.";
if ( q_ptr->canGoNext() )
{
q_ptr->loadNextTrack();
@@ -194,6 +194,7 @@ AudioEngine::AudioEngine()
connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) );
connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) );
connect( d->audioOutput, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) );
qRegisterMetaType< AudioErrorCode >("AudioErrorCode");
qRegisterMetaType< AudioState >("AudioState");
@@ -1248,6 +1249,11 @@ AudioEngine::currentTime() const
qint64
AudioEngine::currentTrackTotalTime() const
{
// TODO : This is too hacky. The problem is that I don't know why
// libVLC doesn't report total duration for stream data (imem://)
if ( d_func()->currentTrack && d_func()->currentTrack->track() ) {
return d_func()->currentTrack->track()->duration() * 1000 + 1000;
}
return d_func()->audioOutput->totalTime();
}

View File

@@ -18,6 +18,7 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AudioEngine.h"
#include "AudioOutput.h"
#include "utils/Logger.h"
@@ -37,6 +38,7 @@
static QString s_aeInfoIdentifier = QString( "AUDIOOUTPUT" );
static const int ABOUT_TO_FINISH_TIME = 2000;
AudioOutput* AudioOutput::s_instance = 0;
@@ -55,12 +57,15 @@ AudioOutput::AudioOutput( QObject* parent )
, m_volume( 1.0 )
, m_currentTime( 0 )
, m_totalTime( 0 )
, m_aboutToFinish( false )
, dspPluginCallback( 0 )
{
tDebug() << Q_FUNC_INFO;
AudioOutput::s_instance = this;
currentStream = 0;
qRegisterMetaType<AudioOutput::AudioState>("AudioOutput::AudioState");
QList<QByteArray> args;
@@ -94,7 +99,7 @@ AudioOutput::AudioOutput( QObject* parent )
vlcPlayer = libvlc_media_player_new( vlcInstance );
libvlc_event_manager_t *manager = libvlc_media_player_event_manager( vlcPlayer );
libvlc_event_manager_t* manager = libvlc_media_player_event_manager( vlcPlayer );
libvlc_event_type_t events[] = {
libvlc_MediaPlayerMediaChanged,
libvlc_MediaPlayerNothingSpecial,
@@ -113,7 +118,7 @@ AudioOutput::AudioOutput( QObject* parent )
libvlc_MediaPlayerPausableChanged,
libvlc_MediaPlayerTitleChanged,
libvlc_MediaPlayerSnapshotTaken,
libvlc_MediaPlayerLengthChanged,
//libvlc_MediaPlayerLengthChanged,
libvlc_MediaPlayerVout
};
const int eventCount = sizeof(events) / sizeof( *events );
@@ -142,9 +147,12 @@ void
AudioOutput::setCurrentSource(MediaStream* stream)
{
tDebug() << Q_FUNC_INFO;
currentStream = stream;
currentState = Loading;
setState(Loading);
currentStream = stream;
m_totalTime = 0;
m_currentTime = 0;
QByteArray url;
switch (stream->type()) {
@@ -173,10 +181,21 @@ AudioOutput::setCurrentSource(MediaStream* stream)
tDebug() << "MediaStream::Final Url:" << url;
vlcMedia = libvlc_media_new_location( vlcInstance, url.constData() );
libvlc_event_manager_t* manager = libvlc_media_event_manager( vlcMedia );
libvlc_event_type_t events[] = {
libvlc_MediaDurationChanged,
};
const int eventCount = sizeof(events) / sizeof( *events );
for ( int i = 0 ; i < eventCount ; i++ ) {
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
}
libvlc_media_player_set_media( vlcPlayer, vlcMedia );
if ( stream->type() == MediaStream::Url ) {
m_totalTime = libvlc_media_get_duration( vlcMedia );
}
@@ -194,7 +213,8 @@ AudioOutput::setCurrentSource(MediaStream* stream)
libvlc_media_add_option(vlcMedia, ":audio-filter dsp");
libvlc_media_add_option(vlcMedia, "--audio-filter dsp");
currentState = Stopped;
m_aboutToFinish = false;
setState(Stopped);
}
@@ -210,8 +230,9 @@ void
AudioOutput::setState( AudioState state )
{
tDebug() << Q_FUNC_INFO;
emit stateChanged ( state, currentState );
AudioState last = currentState;
currentState = state;
emit stateChanged ( state, last );
}
@@ -226,7 +247,20 @@ void
AudioOutput::setCurrentTime( qint64 time )
{
m_currentTime = time;
if ( m_totalTime <= 0 ) {
m_totalTime = AudioEngine::instance()->currentTrackTotalTime();
}
emit tick( time );
tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime;
if ( time < m_totalTime - ABOUT_TO_FINISH_TIME ) {
m_aboutToFinish = false;
}
if ( !m_aboutToFinish && m_totalTime > 0 && time >= m_totalTime - ABOUT_TO_FINISH_TIME ) {
m_aboutToFinish = true;
emit aboutToFinish();
}
}
@@ -237,6 +271,17 @@ AudioOutput::totalTime()
}
void
AudioOutput::setTotalTime( qint64 time )
{
if ( time > 0 ) {
m_totalTime = time;
// emit current time to refresh total time
emit tick( m_currentTime );
}
}
void
AudioOutput::play()
{
@@ -367,16 +412,23 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque )
case libvlc_MediaPlayerSeekableChanged:
//TODO, bool event->u.media_player_seekable_changed.new_seekable
break;
case libvlc_MediaPlayerLengthChanged:
that->m_totalTime = event->u.media_player_length_changed.new_length;
case libvlc_MediaDurationChanged:
that->setTotalTime( event->u.media_duration_changed.new_duration );
break;
/*
case libvlc_MediaPlayerLengthChanged:
that->setTotalTime( event->u.media_player_length_changed.new_length );
break;
*/
case libvlc_MediaPlayerNothingSpecial:
case libvlc_MediaPlayerOpening:
case libvlc_MediaPlayerBuffering:
case libvlc_MediaPlayerPlaying:
case libvlc_MediaPlayerPaused:
case libvlc_MediaPlayerStopped:
break;
case libvlc_MediaPlayerEndReached:
that->setState(Stopped);
break;
case libvlc_MediaPlayerEncounteredError:
// TODO emit Error

View File

@@ -68,10 +68,12 @@ public slots:
signals:
void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState );
void tick( qint64 );
void aboutToFinish();
private:
void setState( AudioState state );
void setCurrentTime( qint64 time );
void setTotalTime( qint64 time );
static void vlcEventCallback( const libvlc_event_t *event, void *opaque );
static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples );
@@ -83,6 +85,7 @@ private:
qreal m_volume;
qint64 m_currentTime;
qint64 m_totalTime;
bool m_aboutToFinish;
void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples );

View File

@@ -29,6 +29,7 @@ static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" );
MediaStream::MediaStream()
: m_type( Unknown )
, m_url( QUrl() )
, m_eos( false )
, m_pos( 0 )
, m_streamSize( 0 )
{
@@ -85,6 +86,15 @@ MediaStream::setStreamSize( qint64 size )
}
void
MediaStream::endOfData()
{
tDebug() << Q_FUNC_INFO;
m_eos = true;
}
int
MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer )
{
@@ -97,6 +107,10 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_
MediaStream* that = static_cast < MediaStream * > ( data );
if ( that->m_eos == true ) {
return -1;
}
*bufferSize = that->needData(buffer);
return 0;
}
@@ -110,7 +124,9 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz
Q_UNUSED(data);
Q_UNUSED(cookie);
Q_UNUSED(bufferSize);
delete static_cast<char *>(buffer);
// TODO : causes segfault
// delete static_cast<char *>(buffer);
return 0;
}

View File

@@ -53,9 +53,12 @@ public:
static int seekCallback ( void *data, const uint64_t pos );
protected:
void endOfData();
MediaType m_type;
QUrl m_url;
bool m_eos;
qint64 m_pos;
qint64 m_streamSize;
};

View File

@@ -100,7 +100,7 @@ QNR_IODeviceStream::needData ( void** buffer )
if ( ( data.size() == 0 ) && m_networkReply->atEnd() && m_networkReply->isFinished() )
{
// We're done.
//TODO endOfData();
endOfData();
return 0;
}