« video タグからのリクエスト | ホーム | IPC::Cmd では空文字のパラメータを与えられない »

2012年1月27日

video タグからの要求に応える

Mojolicious でサーバ morbo を起動している。

video タグに指定した src の URL が public に置かれた静的コンテンツのときは、なんの問題もなくビデオ( mp4 )が再生された。

ただしビデオソースを public な場所に置く事に不都合な事情があったため、 video タグから要求された URL には、アクションに結びつけ、アクションはビデオのソースをバッファして、レスポンスに直接書き出すようにしたかった。

Safari (の video タグのヘルパー?は AppleCoreMedia というエージェントだった)からのリクエストは Range つきのリクエストで、これには Content-Range でもって、要求されたとおりのバイト範囲を部分的に返さないといけない事がわかった。(サーバは Range を無視できるにもかかわらず。)ビデオのソースを全部読み込んで、一気に返す、といった乱暴な手続きでは駄目だった。

# FIXME - support whole patterns of "Range" parameter
sub video {
    my $c       = shift;
    my $file    = shift;
    my $type    = shift;
    my $size    = -s $file;

    my ($buffer, $start, $end);
    my  $request_range = $c->req->headers->range;
    if( $request_range and $request_range =~ /bytes=(\d+)-(\d+)/ ){
        ($start, $end) = ($1, $2);
        $c->res->headers->status('206 Partial Content');
        $c->res->headers->content_range(
            sprintf('bytes %d-%d/%d', $start, $end, $size));
    }else{
        ($start, $end); = (0, $size -1);
        $c->res->headers->status('200 OK');
        $c->res->headers->content_length($size);
    }

    # read range
    my $handle = IO::File->new;
    $handle->open($file, "r");
    $handle->seek($start, 0);
    $handle->read($buffer, $end - $start + 1, 0);
    $handle->close;

    # send contents
    $c->render( data => $buffer, format => $type );
}

レスポンスを自前で組み立てないといけない? このへんは WAF のほうで面倒見てくれてもいいと思うのだけれども。

ただし、このやりかたも Firefox に対しては駄目だった(ちなみに Google Chrome はOKだった。)

コメントする

OpenID対応しています OpenIDについて

このブログ記事について

このページは、hiroakiが2012年1月27日 22:48に書いたブログ記事です。

ひとつ前のブログ記事は「video タグからのリクエスト」です。

次のブログ記事は「IPC::Cmd では空文字のパラメータを与えられない」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。