ひまつぶし雑記帖

perlでMP4やMOVの縦横サイズを取得する

2025/4/21 [17:44:28] (月) 天気

タイトルのまんまのエントリ。
動機としては、ウチのおひとり様ActivityPubサーバーに動画をアップロードしてみたい。
んで、ActivityPubサーバーは、フォロワーさんのところに投稿(ActivityのJSON)を配送するんだけど、この時に縦横のピクセルサイズが必要っぽい。

動画を扱う時に、鉄板の定番のffmpegでサイズ取得も当然、ほかに解像度変更やファイルサイズの圧縮とかいろいろできるんだけど、レンタルサーバーでffmpegを使えるという話を見たことがなく、当然わたしが利用しているロリポップも使えない。

となると、縦横のピクセルサイズは自力でなんとかする必要がある。
ぐーぐる先生に聞きまくってなんとかなったのでメモ。

「MP4のファイル構造を解説」
https://qiita.com/satken2/items/d14b4113fe3fb5f5597b
↑こちらのサイトで一発解答(多謝!)

MP3とMOVファイルは基本3つのブロックの塊らしい。

サイズタイプ名データ
4バイト4バイト可変


最初の4バイトに入ってるサイズでブロック全体の長さがわかる。
BOXの長さの情報が2^32バイト(=4294967296)を超える場合、最初の4バイトには0x00000001が格納され、その変わりに9バイト~16バイトに実際のBOXの長さが書かれます
ということだけど、今回わたしの場合は10秒もないようなSNSに上げるためだけの動画なのでスルーする。

そのブロックにもろもろの情報が入っているので、欲しいところを取得する。
このブロックのタイプはいったいなんなの?というのは
「QuickTime File Format」
https://developer.apple.com/documentation/quicktime-file-format#//apple_ref/doc/uid/TP40000939-CH204-SW1
↑こちらに全部ある。

ここまでわかればやることはわりと単純。
1)最初の4バイトをみてブロックサイズを取得
2)次の4バイトをみてブロックのタイプを取得
3)必要なタイプだったらそこで情報を取得して終了
 必要なタイプじゃなかったら次のブロックをみにいく

ちょっとハマったのが
各ブロックはデータを持たないものと持ってるものがあるということ。
しょうがないんで、次のブロックを先読みしてタイプ名があるかないかで判定。

以下で欲しい情報が取れた。
わたしが欲しいのはタイプ「tkhd」(たぶん、トラックヘッダーの略)のブロックのデータ部に入ってる幅と高さ。

my @parent = (
'cmov', 'ctts', 'edts', 'esds',
'free', 'ftyp', 'iods', 'junk',
'mdia', 'minf', 'moov', 'mvhd',
'pict', 'pnot', 'rmda', 'rmra',
'skip', 'stbl', 'trak', 'uuid',
'wide');
my @child = (
'fiel', 'mdat', 'rdrf', 'rmcd',
'rmcs', 'rmdr', 'rmqu', 'rmvc',
'wfex', 'cmvd', 'co64', 'dcom',
'elst', 'gmhd', 'hdlr', 'mdhd',
'smhd', 'stco', 'stsc', 'stsd',
'stss', 'stsz', 'stts', 'tkhd',
'vmhd');

open(IMG, $file) || die;
binmode IMG;
my $len; my $type; my $data;
my $width; my $height;
while(1){
    my $buf;
    read(IMG, $buf, 4);
    $len = unpack("N", $buf);
    read(IMG, $type, 4);
    last if ! $type;
    # check next type
    my $has_data;
    seek(IMG,4, 1) || last;
    read(IMG,$buf,4);
    last if ! $buf;
    $buf = quotemeta $buf;
    unless( grep(m!$buf!, @parent) || grep(m!$buf!, @child) ){ 
        $has_data = 1; 
    }
    seek(IMG, -8, 1);
    if( $has_data ){
        $len -= 8;
        last if $len < 0;
        my $begin = tell(IMG);
        read(IMG, $data, $len);
    }
    if($type =~ m!tkhd!){
        my @check =  unpack("x76 n x2 n", $data);
        if( $check[0] && $check[1] ){
            $width = $check[0]; $height = $check[1];
            last;
        }
    }
}



perlはやっぱり凄くて、バイナリファイルも簡単に扱うことができる。
とはいえ、それを扱うスキルがない人間のせいでずいぶん時間がかかってしまった。

これでうちのActivityPubサーバーに動画をあげるための下準備はできた!
…と思ったんだけど、動画ファイルって5秒ぐらいのものでも1M〜2Mもあって慌てた(今さら
わたしはロリポップのビギナーコース。そんなでかいファイルを気楽に上げてたらあっという間に利用できるディスクスペースを食い尽くしてしまう。

なもんで、ここまで作ったけど諦め。きっとそのうち何かの約に立つ、こともある、かな。

image

今の時期、まじでタケノコ美味くて悶絶する。
刺身で美味いのはもちろん、焼きタケノコがもう絶品。
水分を飛ばすイメージでじっくり弱火のフライパン。水分が飛んできたかなと思ったらオリーブオイルを回しかけてタケノコに焼きめをつけて、塩をふたふり。
これだけでいくらでもご飯が食えるし酒が飲める。
マジでオススメ!!!

»電子書籍制作代行についてはこちら

【電子書籍発売中】

doncha.net制作・発行:KindleやiBooks、楽天kobo、BOOK☆WALKERで読む電子書籍

profile

profile

 
doncha.net
contact:
»運営者
@t2aki@tokoroten.doncha.net

ため池

[2025/05/22 19:59]
え?…これ、シリーズってことは好評だったてこと???…SUGEEE MAJIKAYO @@;

[2025/05/22 19:49]
処刑山 ナチゾンビvsソビエトゾンビ
https://www.amazon.co.jp/%E5%87%A6%E5%88%91%E5%B1%B1-%E3%83%8A%E3%83%81%E3%82%BE%E3%83%B3%E3%83%93VS%E3%82%BD%E3%83%93%E3%82%A8%E3%83%88%E3%82%BE%E3%83%B3%E3%83%93%EF%BC%88%E5%AD%97%E5%B9%95%E7%89%88%EF%BC%89-%E3%83%B4%E3%82%A7%E3%82%AC%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB/dp/B08PRSCLGB

アマプラ眺めてたらなんかひどいもの見つけたwwwww
とりあえずウォッチリストにいれておこうか。

[2025/05/22 18:10]
困った時のコレ、というポジション。
初見を観るにはちょっと気合と体力が必要なので避けたい、今まで観た中から選ぶんだけど、込み入ったシナリオはちょっとしんどいし。
という時に、今日時点だとドンソクさんが最強 ...

@t2aki@tokoroten.doncha.net

検索
<<2025/5>>
    123
45678910
11121314151617
18192021222324
25262728293031

リンク

WINDOWS版サウンドノベル
おかえりください PC WINDOWS版サウンドノベル
『おかえりください』体験版