Python:使用Kaitai结构读取ID3v1标记

Python:使用Kaitai结构读取ID3v1标记,python,id3,kaitai-struct,Python,Id3,Kaitai Struct,我试图让Kaitai Struct解析MP3的ID3v1标记格式。根据,它是一个固定格式的结构,位于某个偏移量处,但诀窍是该偏移量不是从文件的开头计算的,而是从文件的结尾计算的 下面是标签的基本轮廓,我认为它不应该真正改变: meta: id: id3v1 types: id3v1_tag: seq: - id: magic contents: 'TAG' - id: title size: 30 - id: a

我试图让Kaitai Struct解析MP3的ID3v1标记格式。根据,它是一个固定格式的结构,位于某个偏移量处,但诀窍是该偏移量不是从文件的开头计算的,而是从文件的结尾计算的

下面是标签的基本轮廓,我认为它不应该真正改变:

meta:
  id: id3v1
types:
  id3v1_tag:
    seq:
      - id: magic
        contents: 'TAG'
      - id: title
        size: 30
      - id: artist
        size: 30
      - id: album
        size: 30
      - id: year
        size: 4
      - id: comment
        size: 30
      - id: genre
        type: u1
下面是我关于如何从128字节读取到文件末尾的天真想法:

instances:
  tag:
    pos: -128
    type: id3v1_tag
我尝试使用一个简单的Python测试脚本:

#!/usr/bin/env python

from id3v1 import *

f = Id3v1.from_file('some_file_with_id3.mp3')
print(f.tag)
但是,它似乎将该负数直接传递到Python的文件对象
seek()
,因此失败:

回溯(最后一次调用):文件“try-id3.py”,第6行,在 打印(f.id3v1_标记)文件“id3v1_1.py”,第171行,在id3v1_标记中 seek中的self._io.seek(-128)文件“kaitaistruct.py”,第29行 self._io.seek(n)IOError:[Errno 22]参数无效

在其他一些同样疯狂的想法之后,我找到了一个解决办法:我可以省略
.ksy
中的任何
pos
参数,然后手动寻找脚本中的正确位置:

f = Id3v1.from_file('some_file_with_id3.mp3')
f._io.seek(-128, 2)
print(f.tag.title)

这是可行的,但感觉真的很粗糙:(在Kaitai Struct和Python中有更好的方法吗?

即将发布的Kaitai Struct v0.4版本中有一个新功能正好解决了这个问题。您可以使用
\u io
获取当前流对象,然后可以使用
.size
获取当前流的完整长度(以字节为单位)。因此,如果您想解决某些结构问题,请通过与流末尾的固定偏移量,您可能希望在.ksy中使用类似的内容:

instances:
  tag:
    pos: _io.size - 128
    type: id3v1_tag

请注意,虽然当前的稳定版本是v0.3,但您必须从Github下载并构建编译器+运行时,然后使用最新版本。

谢谢!这可能会很好地解决问题!我已经尝试过-它报告了v0.4,但它似乎不支持
\u io.size
。是我还是那里有某种错误?是的,它不支持et已更新。请继续关注v0.4版本,它有望在本周发布。v0.4已发布!请随时查看!