この記事について
リコーが販売している全天球カメラ THETA の Plugin のサンプルをいじり、録画した動画のファイルサイズが削減できないか試してみます。
THETA
THETA とは?
リコーが販売している全天球カメラです。
上位モデル(V/Z1)は、内部のOSとして Android が試用されており、Androidアプリ(THETA用語では"Plugin")を開発すれば THETA を自由に操作できるという、素敵なものです。
なお、下位モデル(S/SC/SC2)でも、Pluginほどの自由度はないですが、内部で動作している REST API を使用すればそれなりの操作はできるようです(試していない)。
詳細は以下をご参照ください。
- THETA の製品情報
- https://theta360.com/ja/
- THETA の開発の情報
- https://api.ricoh/products/theta-jp/
- https://qiita.com/organizations/theta-plugin
THETA の困りごと
THETAを使ってみて悪い意味で驚いたことは、録画した動画ファイルのサイズが巨大であることでした。
撮影する内容にもよると思いますが、デフォルトの4K・高ビットレートの設定で5分の動画を撮影したところ、ファイルサイズは約1.5GBというサイズになりました。
画質はかなり良いですし、全天球(左右360度・上下360度)分の情報量がありますので、妥当といえば妥当なのかもしれません。
が、画質を絞ってもう少しファイルサイズを下げたいなー、と考え、どこまでファイルサイズを下げられるか試すことにしました。
THETA の動画のファイルサイズを下げてみる
やってみること
今回は THETA V を使用し、小さいファイルサイズで録画できる Plugin を作ってみます。
カメラ撮影の plugin のサンプルである https://github.com/ricohapi/theta-plugin-camera-api-sample をベースに、ちょっと内部をいじってみます。
デフォルト状態でのファイルサイズを調べる
ソースコード CameraFragment.java
を見てみると、このサンプルでは、4K画質・ビットレート56Mbps・フレームレート30fpsで、最大25分撮影していることがわかります。
// Sample:Set up 4K Equi videos
mParameters.set("RIC_PROC_STITCHING", "RicStaticStitching");
mParameters.set("RIC_SHOOTING_MODE", "RicMovieRecording4kEqui");
CamcorderProfile camcorderProfile = CamcorderProfile.get(mCameraId, 10013);
mParameters.set("video-size", "3840x1920");
//(中略)
mMediaRecorder.setVideoEncodingBitRate(56000000); // 56 Mbps
mMediaRecorder.setVideoFrameRate(30); // 30 fps
mMediaRecorder.setMaxDuration(1500000); // max: 25 min
とりあえず、1分間録画したときのファイルサイズを見るため、ちょっといじります。
//mMediaRecorder.setMaxDuration(1500000); // max: 25 min
mMediaRecorder.setMaxDuration(60000); // max: 1 min
これで録画したところ、1分間の動画のファイルサイズは 約450MB ほどでした。
ファイルサイズを削るためにあれこれやってみる
「見るに耐えうる画質」かつ「モバイル回線で送信できるレベルのファイルサイズ」を目標に、画質を調整してみます。
画質の調整
画質は、4K(3840x1920) から 2K(1920x960) に落とし、ビットレートは 1Mbps, フレームレートは 9fps まで落としてみます。
ビットレート・フレームレートはいくつか試してみたのですが、個人的にはこれくらいが「最下限」の値だと思います。
変更後
mParameters.set("RIC_SHOOTING_MODE", "RicMovieRecording2kEqui");
CamcorderProfile camcorderProfile = CamcorderProfile.get(mCameraId, 10014);
mParameters.set("video-size", "1920x960");
//(中略)
mMediaRecorder.setVideoEncodingBitRate(1000000); // 1 Mbps
mMediaRecorder.setVideoFrameRate(9); // 9 fps
mMediaRecorder.setMaxDuration(60000); // max: 1 min
音声について
さらに、デフォルトでは音声が .wav
形式で保存され、それが動画とマージされるような挙動となっているのですが、.wav
の音声が使われるとそれだけでかなりファイルサイズが増加するようなので、.wav
の音声は使わないようにしてみます。なお、.wav
を使わないでも動画に音声は保存されているようです。
変更前
mMp4filePath = String.format("%s/plugin_%s.MP4", DCIM, dateTime);
mWavfilePath = String.format("%s/plugin_%s.WAV", DCIM, dateTime);
String videoWavFile = String.format("%s,%s", mMp4filePath, mWavfilePath);
mMediaRecorder.setOutputFile(videoWavFile);
//(中略)
mInstanceRecordMP4 = new File(mMp4filePath);
mInstanceRecordWAV = new File(mWavfilePath);
//(中略)
Box box = new Box();
box.formBox(mMp4filePath, mWavfilePath, mBoxCallback);
//(中略)
// cancel recording
mInstanceRecordMP4.delete();
mInstanceRecordWAV.delete();
//(中略)
public File[] getRecordFiles() {
File[] recordFiles = {mInstanceRecordMP4, mInstanceRecordWAV};
return recordFiles;
}
変更後
変数 mWavfilePath
mInstanceRecordWAV
を使っている部分を片っ端から削除します。
mMp4filePath = String.format("%s/plugin_%s.MP4", DCIM, dateTime);
//mWavfilePath = String.format("%s/plugin_%s.WAV", DCIM, dateTime);
//String videoWavFile = String.format("%s,%s", mMp4filePath, mWavfilePath);
//mMediaRecorder.setOutputFile(videoWavFile);
mMediaRecorder.setOutputFile(mMp4filePath);
//(中略)
mInstanceRecordMP4 = new File(mMp4filePath);
//mInstanceRecordWAV = new File(mWavfilePath);
//(中略)
Box box = new Box();
//box.formBox(mMp4filePath, mWavfilePath, mBoxCallback);
box.formBox(mMp4filePath, "", mBoxCallback);
//(中略)
// cancel recording
mInstanceRecordMP4.delete();
//mInstanceRecordWAV.delete();
//(中略)
public File[] getRecordFiles() {
//File[] recordFiles = {mInstanceRecordMP4, mInstanceRecordWAV};
File[] recordFiles = {mInstanceRecordMP4};
return recordFiles;
}
変更後の Plugin を動かす
この修正を行った Plugin で動画を録画してみたところ、1分間の動画のファイルサイズを 約8MB まで落とすことができました。 450MB→8MBですから、だいぶファイルサイズを削減できたのではないでしょうか。
当初の動画と比べると、画質はあからさまに落ちましたし、ブロックノイズも増えました。一言でいうと、光回線の画質がLTE回線の画質に落ちた、といった感じでしょうか。が、何が映っているか判断できるレベルは保っていると思います。
修正後のソースコード
githubに置いておきました。
https://github.com/nara256/theta-plugin-camera-api-sample/tree/low_resolution
まとめ(ではないけど...)
THETA は楽しいねー。
plugin でアレコレ操作してみると多くの可能性を感じます。
これからもっと遊んでみる予定です。
最後に
theta SDK を細部まで確認しないままテキトーに実装していますので、なにかお気づきな点や、変なことをやっているようなことがあればご指摘いただけると幸いです。