/* * Copyright (C) 2013 Emeric Poupon * * This file is part of LMS. * * LMS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * LMS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with LMS. If not, see . */ #include "AvFormat.hpp" #include #include "av/AvInfo.hpp" #include "utils/Logger.hpp" #include "utils/Utils.hpp" namespace MetaData { AvFormat::AvFormat(const ClusterTypes& clusterTypes) : Parser(clusterTypes) { } boost::optional AvFormat::parse(const boost::filesystem::path& p, bool debug) { Items items; try { Av::MediaFile mediaFile(p); // Stream info { std::vector audioStreams; auto streams = mediaFile.getStreamInfo(); for (auto stream : streams) audioStreams.push_back( {.bitRate = stream.bitrate } ); if (!audioStreams.empty()) items.insert( std::make_pair(MetaData::Type::AudioStreams, audioStreams)); } // Duration items.insert( std::make_pair(MetaData::Type::Duration, mediaFile.getDuration() )); // Cover items.insert( std::make_pair(MetaData::Type::HasCover, mediaFile.hasAttachedPictures())); // Embedded MetaData // Make sure to convert strings into UTF-8 MetaData::Clusters clusters; std::map metadataMap = mediaFile.getMetaData(); for (auto metadata : metadataMap) { const std::string tag = boost::to_upper_copy(metadata.first); const std::string value = metadata.second; if (debug) std::cout << "TAG = " << tag << ", VAL = " << value << std::endl; if (tag == "ARTIST") items.insert( std::make_pair(MetaData::Type::Artist, stringTrim( value) )); else if (tag == "ALBUM") items.insert( std::make_pair(MetaData::Type::Album, stringTrim( value) )); else if (tag == "TITLE") items.insert( std::make_pair(MetaData::Type::Title, stringTrim( value) )); else if (tag == "TRACK") { // Expecting 'Number/Total' auto strings = splitString(value, "/"); if (strings.size() > 0) { auto number = readAs(strings[0]); if (number) items.insert( std::make_pair(MetaData::Type::TrackNumber, *number )); if (strings.size() > 1) { auto totalNumber = readAs(strings[1]); if (totalNumber) items.insert( std::make_pair(MetaData::Type::TotalTrack, *totalNumber )); } } } else if (tag == "DISC") { // Expecting 'Number/Total' auto strings = splitString(value, "/"); if (strings.size() > 0) { auto number = readAs(strings[0]); if (number) items.insert( std::make_pair(MetaData::Type::DiscNumber, *number )); if (strings.size() > 1) { auto totalNumber = readAs(strings[1]); if (totalNumber) items.insert( std::make_pair(MetaData::Type::TotalDisc, *totalNumber )); } } } else if (tag == "DATE" || tag == "YEAR" || tag == "WM/Year") { auto date = readAs(value); if (date) items.insert(std::make_pair(MetaData::Type::Year, *date)); } else if (tag == "TDOR" // Original release time (ID3v2 2.4) || tag == "TORY") // Original release year { auto date = readAs(value); if (date) items.insert(std::make_pair(MetaData::Type::OriginalYear, *date)); } else if (tag == "MUSICBRAINZ ARTIST ID" || tag == "MUSICBRAINZ_ARTISTID") { items.insert( std::make_pair(MetaData::Type::MusicBrainzArtistID, stringTrim(value)) ); } else if (tag == "MUSICBRAINZ ALBUM ID" || tag == "MUSICBRAINZ_ALBUMID") { items.insert( std::make_pair(MetaData::Type::MusicBrainzAlbumID, stringTrim(value)) ); } else if (tag == "MUSICBRAINZ RELEASE TRACK ID" || tag == "MUSICBRAINZ_RELEASETRACKID" || tag == "MUSICBRAINZ_TRACKID") { items.insert( std::make_pair(MetaData::Type::MusicBrainzTrackID, stringTrim(value)) ); } else if (tag == "ACOUSTID ID") { items.insert( std::make_pair(MetaData::Type::AcoustID, stringTrim(value)) ); } else if (_clusterTypes.find(tag) != _clusterTypes.end()) { std::vector clusterNames = splitString(value, ";,\\"); if (!clusterNames.empty()) { clusters[tag] = std::set(clusterNames.begin(), clusterNames.end()); } } } if (!clusters.empty()) items.insert( std::make_pair(MetaData::Type::Clusters, clusters) ); } catch(Av::MediaFileException& e) { return items; } return items; } } // namespace MetaData