rmff.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 999 行 · 第 1/3 页

CPP
999
字号
/***************************************************************************      copyright            : (C) 2005 by Paul Cifarelli      email                : paulc2@optonline.net ***************************************************************************//*************************************************************************** *   This program 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 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * *   This library 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     * *   Lesser General Public License for more details.                       * *                                                                         * *   You should have received a copy of the GNU Lesser General Public      * *   License along with this library; if not, write to the Free Software   * *   Foundation, Inc., 51 Franklin St, 5th fl, Boston, MA 02110-1301,      * *   USA, or check http://www.fsf.org/about/contact.html                   * *                                                                         * *   Note that no RealNetworks code appears or is duplicated, copied, or   * +   used as a template in this code.  The code was written from scratch   * *   using the reference documentation found at:                           * *                                                                         * *   https://common.helixcommunity.org/nonav/2003/HCS_SDK_r5/helixsdk.htm  * *                                                                         * ***************************************************************************/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <netinet/in.h>#include <taglib.h>#include <id3v1tag.h>#include <id3v2tag.h>#include <tfile.h>#include <fileref.h>#include <iostream>#include <string.h>#include "rmff.h"#define UNPACK4(a, buf, i) memcpy((void *)&a, (void *) &buf[i], 4),i+=4,a=ntohl(a)#define UNPACK2(a, buf, i) memcpy((void *)&a, (void *) &buf[i], 2),i+=2,a=ntohs(a)using namespace TagLib;using namespace TagLib::RealMedia;RMFFile::RMFFile(const char *filename) : File(filename), m_id3tag(0) {    if (isOpen())       m_id3tag = new ID3v1::Tag(this, length() - 128); }   RMFFile::~RMFFile() {    delete m_id3tag; }bool RMFFile::save() {    ByteVector bv = m_id3tag->render(); //TODO finish this   return false; } String RealMediaFF::title () const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->title() : "";}String RealMediaFF::artist () const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->artist() : "";}String RealMediaFF::album () const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->album() : "";}String RealMediaFF::comment() const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->comment() : "";}String RealMediaFF::genre() const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->genre() : "";}TagLib::uint   RealMediaFF::year() const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->year() : 0;}TagLib::uint   RealMediaFF::track() const{   return !m_err && m_id3v1tag ? m_id3v1tag->tag()->track() : 0;}// propertiesint RealMediaFF::length () const{   return m_readProperties && !m_err && m_props ? m_props->duration : 0;}int RealMediaFF::bitrate () const{   return m_readProperties && !m_err && m_props ? m_props->avg_bit_rate : 0;}int RealMediaFF::sampleRate () const{   return 0;}int RealMediaFF::channels () const{   return 0; }RealMediaFF::RealMediaFF(const char *file, bool readProperties, AudioProperties::ReadStyle /*propertiesStyle*/): m_filename(0), m_head(0), m_tail(0), m_err(0), m_hdr(0), m_props(0), media_hdrs(0), m_contenthdr(0), m_md(0), m_title(0), m_author(0), m_copyright(0), m_comment(0), m_id3v1tag(0), m_flipYearInMetadataSection(0), m_readProperties(readProperties){   m_filename = strdup(file);   m_fd = open(m_filename, O_RDONLY);   if (m_fd < 0)   {      m_err = -1;      return;   }   // ok, for RM files, the properties are embedded, so we ignore propertiesStyle   if (m_readProperties)   {      init();      // and now for the really complicated stuff...      if (initMetadataSection())         std::cerr << "ERROR reading Metadata\n";   }   // now get the ID3v1 tag at the end of this file   m_id3v1tag = new RMFFile(m_filename);}RealMediaFF::RealMediaFF(RealMediaFF &src): m_filename(0), m_head(0), m_tail(0), m_err(0), m_hdr(0), m_props(0), media_hdrs(0), m_contenthdr(0), m_md(0), m_title(0), m_author(0), m_copyright(0), m_comment(0), m_id3v1tag(0), m_flipYearInMetadataSection(0), m_readProperties(src.m_readProperties){   m_filename=strdup(src.m_filename);   m_fd = open(m_filename, O_RDONLY);   if (m_fd < 0)   {      m_err = -1;      return;   }   // ok, for RM files, the properties are embedded, so we ignore propertiesStyle   if (m_readProperties)   {      init();      // and now for the really complicated stuff...      if (initMetadataSection())         std::cerr << "ERROR reading Metadata\n";   }   // now get the ID3v1 tag at the end of this file   m_id3v1tag = new RMFFile(m_filename);}RealMediaFF::~RealMediaFF(){   ::free(m_filename);   Collectable *hdr = m_head, *next;   while (hdr)   {      next = hdr->fwd;      delete hdr;      hdr = next;   }   delete m_id3v1tag;   delete m_md;   close(m_fd);}bool RealMediaFF::isEmpty() const {    return m_id3v1tag->tag()->isEmpty(); }         void RealMediaFF::saveHeader(Collectable *hdr){   hdr->fwd = 0;   if (!m_head)      m_head = m_tail = hdr;   else   {      m_tail->fwd = hdr;      m_tail = hdr;   }}int RealMediaFF::init(){   int nbytes;   unsigned char buf[65536];   UINT32 object_id;   UINT32 sz;   UINT32 consumed = 0;   off_t s;   if ( (s = lseek(m_fd, 0, SEEK_SET)) )   {      m_err = -1;      return m_err;   }   m_hdr = new File_Header_v0_v1;   nbytes = getChunk(buf, 65536, m_hdr->s.object_id, m_hdr->s.size, consumed);   if (nbytes < 0 || m_hdr->s.size != consumed || memcmp((void *)&m_hdr->s.object_id, ".RMF", 4))   {      //std::cerr << "SERIOUS ERROR - not likely a RealMedia file\n";      m_err = -1;      return m_err;   }   if (!getRealFileHeader(m_hdr, buf, m_hdr->s.object_id, m_hdr->s.size))   {      saveHeader(m_hdr);      consumed = 0;      nbytes = getChunk(buf, 65536, object_id, sz, consumed);      if (nbytes < 0 || sz != consumed)      {         m_err = -1;         return m_err;      }      while (!m_err && memcmp((void *)&object_id, "DATA", 4))      {         char oid[5];         memcpy((void *)oid, (void *)&object_id, 4);         oid[4] = 0;         if (!memcmp((void *)&object_id, "PROP", 4))         {            m_props = new RMProperties;            getRealPropertyHeader(m_props, buf, object_id, sz);            saveHeader(m_props);         }         if (!memcmp((void *)&object_id, "MDPR", 4))         {            media_hdrs = new MediaProperties;            getMediaPropHeader(media_hdrs, buf, object_id, sz);            saveHeader(media_hdrs);         }         if (!memcmp((void *)&object_id, "CONT", 4))         {            m_contenthdr = new ContentDescription;            getContentDescription(m_contenthdr, buf, object_id, sz);            saveHeader(m_contenthdr);         }         consumed = 0;         do         {            nbytes = getChunk(buf, 65536, object_id, sz, consumed);         } while ( !m_err && memcmp((void *)&object_id, "DATA", 4) && (consumed < sz) );      }   }   return 0;}int RealMediaFF::getHdr(unsigned char *buf, size_t sz, UINT32 &fourcc, UINT32 &csz){   int nbytes = 0, i = 0;   if (sz < (size_t)RMFF_HDR_SIZE)      return 0;   if ( (nbytes = read(m_fd, (void *) buf, RMFF_HDR_SIZE)) != RMFF_HDR_SIZE )   {      m_err = -1;      return (nbytes);   }   memcpy((void *)&fourcc, buf, 4); i+=4;   UNPACK4(csz,buf,i);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?