clementine-player / Clementine

:tangerine: Clementine Music Player
https://www.clementine-player.org/
GNU General Public License v3.0
3.69k stars 674 forks source link

Custom tags / labels #788

Open Clementine-Issue-Importer opened 10 years ago

Clementine-Issue-Importer commented 10 years ago

From luke.schlather on September 21, 2010 22:51:43

Add support for labels like Gmail's. My memory says Amarok supported some sort of custom tags. Would allow people to organize their music in intuitive ways.

Original issue: http://code.google.com/p/clementine-player/issues/detail?id=788

Clementine-Issue-Importer commented 10 years ago

From john.maguire on September 22, 2010 05:57:14

Summary: Custom tags / labels
Labels: -Type-Defect -Priority-Medium Type-Enhancement Priority-Low Component-MusicLibrary

Clementine-Issue-Importer commented 10 years ago

From davidsansome on January 13, 2011 12:48:58

Issue 1286 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From marcansoft on January 27, 2011 10:12:26

I agree, this enables quite a few nice use cases. For example, with Amarok 1.4 I used to tag instrumental songs as such, so I could make a smart playlist that picked up only those. Same with different styles of music (not necessarily something that can be done with just the genre field). I find this much more robust and intuitive than maintaining actual playlists for each category, and it's also by nature more powerful since you can easily combine criteria in a smart playlist.

Clementine-Issue-Importer commented 10 years ago

From jf8011 on February 02, 2011 14:19:46

This is the feature I now miss most from Amarok 1.4. Combined with smart playlists it allows for the creation of very specific playlists.

Clementine-Issue-Importer commented 10 years ago

From john.maguire on April 07, 2011 14:30:38

Issue 1288 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From Arpheno on April 08, 2011 07:58:20

I Would like to see the priority increased on this issue. Also, I will be investigating the subject.

Clementine-Issue-Importer commented 10 years ago

From luke.schlather on April 08, 2011 09:03:55

So basically, what we need is:

  1. Two new tables in the database; a labels table and a songs-to-labels association table.
  2. UI - right-click -> label -> choose from dropdown / new label dialog.
  3. Display column in the playlist view.
  4. A search mechanism.

On #1 it might be cheaper since these will mostly be displayed to use a delimited list of IDs stored as a single field in the songs table, though that will make searching a little kludgey.

As far as search, do we want something that passively integrates with the search box, a way to specify directly "show songs with these tags" or both?

Clementine-Issue-Importer commented 10 years ago

From zzanzare on April 08, 2011 09:14:59

and don't forget the possibility to create dynamic playlists based on labels.. that's exactly what I'm waiting for;-)

Clementine-Issue-Importer commented 10 years ago

From Arpheno on April 09, 2011 04:31:20

I'm still not entirely sure if this is what I am expecting of it, I was told multiple values for one property are called labels. So what I want is this:(ID3v2.4 informal standard) 4.2. Text information frames The text information frames are often the most important frames, containing information like artist, album and more. There may only be one text information frame of its kind in an tag. All text information frames supports multiple strings, stored as a null separated list, where null is reperesented by the termination code for the charater encoding.

There's hardly one song in my library that does not look like: TCON="Rock\0Alternative\0" or TPE1="Eminem\0Rhianna\0" where TCON is the genre frame and TPE1 could be seen as the "main artist" frame.

Does the ability to assign labels include the ability to read from ID3v2.4 compliant null seperated lists? Right now the support for ID3v2.4 is not really exuberant, maybe on the same level as iTunes, which really is a pity.

Could someone with more insight to the topic explain what the database looks like and which files are responsible for its behaviour, so I have something I could start with. I'm an apprentice coder in c++ but I do well in C and python and the syntax is partly very confusing. Thank you

Clementine-Issue-Importer commented 10 years ago

From zzanzare on April 09, 2011 04:39:02

I believe this issue is more about the Labels as they were in Amarok 1.4. These labels are (to my knowledge) non-ID3 and completely custom and only kept in the collection database, not in the song file itself.. correct me if I'm wrong..

Attachment: Screenshot-Track Information: Mariella by Kate Nash - Amarok.png

