• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created over 10 years ago
  • Updated almost 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The cine.io iOS Broadcast SDK

cineio-broadcast-ios - cine.io Broadcast iOS SDK

Build Status

This is the cine.io Broadcast 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).

Table of Contents

Installation

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-broadcast-ios', '~> 0.6'

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

Example Application

Check out the cineio-broadcast-ios-example-app and cineio-broadcast-ios-swift-example-app repositories for working examples that use this SDK.

Basic Usage

Import the SDK

#import <cineio/CineIO.h>

Instantiate the client

CineClient *client = [[CineClient alloc] init];

Set the client properties

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";

Get your projects (asynchronously)

[client getProjectsWithCompletionHandler:^(NSError *err, NSArray *projects) {
  for (id object in streams) {
    CineProject *project = (CineProject *)object;
    // do something
  }
}];

Get your project (asynchronously)

[client getProjectWithCompletionHandler:^(NSError *error, CineProject *project) {
  // do something
}];

Get your streams (asynchronously)

[client getStreamsWithCompletionHandler:^(NSError *err, NSArray *streams) {
  for (id object in streams) {
    CineStream *stream = (CineStream *)object;
    // do something
  }
}];

Get an individual stream (asynchronously)

[client getStream:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, CineStream* stream) {
  // do something
}];

Create a new stream (asynchronously)

[client createStream:@{ @"name" : @"my stream" } withCompletionHandler:^(NSError* error, CineStream* stream) {
  // do something
}];

Update a stream (asynchronously)

[client updateStream:@{ @"" : "<SOME STREAM ID>", @"name" : @"my stream" } withCompletionHandler:^(NSError* error, CineStream* stream) {
  // do something
}];

Delete a stream (asynchronously)

[client deleteStream:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, NSHTTPURLResponse* response) {
  // do something, like check for response.statusCode == 200
}];

Get the recordings of a stream (asynchronously)

[client getStreamRecordings:@"<SOME STREAM ID>" withCompletionHandler:^(NSError* error, NSArray* recordings) {
  // do something
}];

Delete a stream recording (asynchronously)

[client deleteStreamRecording:@"<SOME STREAM ID>"
                     withName:@"foo.mp4"
         andCompletionHandler:^(NSError* error, NSHTTPURLResponse* response) {
  // do something, like check for response.statusCode == 200
}];

Playback (using CinePlayerView)

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.

Storyboard Setup

If you're using XCode's Storyboards to build your user interface, our UI components should work seamlessly. To use them, follow these steps:

  1. Make your view controller inherit from CinePlayerViewController rather than UIViewController.
  2. Ensure that the view controller in your Storyboard has the correct class name set. It should be set to your subclass of CinePlayererViewController.

The stream Property

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;
        }
    }];

Starting Playback

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];
}

Cleaning up

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;
}

Publishing (using CineBroadcasterView and CineBroadcasterViewController)

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.

Setup

Handling Device Rotation

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;
}

Storyboard Setup

If you're using XCode's Storyboards to build your user interface, our UI components should work seamlessly. To use them, follow these steps:

  1. Make your view controller inherit from CineBroadcasterViewController rather than UIViewController.
  2. Ensure that the view controller in your Storyboard has the correct class name set. It should be set to your subclass of CineBroadcasterViewController.
  3. Ensure that the view in your Storyboard has the correct class name set. It should be set to CineBroadcasterView.

Initializing the properties

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];
        }
    }];
}

Streaming Hooks

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];
}

Acknowledgements

Much of the basis for the cine.io iOS SDK comes from the excellent VideoCore library.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

More Repositories

1

android-ffmpeg-with-rtmp

script(s) to build ffmpeg for android, including support for RTMP (and OpenSSL)
Shell
241
star
2

cineio-broadcast-android

The cine.io Android Broadcast SDK
Java
51
star
3

cineio-meetups

Full video/audio/text chat example app using cine.io peer sdk.
CoffeeScript
43
star
4

primus-android

A Primus library for Android
Java
19
star
5

cineio-broadcast-ios-example-app

iOS example app for publishing and playback using cine.io
Objective-C
13
star
6

peer-js-sdk

code for the cine.io peer js sdk
JavaScript
11
star
7

cineio-node

The cine.io node package
CoffeeScript
9
star
8

broadcast-js-sdk

The JavaScript SDK for cine.io
CoffeeScript
7
star
9

cineio-peer-ios

The cine.io iOS Peer SDK
Objective-C
7
star
10

cineio-peer-android

The cine.io Android Peer SDK
Java
6
star
11

cineio-peer-ios-example-app

iOS example app for realtime video chat using cine.io
Objective-C
5
star
12

cineio-peer-html-example-app

An example application in html using cine-io peer.
HTML
5
star
13

ffmpegbridge

JNI FFmpeg bridge for streaming from Android.
C
5
star
14

cineio-broadcast-ios-swift-example-app

Sample iOS application (written in Swift) to demonstrate broadcasting and playback using the cine.io iOS SDK.
Swift
5
star
15

cineio-broadcast-node-example-app

Example broadcast application using the Node SDK and Node.js
JavaScript
5
star
16

cineio-python

The cine.io python client.
Python
4
star
17

cineio-ruby

The cine.io ruby client.
Ruby
3
star
18

nested-query-string

A querystring encoder with nesting support
Python
2
star
19

rtmp-player-test

Demonstrate the JWPlaye aspect-ratio bug.
JavaScript
2
star
20

ios-webrtc-build

Script(s) to build WebRTC for iOS.
Shell
1
star
21

cineio-peer-node-example-app

An example application in Node.js using cine-io peer.
JavaScript
1
star
22

cineio-broadcast-sinatra-example-app

Example broadcast application using the Ruby SDK and Sinatra.
Ruby
1
star