File indexing completed on 2024-05-19 04:56:30
0001 /** 0002 * \file m4afile.h 0003 * Handling of MPEG-4 audio files. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 25 Oct 2007 0008 * 0009 * Copyright (C) 2007-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #pragma once 0028 0029 #include "taggedfile.h" 0030 #include <QMap> 0031 0032 /** MPEG-4 audio file */ 0033 class M4aFile : public TaggedFile { 0034 public: 0035 /** 0036 * Constructor. 0037 * 0038 * @param idx index in tagged file system model 0039 */ 0040 explicit M4aFile(const QPersistentModelIndex& idx); 0041 0042 /** 0043 * Destructor. 0044 */ 0045 ~M4aFile() override = default; 0046 0047 /** 0048 * Get key of tagged file format. 0049 * @return "Mp4v2Metadata". 0050 */ 0051 QString taggedFileKey() const override; 0052 0053 /** 0054 * Read tags from file. 0055 * 0056 * @param force true to force reading even if tags were already read. 0057 */ 0058 void readTags(bool force) override; 0059 0060 /** 0061 * Write tags to file and rename it if necessary. 0062 * 0063 * @param force true to force writing even if file was not changed. 0064 * @param renamed will be set to true if the file was renamed, 0065 * i.e. the file name is no longer valid, else *renamed 0066 * is left unchanged 0067 * @param preserve true to preserve file time stamps 0068 * 0069 * @return true if ok, false if the file could not be written or renamed. 0070 */ 0071 bool writeTags(bool force, bool* renamed, bool preserve) override; 0072 0073 /** 0074 * Free resources allocated when calling readTags(). 0075 * 0076 * @param force true to force clearing even if the tags are modified 0077 */ 0078 void clearTags(bool force) override; 0079 0080 /** 0081 * Remove frames. 0082 * 0083 * @param tagNr tag number 0084 * @param flt filter specifying which frames to remove 0085 */ 0086 void deleteFrames(Frame::TagNumber tagNr, const FrameFilter& flt) override; 0087 0088 /** 0089 * Check if tag information has already been read. 0090 * 0091 * @return true if information is available, 0092 * false if the tags have not been read yet, in which case 0093 * hasTag() does not return meaningful information. 0094 */ 0095 bool isTagInformationRead() const override; 0096 0097 /** 0098 * Check if file has a tag. 0099 * 0100 * @param tagNr tag number 0101 * @return true if a V2 tag is available. 0102 * @see isTagInformationRead() 0103 */ 0104 bool hasTag(Frame::TagNumber tagNr) const override; 0105 0106 /** 0107 * Get technical detail information. 0108 * 0109 * @param info the detail information is returned here 0110 */ 0111 void getDetailInfo(DetailInfo& info) const override; 0112 0113 /** 0114 * Get duration of file. 0115 * 0116 * @return duration in seconds, 0117 * 0 if unknown. 0118 */ 0119 unsigned getDuration() const override; 0120 0121 /** 0122 * Get file extension including the dot. 0123 * 0124 * @return file extension ".m4a". 0125 */ 0126 QString getFileExtension() const override; 0127 0128 /** 0129 * Get the format of tag. 0130 * 0131 * @param tagNr tag number 0132 * @return "Vorbis". 0133 */ 0134 QString getTagFormat(Frame::TagNumber tagNr) const override; 0135 0136 /** 0137 * Get a specific frame from the tags. 0138 * 0139 * @param tagNr tag number 0140 * @param type frame type 0141 * @param frame the frame is returned here 0142 * 0143 * @return true if ok. 0144 */ 0145 bool getFrame(Frame::TagNumber tagNr, Frame::Type type, Frame& frame) const override; 0146 0147 /** 0148 * Set a frame in the tags. 0149 * 0150 * @param tagNr tag number 0151 * @param frame frame to set 0152 * 0153 * @return true if ok. 0154 */ 0155 bool setFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0156 0157 /** 0158 * Add a frame in the tags. 0159 * 0160 * @param tagNr tag number 0161 * @param frame frame to add 0162 * 0163 * @return true if ok. 0164 */ 0165 bool addFrame(Frame::TagNumber tagNr, Frame& frame) override; 0166 0167 /** 0168 * Delete a frame from the tags. 0169 * 0170 * @param tagNr tag number 0171 * @param frame frame to delete. 0172 * 0173 * @return true if ok. 0174 */ 0175 bool deleteFrame(Frame::TagNumber tagNr, const Frame& frame) override; 0176 0177 /** 0178 * Get all frames in tag. 0179 * 0180 * @param tagNr tag number 0181 * @param frames frame collection to set. 0182 */ 0183 void getAllFrames(Frame::TagNumber tagNr, FrameCollection& frames) override; 0184 0185 /** 0186 * Get a list of frame IDs which can be added. 0187 * @param tagNr tag number 0188 * @return list with frame IDs. 0189 */ 0190 QStringList getFrameIds(Frame::TagNumber tagNr) const override; 0191 0192 private: 0193 M4aFile(const M4aFile&); 0194 M4aFile& operator=(const M4aFile&); 0195 0196 /** 0197 * Get metadata field as string. 0198 * 0199 * @param name field name 0200 * 0201 * @return value as string, "" if not found, 0202 * QString::null if the tags have not been read yet. 0203 */ 0204 QString getTextField(const QString& name) const; 0205 0206 /** 0207 * Set text field. 0208 * If value is null if the tags have not been read yet, nothing is changed. 0209 * If value is different from the current value, tag 2 is marked as changed. 0210 * 0211 * @param name name 0212 * @param value value, "" to remove, QString::null to do nothing 0213 * @param type frame type 0214 */ 0215 void setTextField(const QString& name, const QString& value, 0216 const Frame::ExtendedType& type); 0217 0218 /** true if file has been read. */ 0219 bool m_fileRead; 0220 0221 /** Information about MPEG-4 file. */ 0222 struct FileInfo { 0223 /** 0224 * Constructor. 0225 */ 0226 FileInfo() : valid(false), channels(0), sampleRate(0), bitrate(0), 0227 duration(0) {} 0228 0229 /** 0230 * Read information about an MPEG-4 file. 0231 * @param handle MP4 handle 0232 * @return true if ok. 0233 */ 0234 bool read(void* handle); 0235 0236 bool valid; /**< true if read() was successful */ 0237 int channels; /**< number of channels */ 0238 long sampleRate; /**< sample rate in Hz */ 0239 long bitrate; /**< bitrate in bits/s */ 0240 long duration; /**< duration in seconds */ 0241 }; 0242 0243 /** Info about file. */ 0244 FileInfo m_fileInfo; 0245 0246 /** Map with metadata. */ 0247 typedef QMap<QString, QByteArray> MetadataMap; 0248 0249 /** Metadata. */ 0250 MetadataMap m_metadata; 0251 QList<Frame> m_extraFrames; 0252 };