Clementine-Issue-Importer commented 10 years ago

From marcansoft on April 09, 2011 05:34:37

That is correct, labels here are meant as "tags" in the Web 2.0 sense - lists of words (or possibly short phrases) that can be used to group together songs by different categories. They are kept in the database, not as ID3 tags.

Clementine-Issue-Importer commented 10 years ago

From Arpheno on April 09, 2011 05:39:12

So please unmerge the topics that were merged into here as they do not relate. I strongly reject player specific data storage because my music must be portable at any rate.

Clementine-Issue-Importer commented 10 years ago

From Arpheno on April 09, 2011 05:41:11

sorry for my double post, but i feel issue 1288 shuold instead be merged into here: http://code.google.com/p/clementine-player/issues/detail?id=409&q=ID3&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Stars

Clementine-Issue-Importer commented 10 years ago

From luke.schlather on April 11, 2011 08:13:32

This issue should probably be blocking the ID3 tag issue, since there are standards other than ID3 and I think we should have an internal representation before we start thinking about how to write it to files. (And the last comment in 409 also notes that implementing 409 probably requires changes across the whole application, this bug is probably one of those changes.)

Clementine-Issue-Importer commented 10 years ago

From Arpheno on April 12, 2011 02:21:33

The thing is, ID3 easily allows for custom tags/labels, you can add more than the average user would want ( MEGABYTES ). Your roadmap you gave in your earlier reply is wrong I think, because we do not need another table in the database at all. We're good to go with our current database. The only thing that needs to be changed is the type of object we're pointing at. Although I have no clue about the internals of the database because I'm simply not clever enough to decypher it, what must be there on the lowest level is some kind of string based representation of an information frame (TPE1, TCON, YOURFAVOURITEUSERGENERATEDLABEL,randomTAG, LULZ). What must basically happen is, that we change the type of the object being pointed at to be a list instead of a string. Instead of the current Array-based approach ( from what it looks like, given the immutability of the set of tags one can write into a file/internal representation) this would much more look like a hash table on the song-level. However I agree with you that a good internal representation is the first step to achieving a solid datastructure.Sadly the model of representing music was not thought to be very extendable in clementine and it only allows for certain information frames to be read by the tag parser ( TCON, APIC, TPE1,etc etc) The TagLib routines are responsible for most of this as far as I have seen. What you're suggesting is already an overhaul of the complete database structure but without critical changes like multiple entries for one frame.

For me the situation folds out like this:!!!!!!!!TL;DR;!!!!!!!!!!!!!!!!!!!! The current database model has limits, therefore we should make it better. We should gather ideas what a good database model would look like, and find a good internal representation. Standards are a good way to make clementine compatible with other players. Only overhaul the database once and do it well. /TLDR

This issue will be solved if full ID3v2.4 compability is achieved. thank you

Clementine-Issue-Importer commented 10 years ago

From davidsansome on April 14, 2011 15:35:02

Issue 1759 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From neocrust on April 16, 2011 01:23:45

Any news?

Clementine-Issue-Importer commented 10 years ago

From davidsansome on June 27, 2011 09:42:26

Issue 2026 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From neocrust on June 27, 2011 10:30:51

Any news?

It's great feature from Amarok 1.4 and Clementine will be a great fork with this =]

Clementine-Issue-Importer commented 10 years ago

From wyatt.epp on July 08, 2011 12:12:07

I'm still using KDE 3.5 and Amarok 1.4 because of this. A few notes:

Attachment: AmarokLabel1.png AmarokLabel2.png AmarokLabel3.png

Clementine-Issue-Importer commented 10 years ago

From luke.schlather on July 08, 2011 14:13:19

Yeah, we definitely don't want to shove stuff in TXXX. I think Arph is just trying to relate this to 409 when they're clearly very different issues.

Wyatt, your UI sounds good. Do you have an opinion on putting in a songs_labels table vs. shoving labels into a single field in the songs table? Since you're running 1.4, could you take a look at your database and see how they do it? (I would do it myself, but I live in the mountains and don't have enough bandwidth to download a dated system image on a lark.)

