ファイルを開いて見るだけならとても便利なPDFですが、中身を自由に触れなくて不便に感じることはありませんか?
先日、PDFに埋め込まれた動画を再生しようとしたところAdobe Acrobat Reader上でしか再生できず、しかもその再生機能がかなり厳しい1再生しかできない。一時停止すらない……ので困りました。できることなら動画ファイルを抽出して、使い慣れたプレーヤーで観たいです。
「PDF ファイル 抽出」 などでGoogle検索したところ、Adobe Acrobat Pro DCではできそうです。ただ、この用途だけに年間20,856円を払う踏ん切りはつきませんでした。また、ファイル抽出のオンラインツールなども見つかりましたが、どれも画像を対象としたもので、ファイル形式(画像、動画…)に関わらずオリジナルの状態(無損失)でのファイル抽出は無理そうです。
自分でなんとかできないかな?と思いながら手を動かしてみたところ、実際にファイルを抽出をすることができたので、その方法を紹介します。すべて無料のツールを使っています。
PDFからファイルを抽出する方法の解説
準備
処理対象のファイルを作業しやすいディレクトリにコピーします。
例として以下としました。
- 作業ディレクトリ: C:\test
- 処理対象ファイル名: compressed.pdf
PDFを解凍する
普段意識することはありませんが、PDFは圧縮された状態になっていることが多いです。圧縮された状態だと扱いづらいため、PDFtkというツールを使って解凍します。2解凍以外にも、PDFの各種操作ができる多機能なツールとして定評があります
PDFtk(今回の用途であれば無料版で大丈夫です)をインストールしたら、対象のファイルにuncompressコマンドを実行します。
> pdftk compressed.pdf output uncompressed.pdf uncompress

無事解凍に成功し、非圧縮のPDFファイル(uncompressed.pdf)が手に入りました。
ファイルを抽出する
PDFの仕様として、埋め込まれたファイルは「streamオブジェクト」としてPDFファイル内にそのまま埋め込まれています。具体的にはPDFファイル中で「stream」と「endstream」に囲まれた位置に記載されています。3PDF32000_2008 7.3.8 Stream Objects
なのでそれらの情報を手がかりに「streamオブジェクト」をテキスト処理で切り出します。
MinGWの環境が手元にあるので、例としてテキスト処理の得意なPerlを使います。4正規表現が扱える言語であればどれでも同じようにできると思います
perl -0777 -ne '$i = 0; while($_ =~ /stream\n([\s\S]*?)\nendstream/g){open($fh, "> data" . $i++ . ".dat") or die("error :$!"); print $fh "$1";}' uncompressed.pdf
実行するとstreamオブジェクトがファイル出力されます。

ファイルの正体を調べてリネームする
streamオブジェクトの正体を調べて正しい拡張子にリネームします。
引き続きMinGWで、ファイル形式を確認するfileコマンドを実行します。5使ったことはないですがWindowsだとWinExChangeなどのツールで拡張子の判別ができるようです
$ file * | sort -V
compressed.pdf: PDF document, version 1.7
data0.dat: ASCII text
data1.dat: lif file
data2.dat: data
data3.dat: ASCII text
data4.dat: ASCII text
data5.dat: ASCII text, with very long lines
data6.dat: JPEG 2000 Part 1 (JP2)
data7.dat: data
data8.dat: data
data9.dat: data
data10.dat: Macromedia Flash data (compressed), version 9
data11.dat: ISO Media, Apple iTunes Video (.M4V) Video
data12.dat: Macromedia Flash data (compressed), version 9
data13.dat: UTF-8 Unicode text, with very long lines
data14.dat: ASCII text
data15.dat: data
data16.dat: data
data17.dat: Microsoft ICM Color Profile
data18.dat: ASCII text
data19.dat: ASCII text
data20.dat: ASCII text
data21.dat: ASCII text
data22.dat: ASCII text
data23.dat: ASCII text
data24.dat: ASCII text
data25.dat: ASCII text
data26.dat: ASCII text
data27.dat: ASCII text
data28.dat: lif file
data29.dat: data
data30.dat: ASCII text, with very long lines
data31.dat: JPEG 2000 Part 1 (JP2)
uncompressed.pdf: PDF document, version 1.7
「data11.dat」が目的の動画ですね。他にも、ファイル内に埋め込まれているJPEG2000形式の画像(data6.datなど)が確認できます。
「data11.dat」を「data11.m4v」にリネームし、再生ソフトで読み込ませたところ、無事再生できました。