しかしUSB 接続故にframe rate が出ません。空手の撮影では画質よりもframe rate です。
USB 以外だとiMac だとthunderbolt になります。Intensity Extreme というthunderbolt
接続のHDMI キャプチャ装置を買いました。
買ったはいいが今度は困りました。
XactiとかそこらにコンデジとかみんなHDMI 端子ついてるからキャプチャできるだろ
と思っていたら。実はカメラの映像をリアルタイムに出力できません。
それはどうやらHDMIスルーアウトとか呼称してるようです。
てことでHDMIスルーアウトできるカメラも購入です。
Sony HDR-CX270V とかいうのを購入しました。
ソニーのハンディカムはだいたいがHDMIスルーアウトできるようです。
まず困ったのはthunderbolt はセンシティブすぎてつながってるのかわかりませんでした。
繋いだらあんまり動かなさいという用途で使うものですようね。バンバン抜き差しは危ない感じです。
目的は
- 道場のust の中継
- 中継しながらの録画
案の定Intensity Extreme は一個アプリが開いちゃうと他のアプリは動画を取れません。
てことで
Intensity Extreme ----> Camtwist ---> 録画アプリ
+----> Ustream Producer
て感じなのをとりあえずやりました。
まず困ったのはそもそもIntensity Extreme で取り込むのが大変....
解像度、フレームレートがばしっと設定されないと取り込めません。HDMI とやりとりして
勝手にやってくれるなんて素敵機能はいっさいありません。
とりあえず60fps で取り込むのが目的なので カメラ側で出力、720p 60fps で設定。
そしてCamtwist でも同様に 720p 60fps で取り込んだら
Preview でみれん。59.94 なら取り込めるようです。
そもそも60fps と 59.94 を分けてる機器なんてあんのか?と思いつつ。
次にCamtwist で 720p かつ60fps で出力できるようにしないといけません。
Preferences-> General
fps と Video Size をぽちっと変更。
これあってないとうまく出力できませんめんどくさすぎます。
次にUstream Producerです。
ソース設定でCamtwist の解像度をあわせないといけません。
720pなので 1280x720 です。
で最後に録画です。ここも苦労しました。
まず、仮想カメラがアプリ側は32bitアプリでしか見えない。そして、そのへんに転がってるアプリは
fps を勝手に落としやがります。
てことで適当に自分で書きました。ruby-cocoa でいまどきは macruby とかのほうがいいんでしょうが、32bit 有効にしてbuild してぶっこむのが面倒なのでAPI リファレンスみながら適当に超適当です。
% cat cap_video.rb require "osx/cocoa" ['AppKit','QTKit','QuartzCore','CoreVideo'].each{|name| OSX.require_framework name } require "fileutils" include OSX class AppDel < NSObject def captureOutput_didFinishRecordingToOutputFileAtURL_forConnections_dueToError(out,url,conn,err) p "call?" p out.recordedFileSize p :conn p conn p QTStringFromTime(out.recordedDuration) p err.localizedDescription end end class CapVideo def get_input_device_by_name(name) device = (QTCaptureDevice.inputDevicesWithMediaType QTMediaTypeVideo) device.to_a.each{|x| if x.localizedDisplayName.to_s =~/#{name}/ return x end } end def capture(path) device = get_input_device_by_name("CamTwist") input = QTCaptureDeviceInput.alloc.initWithDevice(device) output = QTCaptureMovieFileOutput.alloc.init url = OSX::NSURL.fileURLWithPath_ path p url.path FileUtils.rm(url.path.to_s) if File.exists?(url.path.to_s) session = QTCaptureSession.alloc.init @session = session session.addInput_error(input, nil) session.addOutput_error(output,nil) @out = output @session.startRunning output.recordToOutputFileURL(url) begin NSRunLoop.currentRunLoop.run rescue SignalException=>e p e output.recordToOutputFileURL(nil) end stop sleep 0.1 p "aaa?" @session.release output.release input.release end def stop @session.removeOutput(@out) @session.stopRunning end Thread.abort_on_exception = true a = CapVideo.new a.capture(ARGV[0].chomp) % arch -i386 /usr/bin/ruby cap_video2.rb ~/Movies/cap_video-test.mov
ポイントは QTCapture するには NSRunLoop.currentRunLoop.run とかいうのを
走らせて上げないとcapture できません。ここではまりました。
AVFoundation のほうがNSRunLoop.currentRunLoop.run なんてものもいらないし
細かく設定できていいんですが、32bit 版では使えません。
32bit 版では出てるAPI が64bit版では出てないみたいで、それで仮想カメラデバイスが作れないようです。
まぁそのあたりが解決するとこんなうっとおしいのも解決されそうです。
intesity 側で入力/出力を変換してくれるとかもあるようです。まぁあまり使わないのでけど。
とりあえずこんなかんじで。