Clementine-Issue-Importer commented 10 years ago

From wyatt.epp on July 08, 2011 17:16:27

Well, I had nothing to do with the design; only ideas for minor improvements. All credit goes to the Amarok devs of old for what you see there! (Though I'd totally be up for a moderate-major design overhaul if someone was interested in discussing it with me. Not feeling up to soloing because my C++ is mediocre at best).

Anyway, for sake of discussion here is the full schema [1] for Amarok 1.4 (should be roughly the same regardless of type, but I'm using sqlite). Unfortunately the full schema dump jumbles things up a bit, so in brief we're most interested in the tables labels: CREATE TABLE labels ( id INTEGER PRIMARY KEY, name VARCHAR(255), type INTEGER); CREATE UNIQUE INDEX labels_name ON labels( name, type );

and tag_labels (indented to ease reading): CREATE TABLE tags_labels ( deviceid INTEGER, url VARCHAR(1024), uniqueid VARCHAR(32), labelid INTEGER REFERENCES labels( id ) ON DELETE CASCADE); CREATE INDEX tags_labels_labelid ON tags_labels( labelid ); CREATE INDEX tags_labels_uniqueid ON tags_labels( uniqueid ); CREATE INDEX tags_labels_url ON tags_labels( url, deviceid );

Now, the old Amarok code is rather...not especially commentful, and it's a fairly complex codebase to boot, but basically what I see happening is the tags_labels uses the deviceid, URL, and uniqueid to reference files and associate them to labels via the left join of labels.id and tags_labels.labelid

Some relevant example code from src/collectiondb.cpp [2] looks to be in CollectionDB::addLabel() (lines 5972-5999). I'll note at this point that if you grep your way back to the beginning, the labels.type in Amarok 1.4.10 ends up being: enum labelTypes { typeUser = 1 }; //add new types add the end!

...yeah. I think this was mostly just a contingency plan in the event that they decided to integrate e.g. last.fm tags too. I don't personally consider this particularly wise, but it was never used for anything anyway.

Now as for how Clementine should handle it... Looking at the database schema for yesterday's head, I don't see any way of uniquely identifying a track without filename and path. While this is suboptimal (doing some sort of fast hash of the file or part of it would likely be an easy fix), we can see that the old method is still quite available.

Though the two-table design may seem like overkill to some (not all: there are five tables each for songs, magnatune, and spotify) it's a simple canonical method of expressing this sort of relationship that scales without hundreds of columns of sparse content.

While putting it in a single column in the songs table would be very simple, to be blunt, I think it's a very bad idea. Every query of labels would have to brute force search at O(n) where n is the number of songs in your database-- I don't think FTS can save you from that.

Attachment: oldrokschema collectiondb.cpp

Clementine-Issue-Importer commented 10 years ago

From ddidderr@web.de on July 13, 2011 14:05:17

Portability of the songs is what matters. Therefore i would like to see the ability to show columns of custom tags. look at foobar2000, then you know what i mean.

Clementine-Issue-Importer commented 10 years ago

From luke.schlather on October 01, 2011 16:49:17

sqlite3 automatically creates a tablename.ROWID index we can use to uniquely identify songs, so a simple schema would look something like this:

CREATE TABLE songs_labels ( songid INTEGER, labelid INTEGER, FOREIGN KEY (songid) REFERENCES songs(ROWID) ON DELETE CASCADE, FOREIGN KEY (labelid) REFERENCES labels(ROWID) ON DELETE CASCADE, UNIQUE (songid,labelid) );

CREATE TABLE labels ( label text NOT NULL UNIQUE );

So getting all the songs for the label with label.ROWID=2 is simply

SELECT songs.title LEFT JOIN songs_labels ON songs_labels.songid = songs.ROWID WHERE songs_labels.labelid = 2;

For the regular playlist browser, we should be able to display the tags on a track as a column the user can check or uncheck. This SQL would show ids, titles, and labels/labelids for the songs in playlist with id 7:

SELECT playlists.ROWID,playlists.name,songs.ROWID,songs.title,group_concat(labels.label) FROM playlists LEFT JOIN playlist_items ON playlists.ROWID = playlist_items.playlist LEFT JOIN songs ON playlist_items.library_id=songs.ROWID LEFT JOIN songs_labels ON songs_labels.songid=songs.ROWID LEFT JOIN labels ON songs_labels.labelid=labels.ROWID WHERE playlists.ROWID = 7 GROUP BY songs.ROWID;

I'm poking around trying to figure out where to add the join on songs_labels to get this into the actual display.

Clementine-Issue-Importer commented 10 years ago

From alphadeltapapa on January 16, 2012 00:17:49

I think when Clementine gets this feature it will have reached feature parity with Amarok 1.4 (and surpassed it in some ways, of course).

Clementine-Issue-Importer commented 10 years ago

From davidsansome on February 26, 2012 07:52:12

Issue 2750 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From neocrust on February 26, 2012 08:29:45

Any news?

Clementine-Issue-Importer commented 10 years ago

From davidsansome on March 07, 2012 02:46:00

Issue 2785 has been merged into this issue.

Clementine-Issue-Importer commented 10 years ago

From hector@marcansoft.com on August 14, 2012 19:12:09

Any updates? This is really one of the last few Amarok 1.4 features that I'm desperately looking forwards to. I'd attempt to work on it myself, but alas, my project stack is overflowing these days.

Clementine-Issue-Importer commented 10 years ago

From neocrust on August 14, 2012 20:06:39

Its too difficult for developers =]

Just use gmusicbrowser.

Clementine-Issue-Importer commented 10 years ago

From arnaud.bienner on August 15, 2012 09:07:19

@neocrust: If you're so clever, do it yourself and send us a patch ;) We will be glad to integrate it :)

Clementine-Issue-Importer commented 10 years ago

From the.binary.buddha on January 02, 2013 16:24:01

If I knew how to code C, I would.

Clementine-Issue-Importer commented 10 years ago

From hector@marcansoft.com on August 16, 2013 20:37:24

I hate to be the "ping" guy, but I guess once a year isn't too harsh.

Any chance this might make it onto any developer's TODO list? At this point this is the only Amarok 1.4 feature that I dearly miss every day. Pretty please? :-)

Clementine-Issue-Importer commented 10 years ago

From GcHoyman on August 18, 2013 10:25:52

I've been using the comment field, to add a user definable tag that is stored with the file I can add a filter to a smart playlist I use this to exclude songs I don't want to hear as often what's lacking is a way to group the library file browser by comment this would allow me to more quickly edit comment tags in big bunches for me this is a reasonable work around

far easier than redesigning databases & the like :D

Clementine-Issue-Importer commented 10 years ago

From JimiJames.Bove on September 11, 2013 21:55:37

I switched to Clementine from quodlibet and definitely miss this feature. I still have QL and Ex Falso installed for organization purposes.

Clementine-Issue-Importer commented 10 years ago

From alphadeltapapa on September 22, 2013 16:33:03

I finally gave up and made a Python script that applies custom tags to MP3, AAC, and Ogg files in the correct format for each filetype. I also made a few supporting shell scripts so I can quickly tag the currently playing track and autocomplete tags that I've used before. These don't show up inside Clementine, but they will be permanent. I also made a script to create playlists from the custom tags, and those work in Clementine. So in a way it's a hacky workaround, but on the other hand it's a lot faster than clicking around in the Clementine UI every time I want to tag a file, and it's independent of any particular player software.

Anyway, if anyone would like a copy of the scripts, feel free to let me know. I've thought about making them a bit more generic and suitable for posting somewhere, but I'll gladly share them as-is.

Clementine-Issue-Importer commented 10 years ago

From yerikb on November 24, 2013 19:24:53

Ping, any updates on this?

Xaavier commented 10 years ago

I am looking at clementine instead of gmusicbrowser and I like it. One thing I miss is this custom metadata feature. Embedded in the music file or in the DB does not matter very much to me but I'd rather have it in the DB than having to touch (and backup) 1.5TB of music. I need an extra field to store the location of the physical CDs. I have many CDs stored in boxes stored in cabinets and there's no way I could keep them sorted alphabetically.

shapirus commented 8 years ago

Just another traditional yearly ping. With huge collections tag-based navigation is the most (if not the only) convenient way of browsing.

er314 commented 8 years ago

Hi, for information, I'm a foobar2000 user (who will eventually switch to a Linux open source alternative), and foobar2000 big strength is its handling of custom tags. In terms of open source implementation, I observe that Quod Libet does load them without a hitch. So this might be a good inspiration, for a mature and cross-everything custom tag format.

Burrito-Bazooka commented 8 years ago

I'd also like to see this in Clementine. How difficult would it be?

$40 bounty on BountySource

adenisiuk commented 8 years ago

I'd also like to see this in Clementine. How difficult would it be?

JulianVolodia commented 8 years ago

I summarize most of things and start to work on this issue. I add some comments how I plan to implement it.

Part I

  1. Two new tables in the database:
    • changes in DB:
    • creation of labels table (id, label, parent) - parent nullable (only one parent available, checking if we are making cyclic relation should be resolved in UI and check in every save)
    • creation of table songs-to-labels (many-to-many) (song_id <--> label_id)
    • changes in existing tables if it would be necessary
    • changes in UI:
    • right-click (at song form playlist, collection etc.) -> label -> choose from dropdown / new label dialog
    • display column in the playlist view

Part II

Part III "and don't forget the possibility to create dynamic playlists based on labels.. that's exactly what I'm waiting for;-)" I think after creating lists as results of searching feature, it could be easier to implement.

--- notes: I finally gave up and made a Python script that applies custom tags to MP3, AAC, and Ogg files in the correct format* for each filetype. [...] I think it is not that way - we need to have labels which are not related with files...

@shapirus : labels should be attachable not only to songs, but to all hierarchy entities: albums, album/artists, artists, and maybe even years. Maybe you think about tags-like labels... in big thinking I imagine - everything could have label, sth like hashtag... But for most of users it wouldn't be useful I think... to year - you maybe want to have some notes about each year, label should be sth like 'note' but very short (i think even 20 characters will fit ;) ) longer would be a problem - even for user :) better to make hierarchy i think :) here I have some concept that you could create new Label or use existing, but like in the google gmail - it should be very easy, simple cause of thinking about User Experience, for example - labeling with real-time fitting existing labels when you are typing ;) My opinion: I agree with many, but not to years i think... and it should be collections. And not everything at once :) Now only songs I think :) We must debug implementation, test it, and get feedback from that feature, and make it ASAP, cause it too long to do it 2 years :) And have maximal density of feature at one object to test it well and then just reimplement for another types of objects (artists etc.)

What you think about it @Chocobozzz , @hatstand ? Best regards.

shapirus commented 8 years ago

I think that labels should be attachable not only to songs, but to all hierarchy entities: albums, album/artists, artists, and maybe even years. Not sure how easy, if at all possible, it can be to fit into your proposed approach, though.

Llammissar commented 8 years ago

@JulianVolodia It's great to hear you're willing to work on this! Thanks so much!

I'm not sure there's much benefit to associating labels with entities other than individual songs when the basic workflow allows you to apply labels to any arbitrary selection anyway.

Consider: what do you gain when you associate a label with an artist over associating it with all of that artist's songs?

The best I can think of is it automatically applies it to new additions to your library but, in my experience, that dramatically constrains its use in every scenario I can think of because it creates a hierarchical association.

Broadly-speaking, there's very little that's universal even among an artist's songs on a single album, and those sorts of outliers are as annoying as they are common if you're trying to manage a clean semantic space. The real frequency of outliers that don't fit into a rigid hierarchy is a major part of why the ideal semantic user ontology in practice is mostly flat (though support for aliasing and implication can be very helpful) and unitary with respect to the items being handled.

To draw from a potential real-world example, if you were to associate something like... say, "Japanese Vocals" with the artist Utada Hikaru, that works for the most part. But she has songs and even a whole album where she's singing in English. You're further constrained by not knowing if a new album is going to clash with the union of label sets until you listen to it.

The result is either you end up polluting your semantic space with items that don't actually match, or you just don't end up using that feature very much. (It's somewhat a question of engineering trade-off, then: is it worth implementing and maintaining? Judgement call.)

It doesn't solve the implementation problem, but I did think of an alternative approach that might work: when a label is added to an entity that isn't a song, it becomes an import filter. If a new addition to the library matches that filter, it receives the label as it's ingested. The critical difference is this is still applied at the item level, so if the label doesn't fit some of the items, you can fix it trivially without having to add negation hacks or complementary subsets to work around the subset relationship.

Another area that needs addressed is UX and UI. How do you expose that you're labelling an artist or album group vs. their constituent parts? How do you propose to make it intuitive enough that people will use it? That's not a condemnation per se, but it's important to consider.

JulianVolodia commented 8 years ago

@Wyatts, I am glad that you agree with me :) First of all - labels should be only for songs.

In next comment I will prepare small use case to show you what I thought about. I try to think like listener asking myself: "What the hell is the label? What I can use it for at first glance at it?" just imagining the UI in my head ;)

