4

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でそれを行うより良い方法はありますか?

4

1 に答える 1