A native iOS video chat app based on WebRTC
This Xcode project is a native wrapper for the Google’s WebRTC Demo. It organizes the WebRTC components into a cocoa pod that can be easily deployed into any Xcode project. The precompiled libWebRTC static library bundled with the pod works with 64-bit apps, unlike prior versions of WebRTC projects where only the 32-bit version was available. Currently, the project is designed to run on iOS Devices (iOS Simulator is not supported).
Included in this Xcode project is a native Storyboard based Room Locator and Video Chat View Controllers:
The following resources were useful in helping get this project to where it is today:
To run the app on your iPhone or iPad you can fork this repository and open the AppRTC.xcworkspace
in Xcode and compile onto your iOS Device to check it out. By default the server address is set to https://apprtc.appspot.com.
If you’d like to incorporate WebRTC Video Chat into your own application, you can install the AppRTC pod:
pod install AppRTC
From there you can look at the ARTCVideoChatViewController
class in this repo. The following steps below detail the specific changes you will need to make in your app to add Video Chat.
WebRTC can communicate securely over SSL. This is required if you want to test over https://apprtc.appspot.com. You’ll need to modify your AppDelegate.m
class with the following:
#import "RTCPeerConnectionFactory.h"
application:didFinishLaunchingWithOptions:
method: [RTCPeerConnectionFactory initializeSSL];
applicationWillTerminate:
method: [RTCPeerConnectionFactory deinitializeSSL];
To add video chat to your app you will need 2 views:
To do this, perform the following:
#import <libjingle_peerconnection/RTCEAGLVideoView.h>
#import <AppRTC/ARDAppClient.h>
ARDAppClientDelegate
and RTCEAGLVideoViewDelegate
protocols:@interface ARTCVideoChatViewController : UIViewController <ARDAppClientDelegate, RTCEAGLVideoViewDelegate>
* `ARDAppClientDelegate` - Handles events when remote client connects and disconnect states. Also, handles events when local and remote video feeds are received.
* `RTCEAGLVideoViewDelegate` - Handles event for determining the video frame size.
@property (strong, nonatomic) ARDAppClient *client;
@property (strong, nonatomic) IBOutlet RTCEAGLVideoView *remoteView;
@property (strong, nonatomic) IBOutlet RTCEAGLVideoView *localView;
@property (strong, nonatomic) RTCVideoTrack *localVideoTrack;
@property (strong, nonatomic) RTCVideoTrack *remoteVideoTrack;
* *ARDAppClient* - Performs the connection to the AppRTC Server and joins the chat room
* *remoteView* - Renders the Remote Video in the view
* *localView* - Renders the Local Video in the view
/* Initializes the ARDAppClient with the delegate assignment */
self.client = [[ARDAppClient alloc] initWithDelegate:self];
/* RTCEAGLVideoViewDelegate provides notifications on video frame dimensions */
[self.remoteView setDelegate:self];
[self.localView setDelegate:self];
[self.client setServerHostUrl:@"https://apprtc.appspot.com"];
[self.client connectToRoomWithId:@"room123" options:nil];
ARDAppClientDelegate
- (void)appClient:(ARDAppClient *)client didChangeState:(ARDAppClientState)state {
switch (state) {
case kARDAppClientStateConnected:
NSLog(@"Client connected.");
break;
case kARDAppClientStateConnecting:
NSLog(@"Client connecting.");
break;
case kARDAppClientStateDisconnected:
NSLog(@"Client disconnected.");
[self remoteDisconnected];
break;
}
}
- (void)appClient:(ARDAppClient *)client didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
self.localVideoTrack = localVideoTrack;
[self.localVideoTrack addRenderer:self.localView];
}
- (void)appClient:(ARDAppClient *)client didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
self.remoteVideoTrack = remoteVideoTrack;
[self.remoteVideoTrack addRenderer:self.remoteView];
}
- (void)appClient:(ARDAppClient *)client didError:(NSError *)error {
/* Handle the error */
}
RTCEAGLVideoViewDelegate
- (void)videoView:(RTCEAGLVideoView *)videoView didChangeVideoSize:(CGSize)size {
/* resize self.localView or self.remoteView based on the size returned */
}
If you’d like to contribute, please fork the repository and issue pull requests. If you have any special requests and want to collaborate, please contact me directly. Thanks!
The following are known issues that are being worked and should be released shortly:
use_frameworks!
declared in your PodFile
you may get the error message transitive dependencies that include static binaries
. To resolve the issue you can add the following to your PodFile
pre_install do |installer|
def installer.verify_no_static_framework_transitive_dependencies; end
end