to be continued...

JulianVolodia commented 8 years ago

Hmmm... I have an idea but sth in 'real world' appear and I lost time to write about that feature 3 h ago ;)

Think that you can add any way of grouping, labeling adding different infos about that artist - not song actually... Sond could be 'sad', bud artist could be 'awesome', and it do not tell you that each of his work is awesome. You just want to label him as 'awesome'. In search mechanism I imagine, that you have each category (firstly songs, then albums, then artists...) presented as labeled as 'awesome', 'foolish', 'sad', 'programming', 'concentrate', 'german' (artist), 'classic i thought', 'buy my lovely girlfriend' (eg. about album), 'cold war' (eg. about year) - sth like comments which express your feelings, but also:

UX and UI - we should make a research. And first - have labels only for songs... then we will find the proper way to do it. I thought about list of rounded rectangles appearing when you are over the song title, artist, year or sth... View of song, or album, or artist would have the kind of button to show that labels.

Each displayed label should have "x" sign to remove it, and list would contain empty place with "+" to adding that. That's is only sketch of very beginning idea. We must "eat that big, ugly frog" cause it voilent for many people I thought. Any contribution are welcomed (PRs, comments, patches and so on).

Have a nice day and please explain more about that @Wyatts :

It doesn't solve the implementation problem, but I did think of an alternative approach that might work: when a label is added to an entity that isn't a song, it becomes an import filter. If a new addition to the library matches that filter, it receives the label as it's ingested. The critical difference is this is still applied at the item level, so if the label doesn't fit some of the items, you can fix it trivially without having to add negation hacks or complementary subsets to work around the subset relationship.

