Skip to content

Instantly share code, notes, and snippets.

@ykst
Created January 28, 2015 14:05
Show Gist options
  • Save ykst/d54cd1f40e93087646be to your computer and use it in GitHub Desktop.
Save ykst/d54cd1f40e93087646be to your computer and use it in GitHub Desktop.
iOSでWebRTCアプリを作ってみる (組み込み編)

iOSでWebRTCアプリを作ってみる (組み込み編)

webrtcのObj-Cポーティングもそろそろ落ち着いてきた(?)頃合いなので、iOSの実機にWebRTCを組み込んでみます。 本記事中でSVNのバージョンは http://webrtc.googlecode.com/svn/trunk のr7864を使用しています。

まずはビルド

この記事でも書きましたが、webrtcのiOSビルドは、 How to get started with WebRTC and iOS without wasting 10 hours of your life ↑この記事が親切かつ、まめにアップデートされているのでオススメです。

ですが、忙しい人のためにコマンドだけざっくり列挙してみます。 ワーキングディレクトリは~/webrtcとしています。

cd ~/webrtc
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=`pwd`/depot_tools:$PATH
gclient config --name src http://webrtc.googlecode.com/svn/trunk
echo "target_os = ['ios']" >> .gclient
gclient sync --force
export GYP_GENERATORS="ninja"
export GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 libjingle_objc=1 OS=ios target_arch=armv7"
export GYP_GENERATOR_FLAGS="$GYP_GENERATOR_FLAGS output_dir=out_ios"
export GYP_CROSSCOMPILE=1
pushd src
gclient runhooks
ninja -C out_ios/Release-iphoneos AppRTCDemo
popd
libtool -static -o src/out_ios/Release-iphoneos/libWebRTC-ios.a src/out_ios/Release-iphoneos/*.a
strip -S -x -o src/out_ios/Release-iphoneos/libWebRTC-ios-min.a -r src/out_ios/Release-iphoneos/libWebRTC-ios.a
cp src/out_ios/Release-iphoneos/libWebRTC-ios-min.a .
cp -r src/third_party/libjingle/source/talk/app/webrtc/objc/public .

ビルドに大体30分ぐらい掛かると思います。 コマンドの最後で今回組み込むlibWebRTC-ios-min.aとObjective-Cヘッダのpublicディレクトリをカレントディレクトリに持ってきています。

なかなかスムーズにはいかないと思うので個人的にハマった所を少し説明します。

複数のProvisioning Profileでエラーになる

普通はProfileを複数管理している事が多いと思うので、↓のエラーが出るかもしれません。

AssertionError: Multiple codesigning fingerprints for identity: iPhone Developer

これもこの記事の中で詳しく解説してあります。

  • 手っ取り早い対処法

src/build/common.gypiにあるiPhone Developerを空文字にします。

'iPhone Developer' -> ''

Xcodeのパスに空白が入っていてエラーになる

Xcodeを同じディレクトリにバックアップしていたりすると良くあるパターンです。

  • 対処法

必要に応じてXcode.appのパスを変更して、下記コマンドを叩いて修正します。

$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

ライブラリがビルド出来れば後は組み込むだけです。

ライブラリをXcodeプロジェクトに取り込む

適当にXcodeでiOSアプリプロジェクトを立ち上げて、先ほど作ったlibWebRTC-ios-min.apublicを放り込みます。 Linked Frameworks and Librariesに依存しているフレームワークを追加します。

libstdc++.dylib
libicucore.dylib
GLKit.framework
libsqlite3.0.dylib
AVFoundation.framework
libWebRTC-ios-min.a

注意点として、libWebRTC-ios-min.aはarmv7のライブラリになっているためValid Architecturesをarmv7だけにする必要が有ります。 また、Build Active ArchitecturesNOにしておいてください。 (Cocoapodsのライブラリに対してこの設定を一括で適用する際はこの記事も参考にしてみてください。)

とりあえずカメラ映像を出す

ここまででビルドが通ったら、おもむろにローカルストリームでフロントカメラの映像を出してみましょう。 適当なUIViewControllerのviewDidLoadあたりで次のようなコードを入れます。

#import <AVFoundation/AVFoundation.h>

#import "RTCEAGLVideoView.h"
#import "RTCMediaStream.h"
#import "RTCPeerConnectionFactory.h"
#import "RTCMediaConstraints.h"
#import "RTCPeerConnection.h"
#import "RTCPair.h"
#import "RTCVideoCapturer.h"
#import "RTCVideoTrack.h"
#import "RTCAudioTrack.h"
#import "RTCICECandidate.h"
#import "RTCSessionDescription.h"
#import "ViewController.h"

@implementation ViewController {
    RTCMediaStream    *_local_media_stream;
    RTCPeerConnection *_peer;
}

- (void)viewDidLoad 
{
    [super viewDidLoad];

    RTCPeerConnectionFactory *pc_factory = [RTCPeerConnectionFactory new];

    _peer = [pc_factory peerConnectionWithICEServers:nil constraints:nil delegate:nil];

    RTCEAGLVideoView * local_view = [[RTCEAGLVideoView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:local_view];

    _local_media_stream = [pc_factory mediaStreamWithLabel:@"ARDAMS"];

    NSString *camera_id = nil;

    for (AVCaptureDevice *dev in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] ) {
        if (dev.position == AVCaptureDevicePositionFront) {
            camera_id = [dev localizedName];
            break;
        }
    }

    RTCVideoCapturer *capturer = [RTCVideoCapturer capturerWithDeviceName:camera_id];
    RTCVideoSource *source     = [pc_factory videoSourceWithCapturer:capturer constraints:nil];
    RTCVideoTrack *video_track = [pc_factory videoTrackWithID:@"ARDAMSv0" source:source];

    [_local_media_stream addVideoTrack:video_track];
    [video_track addRenderer:local_view];
}
@end

ここでは基本的にWeb APIのgetUserMediaでvideoタグのsrcを設定しているのと同じ事をしています。 Obj-CのAPIもWeb APIと大体同じなので、それほど苦労せずに後は実装していけるのではないかと思います。 (ちなみに画面サイズは適当です)

更に忙しい人のために

ここまでの時点のXcodeプロジェクトを上げてあります。参考にどうぞ。

ピア通信したいけど、サーバー邪魔くさい・・・

いつもの如くWebRTCではシグナリングサーバーとICEサーバーを別途用意しないと満足に遊べないという独特の面倒くささがありますが、 ここでふと思い直してみると、

  • iOSアプリは普通にhttp/websocketサーバーとして使う事が出来る (CocoaHTTPServer etc.)
  • LANではICEサーバーが要らない (自分自身がICE Candidateになるため)

というわけで、実はiOSアプリが一つあればLAN上にビデオチャットサービスを展開する事が出来ます。 Androidではやった事が無いですが、そっちも同じようにいけると思います。

LANだけという制限は有りますが、サーバーとピアを統合することで何か面白いアプリが作れるかもしれません。 _機会があれば_サーバー組み込みバージョンも記事にしようと思います。機会があれば

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment