2 This program is free software: you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation, either version 3 of the License, or
5 (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <taglib/fileref.h>
20 #include <taglib/tag.h>
21 #include <taglib/tpropertymap.h>
22 #include <taglib/tstringlist.h>
28 enum action {LIST, REPLACE, INSERT, ERASE, AUDIO};
29 typedef pair<action,string> actionpair;
30 typedef vector<actionpair> actionqueue;
31 typedef pair<string,string> tagpair;
33 TagLib::StringList argToStringList (const string &rawtagarg)
35 TagLib::StringList newlist;
39 size_t nextdelpos = rawtagarg.find('=', delpos+1);
42 newlist.append(rawtagarg.substr(delpos,nextdelpos-delpos));
43 delpos = nextdelpos+1;
45 newlist.append(rawtagarg.substr(delpos,string::npos));
50 tagpair splitToTagPair (const string &rawarg)
52 const size_t delpos = rawarg.find('=');
53 return make_pair(rawarg.substr(0, delpos), rawarg.substr(delpos+1, string::npos));
56 void action_eraseTag (const TagLib::FileRef f, const string &key)
58 TagLib::PropertyMap propmap = f.file()->properties();
60 f.file()->setProperties(propmap);
63 void action_replaceTag (const TagLib::FileRef f, const tagpair &tagPair)
65 TagLib::PropertyMap propmap = f.file()->properties();
66 propmap.replace(tagPair.first, argToStringList(tagPair.second));
67 f.file()->setProperties(propmap);
70 void action_insertTag (const TagLib::FileRef f, const tagpair &tagPair)
72 TagLib::PropertyMap propmap = f.file()->properties();
73 propmap.insert(tagPair.first, argToStringList(tagPair.second));
74 f.file()->setProperties(propmap);
77 int action_printTags (const TagLib::FileRef f)
80 TagLib::PropertyMap tags = f.file()->properties();
81 unsigned int longest = 0;
82 for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) {
83 if (i->first.size() > longest) {
84 longest = i->first.size();
87 cout << "-- TAG (properties) --" << endl;
88 for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) {
89 for(TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) {
90 cout << i->first << "=" << *j << endl;
99 int action_printAudio (const TagLib::FileRef f)
101 if(f.audioProperties()) {
102 TagLib::AudioProperties *properties = f.audioProperties();
103 int seconds = properties->length() % 60;
104 int minutes = (properties->length() - seconds) / 60;
105 cout << "-- AUDIO --" << endl;
106 cout << "BITRATE=" << properties->bitrate() << endl;
107 cout << "SAMPLERATE=" << properties->sampleRate() << endl;
108 cout << "CHANNELS=" << properties->channels() << endl;
109 cout << "LENGTH=" << minutes << ":" << setfill('0') << setw(2) << seconds << endl;
118 cout << "Usage: usetaglib [ACTION]... [FILE]..." << endl;
119 cout << "List and edit tags on mediafiles in formats supported by libtag." << endl;
121 cout << "-h, --help Show this help" << endl;
123 cout << "ACTIONS" << endl;
124 cout << setfill(' ') << setw(45) << left << " -l, --list"
125 << "list all tags (implicit if no action specified)"<< endl;
126 cout << setfill(' ') << setw(45) << left << " -e, --erase=TAGNAME"
127 << "erase tag with name TAGNAME"<< endl;
128 cout << setfill(' ') << setw(45) << left << " -r, --replace=TAGNAME=TAGVAL[=TAGVAL...]"
129 << "replace tag TAGNAME with list of values TAGVAL"<< endl;
130 cout << setfill(' ') << setw(45) << left << " -i, --insert=TAGNAME=TAGVAL[=TAGVAL...]"
131 << "insert list of values TAGVAL for tag TAGNAME"<< endl;
134 int main(int argc, char *argv[])
137 actionqueue requestedActions;
141 static struct option long_options[] =
143 {"help", no_argument, 0, 'h'},
144 {"list", no_argument, 0, 'l'},
145 {"listaudio", no_argument, 0, 'a'},
146 {"insert", required_argument, 0, 'i'},
147 {"erase", required_argument, 0, 'e'},
148 {"replace", required_argument, 0, 'r'},
152 int option_index = 0;
153 c = getopt_long (argc, argv, "hlai:e:r:",
154 long_options, &option_index);
162 if (long_options[option_index].flag != 0)
171 requestedActions.push_back( make_pair(LIST, "") );
175 requestedActions.push_back( make_pair(AUDIO, "") );
179 requestedActions.push_back( make_pair(INSERT, optarg) );
183 requestedActions.push_back( make_pair(ERASE, optarg) );
187 requestedActions.push_back( make_pair(REPLACE, optarg) );
198 if (requestedActions.size() == 0)
199 requestedActions.push_back( make_pair(LIST, "") );
201 for(int i = optind; i < argc; i++) {
202 cout << "******************** \"" << argv[i] << "\" ********************" << endl;
203 TagLib::FileRef f(argv[i]);
208 for (actionqueue::iterator actit = requestedActions.begin(); actit != requestedActions.end(); ++actit) {
209 switch (actit->first) {
215 action_printAudio(f);
219 action_eraseTag(f, actit->second);
223 action_replaceTag(f, splitToTagPair(actit->second));
227 action_insertTag(f, splitToTagPair(actit->second));