FLVファイルのヘッダ表示ツール

#!/usr/bin/ruby

def add_char_be(r, c)
  r *= 0x100
  r += c
  return r
end

class FlvHeader
  BUFSIZE = 4096

  def initialize
    @f = open(ARGV[0], 'r')
    @offset = 0
    @outbuf = ''
    @f.readpartial(BUFSIZE, @outbuf)

# 'FLV' header
    read(13)

    loop do
      begin
        packet
      rescue EOFError
        break
      end
    end
  end

  def read(len)
    tmpbuf = ''
    while len > 0
      if @offset + len <= @outbuf.size
        t = @offset
        @offset += len
        tmpbuf << @outbuf[t, len]
        len = 0
      else
        rem = @outbuf.size - @offset
        tmpbuf << @outbuf[@offset, rem]
        len -= rem
        @f.readpartial(BUFSIZE, @outbuf)
        @offset = 0
      end
    end
    return tmpbuf
  end

  def packet
    fb = read(1)
    printf("%02X ", fb.unpack("C*").first)
    body_length = 0
    buf = read(3)
    buf.each_byte{|c|
      body_length = add_char_be(body_length, c)
      printf("%02X ", c)
    }
    buf = read(7)
    buf.each_byte{|c|
      printf("%02X ", c)
    }
    read(body_length)
    printf("%d\n", body_length)
    read(4)
  end
end

FlvHeader.new
    • 使い方
      • % ./hoge.rb foo.flv
    • 以前のスクリプトはどうしようもなく重かった
      • each_byteでファイル全体をなめていたため
      • これは初期のバージョンのnamarecoも同様
    • 上記のスクリプトではreadpartialである程度まとめてとってきている
      • これは現状のnamarecoも同様
      • 以前のnamarecoはPC上のVirtualBoxでようやく動く程度のCPU負荷(60〜70%)だった
      • 今では266MHz動作のマシン上で20〜30%の負荷で動作
  • 閑話休題
    • 上記のスクリプトでヘッダを表示させると以下のようになる
09 00 00 02 00 00 00 00 00 00 01 2
09 01 11 4A 00 00 00 00 00 00 01 69962
09 00 0B B8 00 00 00 00 00 00 01 3000
09 00 08 47 00 00 00 00 00 00 01 2119
09 00 06 9A 00 00 00 00 00 00 01 1690
09 00 04 3A 00 00 00 00 00 00 01 1082
09 00 01 27 00 00 00 00 00 00 01 295
09 00 02 50 00 00 00 00 00 00 01 592
09 00 03 AA 00 00 00 00 00 00 01 938
09 00 02 05 00 00 00 00 00 00 01 517
09 00 04 55 00 00 00 00 00 00 01 1109
09 00 02 79 00 00 00 00 00 00 01 633
09 00 00 BC 00 00 00 00 00 00 01 188
09 00 00 02 00 00 00 00 00 00 01 2
08 00 00 00 00 00 00 00 00 00 01 0
08 00 02 01 00 00 00 00 00 00 01 513
08 00 02 01 00 00 2F 00 00 00 01 513
09 00 04 F0 00 00 54 00 00 00 01 1264
08 00 02 01 00 00 5D 00 00 00 01 513
    • 先頭のFLVから始まるヘッダは表示していない
    • 09から始まる行が映像そして08から始まる行が音声となっている
    • 次の3BytesがBodyサイズで次の3BytesがTimestemp(単位はミリ秒)最後の4BytesがStreamID(よく分からない)
      • 最後はBodyサイズを十進数表記にしたもの