2012年11月7日水曜日

Intensity Extreme をbuy now

道場での日々の稽古の撮影としていままではQcam Orbit を使ってきました。
しかし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 側で入力/出力を変換してくれるとかもあるようです。まぁあまり使わないのでけど。



とりあえずこんなかんじで。





zenback