読者です 読者をやめる 読者になる 読者になる

flv2mp3

ふとしたことから動画フォーマットのひとつである FLV 形式について調べたところ、仕組みとしてはかなり簡単なことがわかった。
FLV 形式から mp3 形式の音声を抽出するスクリプトを Gauche を使って書いてみた。

(use gauche.uvector)
(use srfi-13)

(define (parse-header port)
  (unless (string-prefix? "FLV" (read-block 13 port))
    (error "not a flv file.")))

(define list->num
  (fold$ (lambda(e a) (+ e (* a 256))) 0))

(define (each-packet proc port)
  (define vec (make-u8vector #x1000000))
  (define header (make-u8vector 11))
  (until (eof-object? (read-block! header port))
    (let ((tag (ref header 0))
          (data-length (list->num (u8vector->list header 1 4)))
          (timestamp (list->num (u8vector->list header 4 7))))
      (read-block! vec port 0 data-length)
      (proc tag data-length timestamp vec)
      (read-block 4 port))))

(define (make-packet-filter oport)
  (lambda(tag data-length timestamp data)
    (if (and (= 8 tag) (= (ash (ref data 0) -4) 2))
        (write-block data oport 1 data-length))))

(define (main args)
  (if (< (length args) 3)
      (display #`"usage: ,(car args) infile outfile")
      (call-with-output-file (caddr args)
        (lambda(oport)
          (call-with-input-file (cadr args)
            (lambda(in)
              (parse-header in)
              (each-packet (make-packet-filter oport) in)
              #f)
            :buffering :full)))))

動画から音を切り分けるツールは無数にあるのでイマサラ必要ではないと思うけれど。
Document ID: 21959f167c24b6e988b33dc2567e1675