UstreamのテロップをPHP GDで自動生成する方法

   このエントリをはてなブックマークに登録    2011/9/28-1

兵庫県で25日に開催された第50回全日本女子剣道選手権大会のネット中継を行って来ました。 今回は会場からUstream、ニコニコ生放送、YouTube、Twitter、Flickr、Facebook、大会公式ブログを利用した情報提供を行いました。

Ustreamでの試合中継や、Twitter、Facebook、大会公式ブログ、Flickr、YouTubeを利用することそのものは、従来通りだったのですが、今回はUstream用にテロップを自動生成するという部分が私の中での新しい試みでした。

出来上がったテロップを利用した中継動画は、以下のような感じです。 Ustreamで録画したものをYouTubeに転送して公開したものです。

テロップの作り方

今回は、PHP GDでテロップを作成するスクリプトを生成しました(PHP GDの基本的な使い方は「PHP GDプログラミング」をご覧下さい)。

PHP GDを利用したのは、Web上から最新版のテロップが取得できるようにするためです。 全日本女子剣道選手権大会では、試合会場が2会場だったので、Ustream用カメラとPCも2箇所に設置したのですが、それぞれのPCに最新版テロップをインストールしやすくするには、Web経由で最新テロップを自動生成できる仕組みが便利でした。

前景画像用のベースとなる画像

まず最初に、ベースとなる背景画像をPhotoshopで作りました。 この上に選手の顔写真と名前等の文字情報をPHP GDで追加します。

今回のベース用デザインのポイントは、下部の赤白ラインです。 最初に左側から入場する選手が赤で右側から入場する選手が白なのですが、中継を行っていると選手名だけではわかりにくいという意見を去年の中継中に頂いたので、赤白がわかりやすいように中央で区切られた赤と白のラインを一番下に細く入れるというデザインで作りました。

ベース画像の読み込み

PHP GDでベースとなる画像を読み込んでImageオブジェクトを生成します。



$img = ImageCreateFromPNG('baseimage.png');
ImageAlphaBlending($img, false);  
ImageSaveAlpha($img, true);  


Ustreamの前景画像は、多くの部分が透過となっている必要がありますが、 ImageSaveAlpha($img, true)の部分がPNG画像を保存する際に透過情報を保持するアルファチャネル情報を保存することを宣言しています。 ImageSaveAlpha()をtrueで利用するためには、ImageAlphaBlending($img,false)が必要なので、それを行っています。

文字情報の追加

文字列の追加にはImageTTFTextを利用しました。



$white = ImageColorAllocateAlpha($img, 0xff, 0xff, 0xff, 0);

ImageTTFText($img, $fontsz, 0, $x, $y, $white, $pathtottf, $text);


$fontszはフォントのサイズです。 $xと$yは、文字の位置を表しています。 $whiteの生成は一度だけ行えば、その後何度も利用可能です。 $textは、表示させたい文字列を入れて下さい。

$pathtottfは、True Type Fontファイルへのパスです。 True Type Fontの場所は、MacosXであれば /Library/Fonts/ や /System/Library/Fonts/ や ~/Library/Fonts/ などが一般的です。 WindowsではWindows\Fontsなどをご覧下さい。 Linuxやその他UNIX系OSの場合は、どこにインストールされているか各自で調べるか、システム担当者に聞いて下さい(投げやりでごめんなさい。でも、make installをどこにしたかによると思うので。/usr/shareあたりを探るか、findやlocateを使って探して下さい)。

テロップ内に貼付けるテキストの大きさが必要になることもあると思います。 特定の文字列がどれだけの大きさになるのかを知るには、ImageTTFBBoxを利用します。



$bbox = ImageTTFBBox($fontsz, 0, $pathtottf, $text);
$x0 = $bbox[6];
$y0 = $bbox[7];
$x1 = $bbox[2];
$y1 = $bbox[3];

$width = $x1 - $x0;
$height = $y1 - $y0;


上記サンプルコードの中の$widthと$heightは、文字列が取る幅と高さです。

顔写真の追加

顔写真の追加は、以下のように行いました。 「pictures」というディレクトリ(フォルダ)に選手の顔写真を「番号.jpg」というファイル名で保存してあります。



$face = ImageCreateFromJPEG('pictures/' . $num . '.jpg');
$face_width = ImageSx($face);
$face_height = ImageSy($face);
ImageCopyResampled($img, $face, $FACE_X,$FACE_Y,0,0,
                   76, 76, $face_width, $face_height); 


ImageSxは元画像の幅、ImageSyは元画像の高さをそれぞれ取得しています。 ImageCopyResampledは、指定された画像をリサイズした上で、ImageCreateFromPNGで生成された$imgリソースに対して描画を行っています。

PNGとしての保存

このような組み合わせでテロップが簡単に作れますが、最終的にこの画像がWeb経由で保存できるようにしました。

Web経由で、このPHP GDスクリプトが呼び出された時に、ファイル名を指定して保存できるように、Content-Dispositionを利用しています。 以下が、PHP GDスクリプトの最後の数行です。



header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="ustimg' . $match . '.png');

ImagePNG($img);


$matchは、試合番号を入れています。 これによって、試合毎に違ったファイル名のUstream用テロップがダウンロード可能です。

トーナメント戦では、1回戦以降の対戦カードが事前に作れないので、どうしても現場で作る必要がありますが、決勝が近づくにつれてテロップを生成するのに費やせる時間が減ります。 そのため、こういった仕組みがないと、後ろにいくほど辛くなります。

過去の経緯

去年の大会では、試合開始直前にUstreamの機能を利用して文字列として試合内容を打ち込んでいたので、Ustream配信担当者が結構大変でした。

で、それをどうにかできないかということで、私が一括してPhotoshopで作るという荒技に出ました。 それをやりつつUstream中継用テロップで顔写真を最初に入れたのは、4月に名古屋で行われた第9回全日本選抜剣道八段優勝大会でした。

最初のうちは顔写真を入れていなかったのですが、途中からテロップに顔写真を入れるようにしました。 このときは、Photoshopでテロップを毎回作っていたので結構大変でした。



その後、7月に行われた第3回全日本都道府県対抗女子剣道優勝大会で、団体戦内での各ポジションでの結果をテロップに入れるために即席のPHP GDプログラムを書いて、それを改造することで今回の顔写真入りテロップ生成スクリプトを作りました。

音声の工夫

今回のもう一つの試みは、音声品質の上昇です。 30mのCANONケーブルとマイクを利用して第一会場のすぐ近くにマイクを設置してみました。

以下が延長マイクを利用しなかった第二会場の録画映像ですが、第一会場と比べると竹刀がぶつかり合う音や、選手の声に違いがあるのがわかります。

音声の位置というのも大事なんだなぁと実感しました。 まあ、音響を専門の方々にとっては当たり前だと思いますが、こういった細かいところを改善する試みも、ここ1年半ぐらい色々とやっています。

こういうのって誰も教えてくれないので、我流で色々実験してみないといけないのがツライところではありますが。

最後に

ネット中継は少人数のスタッフで行っており、限られた時間の中で行える作業が限られているので、出来るだけ高品質なネット中継を行うためには、ITを利用して効率化する必要性を感じています。 そこで、今回行ったのがテロップの自動生成です。

次の中継では、テロップの自動生成だけではなく、もうちょっと色々と自動化したいと考えています。

体育館で1日限りのネット回線をゼロから安価に用意する方法や、配線、試合中継ノウハウが徐々に溜まりつつあるのですが、まだまだ色々と効率化及び品質上昇をしたいなぁと思う今日この頃です。

その他の剣道関連記事

   このエントリをはてなブックマークに登録