文鎮iPhone救出計画 〜ネットワークカメラ化〜
家で余っているiPhoneをネットワークカメラにしてみました。ネットワークカメラを買うまでも無いけどちょっとしたときに使いたい。作業をしながら鍋の煮え具合を見たいときに使えます。配信用のサーバーを用意する必要もないので便利です。
iOSの画面をキャプチャして配信することもできるので社内でのUIテストとかいいかも知れないですね。ネットワークは社内や家庭内LANでの運用を想定しています。
ソースコード
アプリ自体の公開の予定はありませんが、github(https://github.com/shogo4405/lf.swift/tree/master/lf )上でソースコードを公開しています。スニペットはこちら、
// Cocoapodを使う場合のインストール source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! pod 'lf', '~> 0.2'
// frameworkのインポート import lf final class LiveViewController: UIViewController { var httpService:HTTPService! var httpStream:HTTPStream! override func viewDidLoad() { super.viewDidLoad() httpStream = HTTPStream() // attachCameraの代わりにスクリーンキャプチャーして送ることができるよ //httpStream.attachScreen(ScreenCaptureSession()) httpStream.syncOrientation = true httpStream.attachCamera(AVMixer.deviceWithPosition(.Back)) // helloを指定するとhttp://ip.addr:8080/hello/playlist.m3u8 としてアクセスできるようになる。 httpStream.publish("hello") httpService = HTTPService(domain: "", type: "_http._tcp", name: "lf", port: 8080) httpService.startRunning() httpService.addHTTPStream(httpStream) view.addSubview(httpStream.view) } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() httpStream.view.frame = view.frame } }
技術的なお話
ネットワークカメラ化にあたっては、HLS(HTTP Live Streaming)の配信環境を自前で構築することで実現しています。
- NSNetServiceクラスを利用したHTTPサーバーの実装
- カメラ映像をH264エンコードして.tsファイルを作成する
- HTTPサーバー経由での.tsを配信する
HLSの仕組みを利用することでHLS対応ブラウザー(Microsoft Edge, Safari, モバイルChromeなど)で映像の視聴が可能になります。
NSNetServiceクラスを利用したHTTPサーバーの実装
NSNetServiceクラスを利用します。publishWithOptionsメソッドにNSNetServiceOptions.ListenForConnections指定することでサービスとして機能します。
// ポート番号: 8080, TCPとしてリスンする var service:NSNetService = NSNetService(domain: "", type: "_http._tcp", name: "", port: 8080) service.delegate = self service.publishWithOptions(NSNetServiceOptions.ListenForConnections)
NSNetServiceDelegateプロトコルのnetService(sender: NSNetService, didAcceptConnectionWithInputStream inputStream: NSInputStream, outputStream: NSOutputStream)メソッドで、inputStreamとoutputStreamというソケット通信に利用するインスタントの組み合わせが得られるので初期化していきます。
カメラ映像をH264エンコードして.tsファイルを作成する
主にこのようなことをやって.tsファイルを作成していきます。ライブラリー公開先のAVMixerクラス, AVCEncoderクラス, TSWriterクラスで分担して処理を行っています。
- AVCaptureSessionを利用してCMSampleBufferを取得する
- VTCompressionSessionを利用して生の映像をH264エンコード処理する
- H264データをPacketizedElementaryStream化の後TransportStreamに変換して.tsとして書き出す
HTTPサーバー経由での.tsを配信する
HTTPリクエストに併せて.tsを返すコードを書き出すことでHLSの視聴が可能になります。 HLSのRFCを参考にしました。draft-pantos-http-live-streaming-06 - HTTP Live Streaming