Summary: | Wrong sort order in m3u playlist | ||
---|---|---|---|
Product: | [Applications] k3b | Reporter: | helmut.suessmuth |
Component: | Audio Project | Assignee: | Michał Małek <michalm> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | andytrozzo, bill_wayson, gtdev, trueg |
Priority: | NOR | ||
Version: | 2.0.1 | ||
Target Milestone: | --- | ||
Platform: | openSUSE | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | 2.0.2 | |
Attachments: | screen shots |
Description
helmut.suessmuth
2010-08-29 12:39:47 UTC
Created attachment 51079 [details]
screen shots
I can confirm this with k3b 2.0.1 from Debian unstable. Generated playlists are more or less randomly sorted. I can confirm this in 32-bit openSUSE 11.3, k3b version 2.0.1 from packman.links2linux.de (2.0.1-1.pm.2.36-i586), kde 4.4.4 "release 3", qt4 4.6.3, and kernel 2.6.34.7-0.5-desktop. The sorting does appear to be random even though the songs are ripped in track order. If it matters, the songs were saved in flac format. commit 36bd5a3863677271f4e8d38679e8c7465e0e2622 branch 2.0 Author: Michal Malek <michalm@jabster.pl> Date: Tue Dec 21 09:11:39 2010 +0100 Fixed playlist sort order BUG: 249395 diff --git a/ChangeLog b/ChangeLog index 15c2e4a..0d92c68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ Bugfixes: * Crash on closing dialog after succesful audio CD ripping (241630) * Crash on device detection (249371) * Crash when showing settings window (238819) + * Fixed playlist sort order (249395) 2.0.1 ===== diff --git a/src/rip/k3baudioripjob.cpp b/src/rip/k3baudioripjob.cpp index beae533..74d9060 100644 --- a/src/rip/k3baudioripjob.cpp +++ b/src/rip/k3baudioripjob.cpp @@ -40,6 +40,22 @@ #include <KStandardDirs> +namespace +{ + + struct SortByTrackNumber + { + SortByTrackNumber( K3b::AudioRipJob::Tracks const& tracks ) : m_tracks( tracks ) {} + + bool operator()( QString const& lhs, QString const& rhs ) + { + return m_tracks.value( lhs ) < m_tracks.value( rhs ); + } + + K3b::AudioRipJob::Tracks const& m_tracks; + }; + +} // namespace class K3b::AudioRipJob::Private @@ -242,7 +258,7 @@ bool K3b::AudioRipJob::run() d->overallSectorsRead = 0; d->overallSectorsToRead = 0; d->lengths.clear(); - + Q_FOREACH( const QString& filename, d->tracks.keys().toSet() ) { d->lengths.insert( filename, 0 ); Q_FOREACH( int track, d->tracks.values( filename ) ) { @@ -263,7 +279,7 @@ bool K3b::AudioRipJob::run() } lastFilename = d->currentTrack.key(); } - + if( d->encoder ) { d->encoder->closeFile(); } @@ -312,7 +328,7 @@ bool K3b::AudioRipJob::ripTrack( int track, const QString& filename, const QStri emit infoMessage( i18n("Unable to create folder %1", dir), K3b::Job::MessageError ); return false; } - + // Close the previous file if the new filename is different if( prevFilename != filename ) { if( d->encoder ) @@ -343,7 +359,7 @@ bool K3b::AudioRipJob::ripTrack( int track, const QString& filename, const QStri metaData.insert( AudioEncoder::META_TRACK_TITLE, d->cddbEntry.get( KCDDB::Title ) ); metaData.insert( AudioEncoder::META_TRACK_COMMENT, d->cddbEntry.get( KCDDB::Comment ) ); } - + isOpen = d->encoder->openFile( d->fileType, filename, d->lengths[ filename ], metaData ); if( !isOpen ) emit infoMessage( d->encoder->lastErrorString(), K3b::Job::MessageError ); @@ -433,14 +449,19 @@ bool K3b::AudioRipJob::writePlaylist() // format descriptor t << "#EXTM3U" << endl; - Q_FOREACH( const QString& filename, d->tracks.keys().toSet() ) { - + // Get list of the ripped filenames sorted by track number + QStringList filenames = d->tracks.keys(); + filenames.removeDuplicates(); + qSort( filenames.begin(), filenames.end(), SortByTrackNumber( d->tracks ) ); + + Q_FOREACH( const QString& filename, filenames ) { + // extra info t << "#EXTINF:" << d->lengths[filename].totalFrames()/75 << ","; - + QVariant artist; QVariant title; - + QList<int> trackNums = d->tracks.values( filename ); if( trackNums.count() == 1 ) { int trackIndex = trackNums.first()-1; @@ -451,7 +472,7 @@ bool K3b::AudioRipJob::writePlaylist() artist = d->cddbEntry.get( KCDDB::Artist ); title = d->cddbEntry.get( KCDDB::Title ); } - + if( !artist.toString().isEmpty() && !title.toString().isEmpty() ) { t << artist.toString() << " - " << title.toString() << endl; } @@ -460,7 +481,7 @@ bool K3b::AudioRipJob::writePlaylist() filename.length() - filename.lastIndexOf('/') - 5) << endl; // filename without extension } - + // filename if( d->relativePathInPlaylist ) t << findRelativePath( filename, playlistDir ) << endl; @@ -490,7 +511,7 @@ bool K3b::AudioRipJob::writeCueFile() text.setPerformer( d->cddbEntry.get( KCDDB::Artist ).toString() ); text.setTitle( d->cddbEntry.get( KCDDB::Title ).toString() ); K3b::Msf currentSector; - + QList<int> trackNums = d->tracks.values( filename ); for( int i = 0; i < trackNums.size(); ++i ) { int trackNum = trackNums[ i ]; @@ -510,7 +531,7 @@ bool K3b::AudioRipJob::writeCueFile() // we always use a relative filename here QString imageFile = filename.section( '/', -1 ); cueWriter.setImage( imageFile, ( d->fileType.isEmpty() ? QString("WAVE") : d->fileType ) ); - + // use the same base name as the image file QString cueFile = filename; cueFile.truncate( cueFile.lastIndexOf('.') ); commit 1894adad227f87a55c6bc650dc5ef7a605c045bd branch master Author: Michal Malek <michalm@jabster.pl> Date: Tue Dec 21 09:11:39 2010 +0100 Fixed playlist sort order BUG: 249395 diff --git a/ChangeLog b/ChangeLog index ba6ccaf..de69f3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ Bugfixes: * Crash on closing dialog after succesful audio CD ripping (241630) * Crash on device detection (249371) * Crash when showing settings window (238819) + * Fixed playlist sort order (249395) 2.0.1 ===== diff --git a/src/rip/k3baudioripjob.cpp b/src/rip/k3baudioripjob.cpp index beae533..74d9060 100644 --- a/src/rip/k3baudioripjob.cpp +++ b/src/rip/k3baudioripjob.cpp @@ -40,6 +40,22 @@ #include <KStandardDirs> +namespace +{ + + struct SortByTrackNumber + { + SortByTrackNumber( K3b::AudioRipJob::Tracks const& tracks ) : m_tracks( tracks ) {} + + bool operator()( QString const& lhs, QString const& rhs ) + { + return m_tracks.value( lhs ) < m_tracks.value( rhs ); + } + + K3b::AudioRipJob::Tracks const& m_tracks; + }; + +} // namespace class K3b::AudioRipJob::Private @@ -242,7 +258,7 @@ bool K3b::AudioRipJob::run() d->overallSectorsRead = 0; d->overallSectorsToRead = 0; d->lengths.clear(); - + Q_FOREACH( const QString& filename, d->tracks.keys().toSet() ) { d->lengths.insert( filename, 0 ); Q_FOREACH( int track, d->tracks.values( filename ) ) { @@ -263,7 +279,7 @@ bool K3b::AudioRipJob::run() } lastFilename = d->currentTrack.key(); } - + if( d->encoder ) { d->encoder->closeFile(); } @@ -312,7 +328,7 @@ bool K3b::AudioRipJob::ripTrack( int track, const QString& filename, const QStri emit infoMessage( i18n("Unable to create folder %1", dir), K3b::Job::MessageError ); return false; } - + // Close the previous file if the new filename is different if( prevFilename != filename ) { if( d->encoder ) @@ -343,7 +359,7 @@ bool K3b::AudioRipJob::ripTrack( int track, const QString& filename, const QStri metaData.insert( AudioEncoder::META_TRACK_TITLE, d->cddbEntry.get( KCDDB::Title ) ); metaData.insert( AudioEncoder::META_TRACK_COMMENT, d->cddbEntry.get( KCDDB::Comment ) ); } - + isOpen = d->encoder->openFile( d->fileType, filename, d->lengths[ filename ], metaData ); if( !isOpen ) emit infoMessage( d->encoder->lastErrorString(), K3b::Job::MessageError ); @@ -433,14 +449,19 @@ bool K3b::AudioRipJob::writePlaylist() // format descriptor t << "#EXTM3U" << endl; - Q_FOREACH( const QString& filename, d->tracks.keys().toSet() ) { - + // Get list of the ripped filenames sorted by track number + QStringList filenames = d->tracks.keys(); + filenames.removeDuplicates(); + qSort( filenames.begin(), filenames.end(), SortByTrackNumber( d->tracks ) ); + + Q_FOREACH( const QString& filename, filenames ) { + // extra info t << "#EXTINF:" << d->lengths[filename].totalFrames()/75 << ","; - + QVariant artist; QVariant title; - + QList<int> trackNums = d->tracks.values( filename ); if( trackNums.count() == 1 ) { int trackIndex = trackNums.first()-1; @@ -451,7 +472,7 @@ bool K3b::AudioRipJob::writePlaylist() artist = d->cddbEntry.get( KCDDB::Artist ); title = d->cddbEntry.get( KCDDB::Title ); } - + if( !artist.toString().isEmpty() && !title.toString().isEmpty() ) { t << artist.toString() << " - " << title.toString() << endl; } @@ -460,7 +481,7 @@ bool K3b::AudioRipJob::writePlaylist() filename.length() - filename.lastIndexOf('/') - 5) << endl; // filename without extension } - + // filename if( d->relativePathInPlaylist ) t << findRelativePath( filename, playlistDir ) << endl; @@ -490,7 +511,7 @@ bool K3b::AudioRipJob::writeCueFile() text.setPerformer( d->cddbEntry.get( KCDDB::Artist ).toString() ); text.setTitle( d->cddbEntry.get( KCDDB::Title ).toString() ); K3b::Msf currentSector; - + QList<int> trackNums = d->tracks.values( filename ); for( int i = 0; i < trackNums.size(); ++i ) { int trackNum = trackNums[ i ]; @@ -510,7 +531,7 @@ bool K3b::AudioRipJob::writeCueFile() // we always use a relative filename here QString imageFile = filename.section( '/', -1 ); cueWriter.setImage( imageFile, ( d->fileType.isEmpty() ? QString("WAVE") : d->fileType ) ); - + // use the same base name as the image file QString cueFile = filename; cueFile.truncate( cueFile.lastIndexOf('.') ); HI. Is failing again, but this time ripping from a CD works fine. The problem is when convertion process is from a CD image compressed in flac, let say CDImage.flac file with its CDimage.cue file, to a list of separated ogg/mp3 files. in this case the order of songs in the m3u file is still wrong. Thank!! |