Sayonara Player
MP4Frame.h
1 /* MP4Frame.h */
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 #ifndef SAYONARA_ABSTRACT_MP4_FRAME_H
22 #define SAYONARA_ABSTRACT_MP4_FRAME_H
23 
24 #include "Utils/Tagging/AbstractFrame.h"
25 #include "Utils/Algorithm.h"
26 
27 #include <QString>
28 
29 #include <taglib/tag.h>
30 #include <taglib/tstringlist.h>
31 #include <taglib/mp4tag.h>
32 #include <taglib/tpropertymap.h>
33 
34 #include <algorithm>
35 #include <optional>
36 
37 namespace MP4
38 {
39  template<typename Model_t>
40  class MP4Frame :
41  protected Tagging::AbstractFrame<TagLib::MP4::Tag>
42  {
43  protected:
44  TagLib::MP4::ItemMap::ConstIterator findKey(const TagLib::MP4::ItemMap& itemMap) const
45  {
46  return std::find_if(itemMap.begin(), itemMap.end(), [&](const auto& itemList) {
47  const auto convertedString = Tagging::convertString(itemList.first);
48  return (convertedString.compare(key(), Qt::CaseInsensitive) == 0);
49  });
50  }
51 
52  void eraseAllFromTag(TagLib::MP4::Tag* tag, const QString& key)
53  {
54  const auto taglibKey = Tagging::convertString(key);
55  while(tag->contains(taglibKey))
56  {
57  tag->removeItem(taglibKey);
58  }
59  }
60 
61  virtual std::optional<Model_t> mapItemToData(const TagLib::MP4::Item& item) const = 0;
62  virtual std::optional<TagLib::MP4::Item> mapDataToItem(const Model_t& model) = 0;
63 
64  public:
65  MP4Frame(TagLib::MP4::Tag* tag, const QString& identifier) :
67 
68  virtual ~MP4Frame() = default;
69 
70  bool read(Model_t& data) const
71  {
72  if(!tag())
73  {
74  return false;
75  }
76 
77  const auto& itemMap = tag()->itemMap();
78  const auto it = findKey(itemMap);
79  if(it != itemMap.end() && it->second.isValid())
80  {
81  const auto optionalData = mapItemToData(it->second);
82  if(optionalData.has_value())
83  {
84  data = optionalData.value();
85  return true;
86  }
87  }
88 
89  return false;
90  }
91 
92  bool write(const Model_t& data)
93  {
94  if(!tag())
95  {
96  return false;
97  }
98 
99  eraseAllFromTag(tag(), key());
100 
101  const auto item = mapDataToItem(data);
102  if(item.has_value() && item.value().isValid())
103  {
104  tag()->setItem(tagKey(), *item);
105  }
106 
107  return item.has_value();
108  }
109 
110  bool isFrameAvailable() const
111  {
112  if(!tag())
113  {
114  return false;
115  }
116 
117  const auto& itemMap = tag()->itemMap();
118  return (findKey(itemMap) != itemMap.end());
119  }
120  };
121 }
122 
123 #endif // SAYONARA_ABSTRACT_MP4_FRAME_H
Definition: MP4Frame.h:42
Definition: AbstractFrame.h:54