Burrito-Bazooka commented 8 years ago

The reason I wanted it to be attached to files is so that the methods I use to organise my music is not entirely dependent on Clementine. My own specific use case is to mark out mixes/sets and lyricless or foreign-language songs from the rest of my music, because I sometimes listen to these while working - lyrics I understand distract me.

And I do not want this organisation of my music to be lost if/when I switch music players, nor do I want to maintain playlist files, which depend on the locations of files. If I change the files' names (e.g. using Picard to fix mistagged files), the playlist files will become invalid.

But I like this new idea too.

JulianVolodia commented 8 years ago

@Burrito-Bazooka , I understand that but even if we save it to file, another player must be compatibile to understand that:

If you know how different software technically done sth with music files, and it could be standard for each of: mp3, flac, ogg, acc - post it here :)

You should fix mistagged files with Picard before adding to Clementine. Why are you have problem with labels when you loose it? Your every playlist will be crashed : P

Of course, we could try to be compatible in another players/taggers but first of all - we must have something which work, and say - that it useful and usable. ;)

@Burrito-Bazooka , I will listen to any of your ideas, cause your bounty make me look at that for a (longer) while : P

er314 commented 8 years ago

Hello, As previously said, in terms of cross-players compatibility, I have observed that Quod Libet does load the custom tags created with foobar2000, without a hitch. So this might be a good open-source (Quot Libet, not foobar2000 :-) inspiration , for a mature custom tag format.