是否可以在不实际下载整个文件的情况下阅读在线存储的MP3的ID3标签?
我使用过TagLib Sharp,但据我所知,您实际上必须打开该文件才能阅读ID3标签。
答案 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
有关版本的注释:
- 标签为ID3,表示
3
不是版本- 第一个版本是
2
,因为MP3已经具有TAG
功能,并且被认为是版本1
(在某些情况下是1.1
)。- 目前,除
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标头中请求的范围。