commit 425d684b7df0e8b50faa0cbe86eecb2d4d5022cd Author: Ralf Engels Date: Wed May 18 20:34:42 2011 +0200 Fix some audio cd related issue: not playing, skipping tracks with gstreamer, no length shown Don't start a new track in the EngineController if the new title is the one we just started. (fixes bug 222405) Handle a device specifier (?device=) in EngineController::playUrl, the old code would not play if the deviceName had a slash (/) in it. (fixes bug 261175). Use KIO:NetAccess::stat to compute track lengths, previously shown as 0:00, fixes bug 207806. src/core-impl/meta/cdda/AudioCdTrackProvider_p.cpp (AudioCdTrackProvider::Private::Private,AudioCdTrackProvider::Private::deviceAdded): Fix some typos, that may have caused crashes. Courtesy: Arnold Metselaar diff --git a/src/EngineController.cpp b/src/EngineController.cpp index 2f666fd..a1c4c76 100644 --- a/src/EngineController.cpp +++ b/src/EngineController.cpp @@ -83,6 +83,7 @@ EngineController::EngineController() , m_playWhenFetched( true ) , m_volume( 0 ) , m_currentIsAudioCd( false ) + , m_currentAudioCdTrack( 0 ) , m_ignoreVolumeChangeAction ( false ) , m_ignoreVolumeChangeObserve ( false ) , m_tickInterval( 0 ) @@ -460,6 +461,15 @@ EngineController::playUrl( const KUrl &url, uint offset ) QString trackNumberString = url.url(); trackNumberString = trackNumberString.remove( "audiocd:/" ); + const QString devicePrefix( "?device=" ); + QString device(""); + if (trackNumberString.contains(devicePrefix)) + { + int pos = trackNumberString.indexOf( devicePrefix ); + device = trackNumberString.mid( pos + devicePrefix.size() ); + trackNumberString = trackNumberString.left( pos ); + } + QStringList parts = trackNumberString.split( '/' ); if ( parts.count() != 2 ) @@ -479,25 +489,27 @@ EngineController::playUrl( const KUrl &url, uint offset ) int trackNumber = parts.at( 1 ).toInt(); - debug() << "3.2.1..."; + debug() << "Old device: " << m_media.data()->currentSource().deviceName(); Phonon::MediaSource::Type type = m_media.data()->currentSource().type(); - if( type != Phonon::MediaSource::Disc ) + if( type != Phonon::MediaSource::Disc || m_media.data()->currentSource().deviceName() != device ) { m_media.data()->clear(); - m_media.data()->setCurrentSource( Phonon::Cd ); + debug() << "New device: " << device; + m_media.data()->setCurrentSource( Phonon::MediaSource( Phonon::Cd, device ) ); } - debug() << "boom?"; + debug() << "Track: " << trackNumber; + m_currentAudioCdTrack = trackNumber; m_controller.data()->setCurrentTitle( trackNumber ); debug() << "no boom?"; if( type == Phonon::MediaSource::Disc ) { - // The track has changed but the slot will not be called, - // because it's still the same media source, which means + // The track has changed but the slot may not be called, + // because it may be still the same media source, which means // we need to do it explicitly. - slotNewTrackPlaying( Phonon::Cd ); + slotNewTrackPlaying( m_media.data()->currentSource() ); } //reconnect it @@ -1306,9 +1318,10 @@ EngineController::slotSeekableChanged( bool seekable ) void EngineController::slotTitleChanged( int titleNumber ) { DEBUG_BLOCK - Q_UNUSED( titleNumber ); - - slotAboutToFinish(); + if ( titleNumber != m_currentAudioCdTrack ) + { + slotAboutToFinish(); + } } void EngineController::slotVolumeChanged( qreal newVolume ) diff --git a/src/EngineController.h b/src/EngineController.h index 4117a89..7874a79 100644 --- a/src/EngineController.h +++ b/src/EngineController.h @@ -553,6 +553,7 @@ private: bool m_playWhenFetched; int m_volume; bool m_currentIsAudioCd; + int m_currentAudioCdTrack; QList m_metaDataHistory; // against metadata spam diff --git a/src/core-impl/collections/audiocd/AudioCdCollection.cpp b/src/core-impl/collections/audiocd/AudioCdCollection.cpp index 13a04ae..3e73dde 100644 --- a/src/core-impl/collections/audiocd/AudioCdCollection.cpp +++ b/src/core-impl/collections/audiocd/AudioCdCollection.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -254,7 +255,7 @@ AudioCdCollection::infoFetchComplete( KJob *job ) debug() << "Track name: " << trackName; - QString padding = i < 10 ? "0" : QString(); + QString padding = (i + 1) < 10 ? "0" : QString(); QString baseFileName = m_fileNamePattern; debug() << "Track Base File Name (before): " << baseFileName; @@ -277,6 +278,7 @@ AudioCdCollection::infoFetchComplete( KJob *job ) trackPtr->setTrackNumber( i + 1 ); trackPtr->setFileNameBase( baseFileName ); + trackPtr->setLength( trackLength( i + 1 ) ); memoryCollection()->addTrack( Meta::TrackPtr::staticCast( trackPtr ) ); @@ -324,6 +326,19 @@ AudioCdCollection::infoFetchComplete( KJob *job ) } } +qint64 +AudioCdCollection::trackLength(int i) const +{ + KUrl kioUrl = audiocdUrl( QString("Track%1.wav").arg(i, 2, 10, QChar('0') ) ); + KIO::UDSEntry uds; + if ( KIO::NetAccess::stat(kioUrl, uds, NULL) ) + { + qint64 samples = (uds.numberValue(KIO::UDSEntry::UDS_SIZE, 44) - 44) / 4; + return (samples - 44) * 10 / 441; + } + return 0; +} + QString AudioCdCollection::collectionId() const { @@ -456,6 +471,7 @@ AudioCdCollection::noInfoAvailable() trackPtr->setTrackNumber( i ); trackPtr->setFileNameBase( trackName ); + trackPtr->setLength( trackLength( i ) ); memoryCollection()->addTrack( Meta::TrackPtr::staticCast( trackPtr ) ); diff --git a/src/core-impl/collections/audiocd/AudioCdCollection.h b/src/core-impl/collections/audiocd/AudioCdCollection.h index a3baf61..6196b4a 100644 --- a/src/core-impl/collections/audiocd/AudioCdCollection.h +++ b/src/core-impl/collections/audiocd/AudioCdCollection.h @@ -103,6 +103,7 @@ private: // Helper function to build the audiocd url. KUrl audiocdUrl( const QString &path = "" ) const; + qint64 trackLength( int i ) const; /** * Clear collection and read the CD currently in the drive, adding Artist, Album, diff --git a/src/core-impl/meta/cdda/AudioCdTrackProvider_p.cpp b/src/core-impl/meta/cdda/AudioCdTrackProvider_p.cpp index 048e6b6..e697367 100644 --- a/src/core-impl/meta/cdda/AudioCdTrackProvider_p.cpp +++ b/src/core-impl/meta/cdda/AudioCdTrackProvider_p.cpp @@ -52,7 +52,7 @@ AudioCdTrackProvider::Private::Private() if( device.is() ) { //does this actually work on windows??? - Solid::Block *sb = devie.as>Solid::Block>(); + Solid::Block *sb = device.as(); m_cddaDevices.insert( device.udi(), sb->device() ); } } @@ -81,7 +81,7 @@ AudioCdTrackProvider::Private::deviceAdded( const QString &udi ) if( device.is() ) { //does this actually work on windows??? - Solid::Block *sb = devie.as>Solid::Block>(); + Solid::Block *sb = device.as(); m_cddaDevices.insert( device.udi(), sb->device() ); KCompactDisc cd; cd.setDevice( sb->device() );