プロ生ちゃんと一緒にiPhoneから生放送!
iOS向けのライブ配信ライブラリーを書いてみた - Thousand Yearsで制作したRTMPなライブラリーGitHub - shogo4405/lf.swift: iOS用のライブ配信ライブラリーに映像効果を適用する機能をつけたので紹介します。
映像効果に利用するのは、プログラミング生放送でお馴染みのプロ生ちゃん(プロ生ちゃん(暮井 慧) | プログラミング生放送)です。プロ生ちゃんのpngとカメラ映像を合成して一緒に生放送できるようになります。
映像効果用クラスの作成
自作の映像効果を適用するためのVisualEffectクラスを継承したクラスを用意します。画像ファイルとカメラ映像を合成するための、主なポイントは以下の通り。
- CISourceOverCompositingのCIFilterの用意。ライブラリーの処理上CIImageになっているのでこちらのアプローチによる画像の合成を行います。
- カメラ画像(CIImageのextent)情報をもとにしてカメラ画像と同解像度の画像を作成する。この処理で出来た画像にプロ生ちゃん(合成したい画像)を描画しておく。
- プロ生ちゃんの画像をinputImage。カメラ映像をinputBackgroundImageとしてCIFilterを適用する
final class PronamaEffect: VisualEffect { // 1. CISourceOverCompositingなフィルターの準備 let filter:CIFilter? = CIFilter(name: "CISourceOverCompositing") // 2. カメラ映像と同解像度の画像の作成 var extent:CGRect = CGRectZero { didSet { if (extent == oldValue) { return } UIGraphicsBeginImageContext(extent.size) let image:UIImage = UIImage(named: "Icon.png")! image.drawAtPoint(CGPointMake(50, 50)) pronama = CIImage(image: UIGraphicsGetImageFromCurrentImageContext(), options: nil) UIGraphicsEndImageContext() } } var pronama:CIImage? override init() { super.init() } // 3. フィルターの適用 override func execute(image: CIImage) -> CIImage { guard let filter:CIFilter = filter else { return image } extent = image.extent filter.setValue(pronama!, forKey: "inputImage") filter.setValue(image, forKey: "inputBackgroundImage") return filter.outputImage! } }
映像効果の適用
自作した映像効果を適用するコード
var effect:VisualEffect = VisualEffect() var rtmpConnection:RTMPConnection = RTMPConnection() var rtmpStream:RTMPStream = RTMPStream(rtmpConnection: rtmpConnection) // カメラソースの追加 rtmpStream.attachCamera(AVMixer.deviceWithPosition(.Back)) // -- エフェクトの登録 rtmpStream.registerEffect(effect) // -- エフェクトの解除 // rtmpStream.unregisterEffect(effect) // プレビュー映像の表示(映像効果が適用された状態で表示する) view.addSubview(rtmpStream.view)
配信開始
// イベントハンドラの登録。接続が確立したことを確認するためにハンドラ内で行う rtmpConnection.addEventListener(Event.RTMP_STATUS, selector:#selector(HogeController.rtmpStatusHandler(_:)), observer: self) // サーバーへの接続 rtmpConnection.connect("rtmp://path/to/server") func rtmpStatusHandler(notification:NSNotification) { let e:Event = Event.from(notification) if let data:ASObject = e.data as? ASObject , code:String = data["code"] as? String { switch code { case RTMPConnection.Code.ConnectSuccess.rawValue: // 配信開始! rtmpStream!.publish("streamName") default: break } } }
ソースコード
説明のために端折って書いています。ソースコードの全部はこちらで参照できます。
lf.swift/LiveViewController.swift at master · shogo4405/lf.swift · GitHub