Kaitai Struct に MP3 の ID3v1 タグ形式を解析させようとしています。標準によると、これは特定のオフセットにある固定形式の構造ですが、このオフセットはファイルの先頭からではなく、末尾から計算されるというトリックがあります。
タグの基本的な.ksy
概要は次のとおりです。実際に変更してはならないのは当然だと思います。
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 の File オブジェクトに直接渡すように見えるためseek()
、失敗します。
トレースバック (最後の最後の呼び出し): ファイル "try-id3.py"、6 行目、print(f.id3v1_tag) ファイル "id3v1_1.py"、171 行目、id3v1_tag self._io.seek(-128) ファイル " kaitaistruct.py", line 29, in seek self._io.seek(n) IOError: [Errno 22] Invalid argument
他のいくつかの同様に非常識なアイデアの後、回避策を見つけました。pos
引数を省略.ksy
して、スクリプト内の適切な位置を手動で探すことができます。
f = Id3v1.from_file('some_file_with_id3.mp3')
f._io.seek(-128, 2)
print(f.tag.title)
これは機能しますが、本当にハックな気がします:( Kaitai StructとPythonでそれを行うより良い方法はありますか?