Version: unspecified (using KDE 4.4.4) OS: Linux After ripping with k3b the playlist file contains the tracks in the wrong sort order. Example: Ripping CD "Motörhead, Speed Not Comfort, Disc 1" with k3b (output format mp3 with playlist m3u) Expected: sort order of tracks in playlist as on CD, starting with "Shoot You In The Back" followed by "Dirty Love" and so on. What I get is a completely different order: #EXTM3U #EXTINF:252,Motörhead - Nightmare Motörhead/Speed Not Comfort (Disc 1)/Nightmare.mp3 #EXTINF:293,Motörhead - Dirty Love Motörhead/Speed Not Comfort (Disc 1)/Dirty Love.mp3 #EXTINF:233,Motörhead - Treat Me Nice Motörhead/Speed Not Comfort (Disc 1)/Treat Me Nice.mp3 #EXTINF:191,Motörhead - Shoot You In The Back Motörhead/Speed Not Comfort (Disc 1)/Shoot You In The Back.mp3 #EXTINF:223,Motörhead - Bump On Your Back Motörhead/Speed Not Comfort (Disc 1)/Bump On Your Back.mp3 #EXTINF:216,Motörhead - Bomber Motörhead/Speed Not Comfort (Disc 1)/Bomber.mp3 #EXTINF:220,Motörhead - Waltz Of The Vampire Motörhead/Speed Not Comfort (Disc 1)/Waltz Of The Vampire.mp3 #EXTINF:255,Motörhead - Love Me Like A Reptile Motörhead/Speed Not Comfort (Disc 1)/Love Me Like A Reptile.mp3 #EXTINF:275,Motörhead - Stone Dead Forever Motörhead/Speed Not Comfort (Disc 1)/Stone Dead Forever.mp3 #EXTINF:186,Motörhead - Fast And Loose Motörhead/Speed Not Comfort (Disc 1)/Fast And Loose.mp3 #EXTINF:191,Motörhead - You Ain't Gonna Live Forever Motörhead/Speed Not Comfort (Disc 1)/You Ain't Gonna Live Forever.mp3 #EXTINF:196,Motörhead - Sharpshooter Motörhead/Speed Not Comfort (Disc 1)/Sharpshooter.mp3 #EXTINF:210,Motörhead - Love Me Like A Reptile (Alternative Version) Motörhead/Speed Not Comfort (Disc 1)/Love Me Like A Reptile (Alternative Version).mp3 #EXTINF:191,Motörhead - The Hammer Motörhead/Speed Not Comfort (Disc 1)/The Hammer.mp3 Devices ----------------------- HL-DT-ST DVDRAM GH22LS50 TL01 (/dev/sr0, CD-R, CD-RW, CD-ROM, DVD-ROM, DVD-R, DVD-RW, DVD-R doppelschichtig, DVD+R, DVD+RW, DVD+R doppelschichtig) [DVD-ROM, DVD-R sequenziell, Zweischichtige DVD-R sequenziell, Zweischicht-DVD-R-Sprung, DVD-RAM, DVD-RW Eingeschränktes Überbrennen, DVD-RW sequenziell, DVD+RW, DVD+R, Zweischichtige DVD+R, CD-ROM, CD-R, CD-RW] [SAO, TAO, RAW, SAO/R96P, SAO/R96R, RAW/R16, RAW/R96P, RAW/R96R, Eingeschränktes Überschreiben, Sprung zwischen DVD-Schichten] [%7] System ----------------------- K3b Version: 2.0.1 KDE Version: 4.4.4 (KDE 4.4.4) "release 2" QT Version: 4.6.3 Kernel: 2.6.34-12-desktop Reproducible: Always Steps to Reproduce: Ripping the same CD twice. Note: This behavior is new and not previously occurred with older versions! Actual Results: #EXTM3U #EXTINF:252,Motörhead - Nightmare Motörhead/Speed Not Comfort (Disc 1)/Nightmare.mp3 #EXTINF:293,Motörhead - Dirty Love Motörhead/Speed Not Comfort (Disc 1)/Dirty Love.mp3 #EXTINF:233,Motörhead - Treat Me Nice Motörhead/Speed Not Comfort (Disc 1)/Treat Me Nice.mp3 #EXTINF:191,Motörhead - Shoot You In The Back Motörhead/Speed Not Comfort (Disc 1)/Shoot You In The Back.mp3 #EXTINF:223,Motörhead - Bump On Your Back Motörhead/Speed Not Comfort (Disc 1)/Bump On Your Back.mp3 #EXTINF:216,Motörhead - Bomber Motörhead/Speed Not Comfort (Disc 1)/Bomber.mp3 #EXTINF:220,Motörhead - Waltz Of The Vampire Motörhead/Speed Not Comfort (Disc 1)/Waltz Of The Vampire.mp3 #EXTINF:255,Motörhead - Love Me Like A Reptile Motörhead/Speed Not Comfort (Disc 1)/Love Me Like A Reptile.mp3 #EXTINF:275,Motörhead - Stone Dead Forever Motörhead/Speed Not Comfort (Disc 1)/Stone Dead Forever.mp3 #EXTINF:186,Motörhead - Fast And Loose Motörhead/Speed Not Comfort (Disc 1)/Fast And Loose.mp3 #EXTINF:191,Motörhead - You Ain't Gonna Live Forever Motörhead/Speed Not Comfort (Disc 1)/You Ain't Gonna Live Forever.mp3 #EXTINF:196,Motörhead - Sharpshooter Motörhead/Speed Not Comfort (Disc 1)/Sharpshooter.mp3 #EXTINF:210,Motörhead - Love Me Like A Reptile (Alternative Version) Motörhead/Speed Not Comfort (Disc 1)/Love Me Like A Reptile (Alternative Version).mp3 #EXTINF:191,Motörhead - The Hammer Motörhead/Speed Not Comfort (Disc 1)/The Hammer.mp3 Expected Results: Expected: sort order of tracks in playlist as on CD, starting with "Shoot You In The Back" followed by "Dirty Love", "Bump On Your Back", "Love Me Like A Reptile" and so on. See screen shots in attached file.
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!!