阅读在线存储的MP3的ID3标签

时间:2014-05-13 20:20:24

标签: c# .net mp3 id3 id3-tag

是否可以在不实际下载整个文件的情况下阅读在线存储的MP3的ID3标签?

我使用过TagLib Sharp,但据我所知,您实际上必须打开该文件才能阅读ID3标签。

1 个答案:

答案 0 :(得分:0)

正如Florian前面所说,您可以使用HTTP Range读取文件的一点内容,查看是否有ID3,然后读取标记的其余部分(如果存在/必要)。例如:

Range: bytes=0-65535

ID3标签可能包含图像,因此它可能真的很大(我见过一些500Kb)。但是,大多数有用的信息(例如标题,描述等)可能会在前几Kb中可用。根据您的连接(或预期的客户端连接),我将选择第一个Kb数量进行下载。对于大多数连接而言,现在每天64Kb的传输速度会非常快(也许在2014年会有所下降)。

请注意,整个文件的总数也可能少于64Kb。 Range请求应该仍然有效,只有它会返回文件大小。在这种情况下,您永远不会再发送更多数据的请求。

带有ID3标签的MP3文件的启动方式如下:

0x49 0x44 0x33                 ID3
0x03 0x00                      major.revision (2.0 or 3.0)
0x00                           flags
0xSS 0xSS 0xSS 0xSS            size

有关版本的注释:

  1. 标签为ID3,表示3不是版本
  2. 第一个版本是2,因为MP3已经具有TAG功能,并且被认为是版本1(在某些情况下是1.1)。
  3. 目前,除0以外,我没有看到其他任何修订。这就是为什么我们将标签引用为ID3v1(TAG,ID3v2(ID3 + 0x02)和ID3v3(ID3 + 0x03)的原因。

0xSS代表大小。这很有趣,因为每个字节仅使用7位来避免0xFF,后者是MP3(MPEG)文件的同步代码。只有他们忘了对在PNG和JPEG图像中发现的0xFF做一些事情……反正...

计算尺寸的方法如下:

size = (buffer[pos + 6] << 21) +
       (buffer[pos + 7] << 14) +
       (buffer[pos + 8] <<  7) +
       (buffer[pos + 9] <<  0)

重要提示::您应该确认在任何这些字节中均未设置第7位。如果设置,则它不是有效的ID3标签。这就是为什么我不做(buffer[pos + n] & 0x7F的原因,如果您早点正确验证了大小,就不需要& 0x7F部分。

请注意,此size不包括标题的大小。因此请记住,标头有10个字节。

其余缓冲区按组织。它们是3个字母,该帧的大小和数据,或4个字母,大小,标志和数据。每帧的标题由版本(2或3)确定。

无论如何,一旦有了size,如果您想读取整个ID3,则可以对HTTP服务器进行另一次GET,如果第一个64Kb(或您先使用的大小)则可以检索剩余的数据尚未大于或等于必需的大小。

Range: bytes=65536-<size + 10 - 1>

大小是ID3中的数据。 +10用于标题。 -1是因为HTTP范围是包含范围的(不是大小,而是位置)。

重要说明:所有服务器都不接受Range标头。如果您在控制范围内,并且服务器不支持范围请求,则可能要考虑在服务器前面添加代理。 nginx真的很擅长。它可以缓存整个文件,并仅返回HTTP标头中请求的范围。