Backendless Support
 

Developing an iOS Video Recorder and Player in 5 minutes

Video broadcasting and streaming is one of the coolest features of Backendless. Our Media Service API enables client-server functionality for working with live and on-demand audio and video content. An application using the Media Service API can broadcast audio and video from the devices cameras and microphone and Backendless automatically handles streaming to other clients as well recording of the content on the server. The API also supports the capability to stream the pre-recorded (on-demand) content managed by the Media Service. Details are available in the documentation.

This article describes how to build an iOS application which can record a video on the server and then subsequently play it back. To start, a developer will need to create a project in XCode:

  1. Goto File->New->Project
  2. Select Single View Application and click Next button
  3. Enter application name for e.g. SimpleVideoService
  4. Choose iPhone device and click next
  5. Choose a location for your project

Now there is a project with single view. A backendless application must be initialized with an ID and a secret key. It can be done in AppDelegate.m:

#import "AppDelegate.h"
#import "Backendless.h"
// *** YOU SHOULD SET THIS FOR YOUR APPLICATION TO BE REGISTERED ***
static NSString *APP_ID = @"";
static NSString *SECRET_KEY = @"";
static NSString *VERSION_NUM = @"v1";
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[backendless initApp:APP_ID secret:SECRET_KEY version:VERSION_NUM];
return YES;
}
.....

The values for the APP_ID and SECRET_KEY variables must be obtained from Backendless Console. Login to the console, create/select your application and click the Manage icon. The default subsection is App Settings:

Use the “Copy” buttons to copy the application id value and the secret key for iOS into the code. The copied values must be assigned to the “APP_ID” and “SECRET_KEY” variables accordingly.

Drag and drop view component to the main view:

Change the background for the view:

Add buttons to control the video stream:

Download the Backendless SDK for iOS from http://backendless.com/downloads, unzip it and drag and drop library to the project files:

Also, it is necessary to add the following standard libraries:

  • AudioToolbox.framework
  • AVFoundation.framework
  • CoreData.framework
  • CoreGraphics.framework
  • CoreMedia.framework
  • CoreVideo.framework
  • Libz.dylib
  • Security.framework

Open ViewController.m and import backendless and define the constants as shown below:
#import "Backendless.h"
#define VIDEO_TUBE @"videoTube"
#define STREAM_NAME @"defaultStreamName"
Declare the following variables:
@interface ViewController ()
{
 MediaPublisher *_publisher;
 MediaPlayer *_player;
}
Open ViewController.h and declare the *preview property to view the picture from the camera and *playbackView to play the recorded video:
@property (strong, nonatomic) IBOutlet UIView *preview;
@property (strong, nonatomic) IBOutlet UIImageView *playbackView;

The *preview property needs to be associated with a View. In order to do this select the view component and drag and drop New Referencing Outlet to preview.

This view will be used for the camera. Also a view to play the video is necessary. Add the "Image View" component and tie it with the *playbackView property.

Now we should create handlers for control the buttons add their signature to ViewController.h:
-(IBAction) onStopBtn:(id)sender;
-(IBAction) onPlayBtn:(id)sender;
-(IBAction) onRecordBtn:(id)sender;

Add an implementation of the methods in ViewController.m:

Recording Video

- (void)onRecordBtn:(id)sender
{
 MediaPublishOptions *options = [MediaPublishOptions recordStream:self.preview];
 _publisher =[backendless.mediaService publishStream: STREAM_NAME tube:VIDEO_TUBE options:options responder:self];
}
O

n line 3 create an instance of MediaPublishOptions and reference a UI component that will show the video being recorded.

On line 4 we create a publisher. The publisher constructor accepts stream name, a tube name, options and a responder. When the user stops the recording, we check if we are currently publishing a video, then disconnect from the stream and set the publisher and player to nil.
-(void)onStopBtn:(id)sender
{
 if (_publisher)
 {
 [_publisher disconnect];
 _publisher = nil;
 }
 if (_player)
 {
 [_player disconnect];
 _player = nil;
 }
}


Playing Recorded Video

- (void)onPlayBtn:(id)sender
{
 MediaPlaybackOptions *options = [MediaPlaybackOptions recordStream:self.playbackView];
 _player = [backendless.mediaService playbackStream:STREAM_NAME tube:VIDEO_TUBE options:options responder:self]; 
}

On line 3 an instance of MediaPlaybackOptions is created and passed in the UI component that will show the recorded video.

On line 4 we create the media player. The constructor accepts a stream name, a tube name, options and the responder. Since the responder is set to self, the ViewController class must implement IMediaStreamerDelegate.

As IMediaStreamerDelegate has been implemented there should be added the following code to handle stream state changes:

-(void) streamConnectFailed:(id)sender code:(int)code description:(NSString *)description
{
 NSLog(@"<IMediaStreamerDelegate> streamConnectFailed: %d = %@", (int)code, description);
 [self onStopBtn:sender];
 NSString *message = (code == -1) ?
 @"Unable to connect to the server. Make sure the hostname/IP address and port number are valid\n" :
 [NSString stringWithFormat:@"connectFailedEvent: %@ \n", description];
 UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error:" message:message delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
 [av show];
}
-(void) streamStateChanged:(id)sender state:(StateMediaStream)state description:(NSString *)description
{
 switch (state) {
 case MEDIASTREAM_DISCONNECTED: {
 [self onStopBtn:sender];
 break;
 }
 case MEDIASTREAM_PAUSED: {
 [self onStopBtn:sender];
 break;
 }
 case MEDIASTREAM_PLAYING: {
 // PUBLISHER
 if (_publisher) {
 if (![description isEqualToString:@"NetStream.Publish.Start"]) {
 [self onStopBtn:sender];
 break;
 }
 }
 // PLAYER
 if (_player) {
 if (![description isEqualToString:@"NetStream.Play.Start"]) {
 UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error:" message:[NSString stringWithString:description] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
 [av show];
 break;
 }
 self.playbackView.hidden = NO;
 }
 break;
 }
 default:
 break;
 }
 }

 Everything is almost ready, just link the buttons with the handlers: Repeat the same for other buttons. 

The sample code is available for downloading here.

Is article helpful?