代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
获取mp3里的id3信息
作者:
Dezai.CN
/ 发布于
2013/7/1
/
1111
只实现了基本的功能,用到iconv.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <math.h> #include <iconv.h> #define MAX_ID3_KEYS 16 struct id3_v2_header { char id3[4]; char ver_major; char ver_minor; char flags; uint32_t size; }; struct id3_v2_frame_header { char id[4]; uint32_t size; uint16_t flags; }; struct id3_v2_frame_contents { unsigned char id[4]; unsigned int size; unsigned char *contents; }; struct id3tag { int num; struct id3_v2_frame_contents v2[MAX_ID3_KEYS]; }; char *utf16_to_utf8(const char *from, const char *to, char *src_str, int count) { iconv_t cv; size_t len, utf8len; char *pin, *pout, *utf8p; cv = iconv_open(to, from); if (cv < 0) { printf("iconv_open error\n"); return NULL; } len = count; pin = src_str; utf8len = 4 * len; pout = (char *)calloc(1, utf8len); utf8p = pout; if (iconv(cv, &pin, &len, &pout, &utf8len) < 0) { printf("iconv error\n"); return NULL; } iconv_close(cv); return utf8p; } static int output_id3tag(struct id3tag *id3) { int fd; int i; char *out_string; char *tmp; fd = open("id3.txt", O_CREAT | O_RDWR, S_IRWXU); for (i = 0; i < MAX_ID3_KEYS; i++) { if (id3->v2[i].size != 0) { if (strncmp(id3->v2[i].id, "APIC", 4) != 0 && strncmp(id3->v2[i].id, "TXXX", 4) != 0) { write(fd, id3->v2[i].contents, id3->v2[i].size); out_string = utf16_to_utf8("UTF-16LE", "UTF-8", id3->v2[i].contents, id3->v2[i].size); if (out_string) { printf ("--- %s---\n", out_string); tmp = id3->v2[i].contents; id3->v2[i].contents = out_string; free(tmp); } } } } close(fd); } void id3tag_init(struct id3tag *id3) { memset(id3, 0, sizeof(*id3)); } void id3tag_free(struct id3tag *id3) { int i; for (i = 0; i < MAX_ID3_KEYS; i++) if (id3->v2[i].contents != NULL) free(id3->v2[i].contents); } static int add_id3tag(struct id3tag *id3, struct id3_v2_frame_header *fh, unsigned char *buf) { char *tmp, *out_string; int i; if (id3->num < MAX_ID3_KEYS) { strncpy( id3->v2[id3->num].id, fh->id, 4); id3->v2[id3->num].contents = (unsigned char *)calloc(1, fh->size); memcpy(id3->v2[id3->num].contents, buf+11, fh->size-1); id3->v2[id3->num].size = fh->size - 1; if (id3->v2[i].size != 0) { if (strncmp(id3->v2[id3->num].id, "APIC", 4) != 0 && strncmp(id3->v2[id3->num].id, "TXXX", 4) != 0) { out_string = utf16_to_utf8("UTF-16", "UTF-8", id3->v2[id3->num].contents, id3->v2[id3->num].size); if (out_string) { // printf ("--- %s---\n", out_string); tmp = id3->v2[id3->num].contents; id3->v2[id3->num].contents = out_string; free(tmp); } } } id3->num++; } } static void print_id3tag(struct id3tag *id3) { int i; for (i = 0; i < MAX_ID3_KEYS; i++) { if (id3->v2[i].size != 0) { printf("%c%c%c%c:", id3->v2[i].id[0],id3->v2[i].id[1],id3->v2[i].id[2],id3->v2[i].id[3]); printf("%s\n", id3->v2[i].contents); } } } static ssize_t read_all(int fd, void *buf, size_t count) { char *buffer = buf; int pos = 0; do { int rc; rc = read(fd, buffer + pos, count - pos); if (rc == -1) { if (errno == EINTR || errno == EAGAIN) continue; return -1; } if (rc == 0) { /* eof */ break; } pos += rc; } while (count - pos > 0); return pos; } static void print_v2_header(struct id3_v2_header *vh) { printf("%s\n" , vh->id3); printf("major:%d\n", vh->ver_major); printf("minor:%d\n", vh->ver_minor); printf("flags:%d\n", vh->flags); printf("Size:%d\n", vh->size); } static void print_v2_frame_header(struct id3_v2_frame_header *fh) { if (fh->size == 0) return; printf("%c%c%c%c\n", fh->id[0], fh->id[1], fh->id[2], fh->id[3]); printf("frame->size:%d\n", fh->size); printf("frame->flags:%d\n", fh->flags); } int parse_id3_v2_header(struct id3_v2_header *vh, int fd) { char buf[20]; int i; uint32_t s = 0; memset(buf, 0, 20); read_all(fd, buf, 10); vh->id3[0] = buf[0]; vh->id3[1] = buf[1]; vh->id3[2] = buf[2]; vh->id3[3] = 0; vh->ver_major = buf[3]; vh->ver_minor = buf[4]; vh->flags = buf[5]; for (i = 0; i < 4; i++) { s = s << 7; s |= buf[6+i]; } vh->size = s; if (vh->ver_major != 3) { printf("Can't parse id3 with major:%d (Only major:3)", vh->ver_major); return 1; } return 0; } static int get_id3_v2_frame_header(unsigned char *buf, struct id3_v2_frame_header *fh) { int i; uint32_t b, s = 0; uint16_t f = 0; fh->id[0] = buf[0]; fh->id[1] = buf[1]; fh->id[2] = buf[2]; fh->id[3] = buf[3]; for (i = 0; i < 4; i++) { b = buf[4 + i]; s = s << 8; s |= b; } fh->size = s; for (i = 0; i < 2; i++) { f = f << 8; f |= buf[8+i]; } fh->flags = f; } static int parse_id3_v2_frame(struct id3tag *id3, struct id3_v2_header *vh, int fd) { unsigned char *buf, *tmp; int i; uint32_t s; struct id3_v2_frame_header fh; int f; lseek(fd, 0, SEEK_SET); tmp = (unsigned char *)calloc(1, vh->size + 10); read_all(fd, tmp, vh->size + 10); buf = tmp + 10; i = 0; while (i < vh->size - 10) { get_id3_v2_frame_header(buf + i, &fh); if (vh->size - i < fh.size) { printf("Error id3_v2_header size\n"); return 1; } // print_v2_frame_header(&fh); if (fh.size != 0) add_id3tag(id3, &fh, buf+i); i += fh.size + 10; } free(tmp); return 0; } int main(int argc, char *argv[]) { int fd; uint32_t size; struct id3_v2_header vh; struct id3tag id3; fd = open(argv[1], O_RDONLY); if (fd == 0) { fprintf(stderr, "Can't open file %s\n", argv[1]); exit(1); } parse_id3_v2_header(&vh, fd); // print_v2_header(&vh); id3tag_init(&id3); parse_id3_v2_frame(&id3, &vh, fd); // output_id3tag(&id3); print_id3tag(&id3); id3tag_free(&id3); close(fd); return 0; }
试试其它关键字
id3信息
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
Dezai.CN
贡献的其它代码
(
4037
)
.
多线程Socket服务器模块
.
生成随机密码
.
清除浮动样式
.
弹出窗口居中
.
抓取url的函数
.
使用base HTTP验证
.
div模拟iframe嵌入效果
.
通过header转向的方法
.
Session操作类
.
执行sqlite输入插入操作后获得自动编号的ID
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3