1 /* TaggingLyrics.cpp */ 2 3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras) 4 * 5 * This file is part of sayonara player 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "TaggingLyrics.h" 22 23 #include "Tagging.h" 24 #include "Tagging/ID3v2/Lyrics.h" 25 #include "Tagging/Xiph/LyricsFrame.h" 26 27 #include "Utils/MetaData/MetaData.h" 28 #include "Utils/Logger/Logger.h" 29 30 #include <QString> 31 32 #include <taglib/fileref.h> 33 34 namespace 35 { 36 QString readLyricsFromId3(const Tagging::ParsedTag& parsedTag) 37 { 38 QString lyrics; 39 40 auto* id3v2 = parsedTag.id3Tag(); 41 const auto lyricsFrame = ID3v2::LyricsFrame(id3v2); 42 43 if(lyricsFrame.isFrameAvailable()) 44 { 45 lyricsFrame.read(lyrics); 46 } 47 48 return lyrics; 49 } 50 51 QString readLyricsFromXiph(const Tagging::ParsedTag& parsedTag) 52 { 53 QString lyrics; 54 55 auto* xiph = parsedTag.xiphTag(); 56 const auto lyricsFrame = Xiph::LyricsFrame(xiph); 57 lyricsFrame.read(lyrics); 58 59 return lyrics; 60 } 61 62 bool writeLyricsToId3(const Tagging::ParsedTag& parsedTag, const QString& lyrics) 63 { 64 auto* id3v2 = parsedTag.id3Tag(); 65 auto lyricsFrame = ID3v2::LyricsFrame(id3v2); 66 67 return lyricsFrame.write(lyrics); 68 } 69 70 bool writeLyricsToXiph(const Tagging::ParsedTag& parsedTag, const QString& lyrics) 71 { 72 auto* xiph = parsedTag.xiphTag(); 73 auto lyricsFrame = Xiph::LyricsFrame(xiph); 74 75 return lyricsFrame.write(lyrics); 76 } 77 } 78 79 bool Tagging::writeLyrics(const MetaData& track, const QString& lyricsData) 80 { 81 auto fileRef = TagLib::FileRef(TagLib::FileName(track.filepath().toUtf8())); 82 if(!Tagging::isValidFile(fileRef)) 83 { 84 spLog(Log::Warning, "Tagging") << "Cannot open tags for " << track.filepath(); 85 return false; 86 } 87 88 auto success = false; 89 90 const auto parsedTag = Tagging::getParsedTagFromFileRef(fileRef); 91 if((parsedTag.type == Tagging::TagType::ID3v2) && parsedTag.id3Tag()) 92 { 93 success = writeLyricsToId3(parsedTag, lyricsData); 94 } 95 96 else if((parsedTag.type == Tagging::TagType::Xiph) && parsedTag.xiphTag()) 97 { 98 success = writeLyricsToXiph(parsedTag, lyricsData); 99 } 100 101 return (success) 102 ? fileRef.save() 103 : false; 104 } 105 106 bool Tagging::extractLyrics(const MetaData& track, QString& lyricsData) 107 { 108 lyricsData.clear(); 109 110 const auto fileRef = TagLib::FileRef(TagLib::FileName(track.filepath().toUtf8())); 111 if(!Tagging::isValidFile(fileRef)) 112 { 113 spLog(Log::Warning, "Tagging") << "Cannot open tags for " << track.filepath(); 114 return false; 115 } 116 117 const auto parsedTag = Tagging::getParsedTagFromFileRef(fileRef); 118 119 if((parsedTag.type == Tagging::TagType::ID3v2) && parsedTag.id3Tag()) 120 { 121 lyricsData = readLyricsFromId3(parsedTag); 122 } 123 124 else if((parsedTag.type == Tagging::TagType::Xiph) && parsedTag.xiphTag()) 125 { 126 lyricsData = readLyricsFromXiph(parsedTag); 127 } 128 129 return (!lyricsData.isEmpty()); 130 } 131 132 bool Tagging::isLyricsSupported(const QString& filepath) 133 { 134 const auto fileRef = TagLib::FileRef(TagLib::FileName(filepath.toUtf8())); 135 if(!Tagging::isValidFile(fileRef)) 136 { 137 return false; 138 } 139 140 const auto parsedTag = Tagging::getParsedTagFromFileRef(fileRef); 141 return ((parsedTag.type == Tagging::TagType::ID3v2) || 142 (parsedTag.type == Tagging::TagType::Xiph)); 143 } 144 145