mp3info.7z 自己写的一版mp3文件解析demo,它采用ID3v1、id3v2.3规则进行解析,其中id3v1是现在主流播放器优先选择实现的,id3v2.3相对于id3v1而言,多了更多内容,结构也更复杂,包括:歌曲名称、歌手名字、所属专辑、发布时间、音乐时长等等 最近在用qt5编写播放器时遇到个问题,在Windows端需要解析音频文件音谱来绘制曲线图,但发现Windows端的库要么太老、要么太弱鸡、要么得自己编译,无奈花了一天时间在下载、编译taglib、学习ffmpeg路上,到最后都是以动态库调用时出现未知函数告终(mingw_gcc),原来qt本身就有对这些的封装,可采用qmediaplaer代替他们,只不过需要安装解码器才行,但qmediaplaer并不支持ffmpeg、taglib的音频文件直接操作功能,这不得已自己重写一版。。。 参考文章 C语言结构体为 ID3V2 ID3V1 part1:ID3v1版本可以通过音乐文件末尾倒数第128字节开始进行数据截取,这也是最简单的 part2:ID3v2.3版本在国内只有原理讲解文章与一些开源第三方库可供参考
MP3文件结构解析(超详细)
要一个解析MP3的代码要C语言的 要自己写的不要网上的
Inside the MP3 Codec – Page 11
lets-build-mp3-decoder
Reading MP3 files [closed]
//起始位置:0x0-0x9 struct ID3V2Header{ char Header[3]; /*必须为“ID3”否则认为标签不存在*/ char Ver[1]; /*版本号ID3V2.3 就记录3*/ char Revision[1]; /*副版本号此版本记录为0*/ char Flag[1]; /*标志字节,只使用高三位,其它位为0 */ char Size[4]; /*标签大小*/ }; //起始位置:0x10-0x19 struct ID3V2INFO{ char ID[4]; /*标识帧,说明其内容,例如作者/标题等*/ char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/ char Flags[2]; /*标志帧,只定义了6 位*/ };
//起始位置:-128 struct ID3V1HEAD{ char tag[3];//tag占用3字节 char musicname[30];//音乐标签占30字节 char artist[30];//歌曲作者占30字节 char album[30];//发行专辑占30字节 char year[4];//发行年份占4字节 char generic[30];//一些音乐的介绍以及其他杂七杂八内容占30字节 char type[1];//类型,占1字节 };
//用于解析mp3文件,采用id3v1取倒数128固定位置数据 MP3INFO MediaTools::toMp3Info(QString path) { int part = 128; QString tag, musicname, artist, album, year, generic, musictype; QFile f(path); f.open(QFile::ReadOnly);//以只读方式打开文件 f.seek(f.size() - part);//从倒数128开始读取数据 part = part - 3; tag = QString::fromLocal8Bit(f.readLine(4));//前3字节为tag标签,这里为什么用4,因为这是qt f.seek(f.size() - part); part = part - 30;//这里减去30,是为了给下面往后移动30字节读取内容 musicname = QString::fromLocal8Bit(f.readLine(31)); f.seek(f.size() - part); part = part - 30; artist = QString::fromLocal8Bit(f.readLine(31)); f.seek(f.size() - part); part = part - 30; album = QString::fromLocal8Bit(f.readLine(31)); f.seek(f.size() - part); part = part - 4; year = QString::fromLocal8Bit(f.readLine(5)); f.seek(f.size() - part); part = part - 30; generic = QString::fromLocal8Bit(f.readLine()); f.seek(f.size() - 1); musictype = QString::fromLocal8Bit(f.readLine(1)); f.close(); //返回mp3info对象,可以用结构体代替 return MP3INFO(tag, musicname, artist, album, year, generic, musictype); }
我这里实现了一版非常烂的demo,望各位懂这方面的大佬帮忙指点指点void MediaTools::seekFiles(int &len, QFile &f) { QByteArray by;//创建一个字节数组对象 f.seek(len);//设置文件读取起始位置 //这个为音乐文件里0x21起始头部的帧信息头部,占4字节 qDebug() << "seekFiles 0 ::" << QString::fromLocal8Bit(f.readLine(5)); f.seek(len + 4); //这个为音乐文件里帧内容大小 by = f.read(4); qDebug() << "seekFiles 1 ::" << by; f.seek(len + 4 + 4); qDebug() << "seekFiles 2 ::" << QString::fromLocal8Bit(f.readLine(3)); int FSize; //帧内容大小计算公式 FSize = by[0] * 0x100000000 + by[1] * 0x10000 + by[2] * 0x100 + by[3]; qDebug() << "seekFiles fsize ::" << FSize; f.seek(len + 11); qDebug() << "seekFiles data ::" << QString::fromLocal8Bit(f.readLine()); len = len + 10 + FSize; qDebug() << "next positi ::: " << len << "n"; } //第一次调用位置 void MediaTools::Mp3ID3V2_3(QString path) { QFile f(path); f.open(QFile::ReadOnly); QByteArray by; //读取0x0-0x9位置的数据 qDebug() << "0 ::" << QString::fromLocal8Bit(f.readLine(4));//tag标识 f.seek(3); qDebug() << "1 ::" << QString::fromLocal8Bit(f.readLine(2)); f.seek(4); qDebug() << "2 ::" << QString::fromLocal8Bit(f.readLine(2)); f.seek(5); qDebug() << "3 ::" << QString::fromLocal8Bit(f.readLine(2)); f.seek(6); //帧数据内容大小,这里的大小为所有帧的内容大小,也就是说,在这个地址往后偏移1位就是音频数据了 by = f.read(4); qDebug() << "4 ::" << by; int len = 10; int total_size; total_size = (by[0] & 0x7F) * 0x200000 + (by[1] & 0x7F) * 0x400 + (by[2] & 0x7F) * 0x80 + (by[3] & 0x7F); qDebug() << total_size; //通过不断的调用来获取音频文件里TIT2、TPE1、TALB等内容信息 seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); seekFiles(len, f); f.close(); }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算