This is the cine.io iOS SDK. This library allows you to do real-time live video streaming from your iOS device to any other device that supports RTMP or HLS streaming (iOS, Android, web).
The easiest way to use the SDK is via CocoaPods. Create a new XCode project with a file named Podfile
that contains at least the following:
platform :ios, '7.0'
pod 'cineio-ios', '~> 0.5'
Then, install the Pod by running the pod install
command:
pod install
Then you can open the project using the <project>.xcworkspace
file:
open <project>.xcworkspace
Check out the cineio-ios-example-app repository for a working example of a simple application that uses this SDK.
#import <cineio/CineIO.h>
CineClient *client = [[CineClient alloc] init];
Most of the APIs on the CineClient require that the projectSecretKey
property
has been set. In addition, the getProjectsWithCompletionHandler
API requires
that the masterKey
property has been set. Be sure to set the appropriate
properties for the APIs you wish to use.
client.masterKey = @"YOUR_ACCOUNT_MASTER_KEY";
client.projectSecretKey = @"YOUR_PROJECT_SECRET_KEY";
[client getProjectsWithCompletionHandler:^(NSError *err, NSArray *projects) {
for (id object in streams) {
CineProject *project = (CineProject *)object;
// do something
}
}];
[client getProjectWithCompletionHandler:^(NSError *error, CineProject *project) {
// do something
}];
[client getStreamsWithCompletionHandler:^(NSError *err, NSArray *streams) {
for (id object in streams) {
CineStream *stream = (CineStream *)object;
// do something
}
}];
[client getStream:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, CineStream* stream) {
// do something
}];
[client createStream:@{ @"name" : @"my stream" } withCompletionHandler:^(NSError* error, CineStream* stream) {
// do something
}];
[client updateStream:@{ @"" : "<SOME STREAM ID>", @"name" : @"my stream" } withCompletionHandler:^(NSError* error, CineStream* stream) {
// do something
}];
[client deleteStream:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, NSHTTPURLResponse* response) {
// do something, like check for response.statusCode == 200
}];
[client getStreamRecordings:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, NSArray* recordings) {
// do something
}];
[client deleteStreamRecording:@"<SOME STREAM ID>"
withName:@"foo.mp4"
andCompletionHandler:^(NSError* error, NSHTTPURLResponse* response) {
// do something, like check for response.statusCode == 200
}];
To make playback as easy as possible, cineio-ios comes with a ready-made view controller that takes care of most of the heavy-lifting. Using it is pretty straight forward.
If you're using XCode's Storyboards to build your user interface, our UI components should work seamlessly. To use them, follow these steps:
- Make your view controller inherit from
CinePlayerViewController
rather thanUIViewController
. - Ensure that the view controller in your Storyboard has the correct class name set. It should be set to your subclass of
CinePlayererViewController
.
Your class that inherits from CinePlayerViewController
will have a writeable
stream
property. You'll need to ensure that this property is set with a
valid CineStream
object.
- (void)viewDidLoad
{
[super viewDidLoad];
//-- cine.io setup
// read our cine.io configuration from a plist bundle
NSString *path = [[NSBundle mainBundle] pathForResource:@"cineio-settings" ofType:@"plist"];
NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:path];
// create a new CineClient to fetch our stream information
CineClient *cine = [[CineClient alloc] initWithSecretKey:settings[@"CINE_IO_SECRET_KEY"]];
[cine getStream:settings[@"CINE_IO_STREAM_ID"] withCompletionHandler:^(NSError *error, CineStream *stream) {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network error"
message:@"Couldn't get stream settings from cine.io."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else {
self.stream = stream;
}
}];
To start playback, simply call startStreaming
. This method will first
attempt to (asynchronously) validate that a stream exists at the given HLS
URL, and if it does, will start to play it. Otherwise, an appropriate error
message will be displayed in a UIAlert
.
You likely want to disable the idle timer in this method.
- (IBAction)playButtonPressed:(id)sender
{
playButton.enabled = NO;
playButton.hidden = YES;
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
[self startStreaming];
}
When the stream has finished playing (for any reason, including the user
quitting, the stream ending, or if errors are encountered), finishStreaming
will be called. You should put any cleanup code that you want executed into
this method (such as re-enabling the idle timer).
- (void)finishStreaming
{
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
playButton.hidden = NO;
playButton.enabled = YES;
}
To make publishing as easy as possible, cineio-ios comes with some ready-made user-interface components that take care of most of the heavy-lifting. Using them is pretty straight forward.
For user-experience reasons, our CineBroadcasterView uses neither "Auto
Layout" nor "Springs and Struts". Instead, the entire user-interface is
constructed programatically. This means that we need to listen for
notifications about when the device changes orientation. The best place to do
this is in the AppDelegate didFinishLaunchingWithOptions
method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
return YES;
}
If you're using XCode's Storyboards to build your user interface, our UI components should work seamlessly. To use them, follow these steps:
- Make your view controller inherit from
CineBroadcasterViewController
rather thanUIViewController
. - Ensure that the view controller in your Storyboard has the correct class name set. It should be set to your subclass of
CineBroadcasterViewController
. - Ensure that the view in your Storyboard has the correct class name set. It should be set to
CineBroadcasterView
.
You'll need to initialize these properties, most likely in your viewDidLoad
method. For example:
- (void)viewDidLoad
{
//-- A/V setup
self.videoSize = CGSizeMake(1280, 720);
self.framesPerSecond = 30;
self.videoBitRate = 1500000;
self.sampleRateInHz = 44100; // either 44100 or 22050
// must be called _after_ we set up our properties, as our superclass
// will use them in its viewDidLoad method
[super viewDidLoad];
//-- cine.io setup
// read our cine.io configuration from a plist bundle
NSString *path = [[NSBundle mainBundle] pathForResource:@"cineio-settings" ofType:@"plist"];
NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:path];
// create a new CineClient to fetch our stream information
CineClient *cine = [[CineClient alloc] initWithSecretKey:settings[@"CINE_IO_SECRET_KEY"]];
[self updateStatus:@"Configuring stream using cine.io ..."];
[cine getStream:settings[@"CINE_IO_STREAM_ID"] withCompletionHandler:^(NSError *error, CineStream *stream) {
if (error) {
[self updateStatus:@"ERROR: couldn't get stream information from cine.io"];
} else {
self.publishUrl = [stream publishUrl];
self.publishStreamName = [stream publishStreamName];
// once we've fully-configured our properties, we can enable the
// UI controls on our view
[self enableControls];
}
}];
}
You may want to take certain actions before or after streaming. You can do that
in the toggleStreaming
method. For example, you will likely want to enable /
disable the idle timer in this method as appropriate.
- (void)toggleStreaming:(id)sender
{
switch(self.streamState) {
case CineStreamStateNone:
case CineStreamStatePreviewStarted:
case CineStreamStateEnded:
case CineStreamStateError:
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
break;
default:
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
break;
}
// start / stop the actual stream
[super toggleStreaming:sender];
}
Much of the basis for the cine.io iOS SDK comes from the excellent VideoCore library.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request