Monthly Archives: December 2016

Android MediaRecorder Start Failed – 19

If you have ever used Android MediaRecorder to record video or audio in your android application, you must have faced this error. Recently I had nightmare in using MediaRecorder in my android application. I think it’s most unstable class in Android SDK and there is a different behavior in each device. In this blog I am going to explain more about this and possible resolution of this.

First lets see wha’s the meaning of this error : Android MediaRecorder Start Failed – 19

There is no documentation on Android developer site about this error code but from my experience I found out that it’s because of mis match in size of video preview frame and MediaRecorder video size and this error comes randomly in different devices. The best approach is to use CamCorder profile as mentioned on Android developer site.

CamcorderProfile profile =CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mMediaRecorder.setProfile(profile);

When you use this most of the following default values are set in MediaRecorder from the selected profile.

  • OutputFormat
  • AudioEncoder
  • VideoEncoder
  • VideoSize
  • VideoFrameRate

But this does not work on all the devices as some the devices don’t accept these default values hence MediaRecorder does not work and specifically due to VideoSize it gives error. So to solve this you should manually set all the values. Following settings works on almost all devices

int width = mCamera.getParameters().getPreviewSize().width;
int height = mCamera.getParameters().getPreviewSize().height;

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setVideoFrameRate(30);

However there are still some problem with it. When I tested in some high resolution devices. I got following width and height from getPreviewSize()

2048
1536

But MediaRecorder failed to start and when I checked error log I got error.

Unsupported Video Dimension 1920 X 1688

That means it changed the dimension by itself and ignored the width and height I set it in setVideoSize. So that means you can not depend on it. So what’s the solution for this. Well the solution is find the optimal video size based on your preferred frame dimensions and available supported size in your device. Following is the function I used for it.

private Size getOptimalPreviewSize(List sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null) {}
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio – targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height – targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height – targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height – targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height – targetHeight);
}
}
}
return optimalSize;
}

List sizes = mCamera.getParameters().getSupportedPreviewSizes();
Camera.Size optimal = getOptimalPreviewSize(sizes, 640, 480);

if(optimal != null){
           
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(optimal.width, optimal.height);
mMediaRecorder.setVideoFrameRate(30);      

}else{

int width = mCamera.getParameters().getPreviewSize().width;
int height = mCamera.getParameters().getPreviewSize().height;

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setVideoFrameRate(30);      

}    

For me above solution worked on almost all devices, first we get optimal size from available supported sizes and if there is no supported sizes then we use default preview size.

PHP / MySql – Generate Big Reports from Big Data

Big data is a term that describes the large volume of data – both structured and unstructured – that inundates a business on a day-to-day basis. But it’s not the amount of data that’s important. It’s what organizations do with the data that matters. Big data as a service market to grow in near future. “Big Data” analysis is a hot and highly valuable skill now a days. For the big data analysis, an organization needs reports generated from it and to generate reports from big data we need some spacial tricks. In this blog I am going to explain some best practices to generate big reports from big data in PHP / MySql.

Challenges we face in managing Big Data with MySql

In MySql when we have big data we face certain performance issues. Most crucial issue is slow performance of MySql. When you have millions of rows in table and you want to search certain raws from it, it will take some time to get data and you need to improve in that. So in MySql there is a way to make faster data retrieval.

INDEXING

Yes, that ‘s right indexing solved my issue. There was a table in my database which has 100K records and executing query from it was taking lots of time as there was no indexing. So I created an index on columns which are used mostly for querying that table and after creating index query was working blazing fast.

If you are facing the same issue, better check your database queries and optimize it with indexing to make it faster.

Challenges we face in generating Big Reports with PHP

In PHP when we generate big reports it will surely take time and while working with PHP we have certain restrictions. For example, a PHP script can run for only certain time limits on any server and that limits can not be changed on most of server providers. So in case of generating big reports we surely need time as we have lots of data at backend and from it we are creating reports. So how to deal with it. 
Here is the one solution I always use. You can make use of scheduled cron job. Cron jobs run in background and there is no time restrictions with it so it can run for any amount of time and it can resources as much as possible. So get the reports parameters from the user and save it in database and schedule it for certain time.  For example user want to see day wise sales of products for a month. Save parameters like month in database have a scheduled cron job to read this data and start creating reports in background. Once the report is generated you can notify user about it so they can download it. Which this trick you can generated Big Reports from Big Data.

Copy Files via SSH from Another Server FTP

Recently for one of my project our server was hacked and some files were deleted and corrupted with malwares. So we had to restore the old backups. We were using the contabo web server where we have separate backup server with 100 GB space which was accessible only through FTP from the SSH. So in this blog I am going to explain how you can copy files Copy Files via SSH from Another Server FTP.

Step 1: Login to SSH with your SSH username and password. 

ssh yourusername@host

On prompt of password enter password and login.

Step 2 : Go to directory where you want to copy files from FTP.

cd /yourpath/to/folder

Step 3: Connect to FTP

Use following command to connect to FTP

ftp hostname

It will ask for username and password. Once you enter correct username and password, you will get ftp command prompt.

Step 4 : Go to directory from where you want to copy files on FTP.

cd /yourpath/to/folder
You can use cd command on FTP just like you  use on SSH.

Step 5 : Copy Specific File.

Use following command to copy file.
get filename
And wait for the process to be finished.

Step 6 : Exit From FTP

Use following command to close FTP and return back to SSH.
bye
With this you will close the FTP session and you are back to SSH session and you can see the copied files using LS command.

Every Company Will be a Technology Company in 2017

Recently I was reading through some tech predictions of 2017 and one prediction caught my attention. It says.

Every Company Will be a Technology Company in 2017

It’s very well said. Technology is growing and more and more businesses are adapting technology to grow. No matter what the business or company is, they are in need of more and more technical solutions to sustain in competition and grow the business. In 2011, Marc Andreesen famously wrote a Wall Street Journal essay declaring that “software is eating the world.” Five years later, the five largest companies in the world by market capitalization are all software companies. Today it doesn’t matter what industry you are in, how large or small your company is, or where you company is located. Every single company today is a technology company. Whether you are a mining organization looking at automated trucks, a real estate firm deploying an internal social network, a warehouse looking to leverage wearable devices, an agricultural company exploring the internet of things, or a hospital interested in teaming up with IBM Watson, every single company today is a technology company and more companies will be technology company in 2017. 
Today in the era of technology people are becoming smart and at the same time they are becoming demanding in terms of services. You end users will expect and more and more services which can be easily available. They don’t like to wait, it should be done immediately. They  want hassle free services. They don’t want wait in queue on wait on phone call. If something can be done by sitting at home or through mobile phone, they will prefer it. Today in busy life nobody have time so everyone is looking for a solution and services that can save their time and money. So all the companies must have innovative technology solutions that can make their customer happy and for that they have to go for IT and technology solution. With technology solutions like Mobile Applications and Cloud based services it will be easy to server customer in real time and all the companies will be looking for such solution in 2017. If a company does not adopt technology solution, they may have to lose their customers in 2017. Every company in every industry, from agriculture, mining, and manufacturing to logistics, financial services, and healthcare, will become a technology company. Additionally, every technology company will need a CTO who has a deep understanding of the company’s technological infrastructure, software development, and support needs.
For companies to successfully make the transition and become a technology company, cultures need to change to take into account the unique way that software development works and to highlight the importance of technology and the people who manage and build it. They have to convince their customers about the technology they offer. We have seen certain example where a company wanted to become technology company and implemented IT solutions but it failed to convince customers to use it hence they failed to be technology company.  A company has to create technology driven culture within the company to be successful technology company. They have to hire and train staff to make them understand about technology. Companies need to move fast and adopt agile practices. The pace of technology adoption is getting faster and faster every year. For example, it took decades for electricity and telephones to reach 50% of US households, but today it takes only years for new technologies like smartphones and tablets to reach a majority of the population. To become a successful technology company, company has to invest in technology solutions and infrastructure with proper planning. They have to study market and hire consultants to give them proper directions and build a proper strategy of transformations. Off course this transformation will not be easy also it may end up in mess but a company has to do it. 

Conclusion

The race to become the market leader across a variety of sectors and geographies is speeding up so Every Company Will be a Technology Company in 2017

Step By Step Guide on iOS TestFlight Beta Testing

In this blog I am going to explain step by step procedure of TestFlight Beta Testing in iOS.

What is TestFlight?

TestFlight was the platform built for iOS beta testing. As we know iOS does not allow any application to be installed our of App Store and earlier to test you have to sync Apps with iTunes and proper provisioning profiles which was hard for newbies and non technical users. So TestFlight made this process simple and built platform where you can do it easily with TestFlight app. Later on TestFlight was acquired by Apple and it was integrated in iTunes Connect. Still it sometimes confuses new user. So in this blog I am going to explain step by step procedure. 
Please note that you should have valid Apple Developer Account. If you don’t have one please signup for it. 

Step 1 : Create Application Id

For this go to Apple Developer Member Center. Here is the Link Login here with Apple Developer Account credentials. Once you logged in following screen will be displayed. From here click on 
“Certificates, Identifiers & Profiles”
First of all we will create new Application Id. For that click on it Identifiers —> App IDs and it will show you following screen. Click on + symbol on top right .
Once you click on + sign following form. Fill up information here as displayed below. Here you have to specify name of app and bundle ID and click on continue.
After continue, it will ask you to confirm it. Click on Register and your App id is created. Here your app id registration is completed. Click on Done. 

Step 2: Create Distribution Certificate and Distribution Provisioning Profile 

Next step is to create distribution certificate and provisioning profile as we need to sign application with it. 
First lets create Distribution Certificate. Click on Certificates —> Production in the side menu. And then click on + icon on top right side.
It will start Add iOS certificate wizard. In first step. What type of certificate do you need? Select 
App Store and Ad Hoc below production and click on continue.  It will show you screen about creating certificate signing request. Create CSR file as mentioned here and save to your desktop and click on continue.
In the next step upload Certificate Signing Request you created and click on continue. In the final step it shows Your certificate is ready. Click on Done here.
Next we will create distribution provisioning profile. Click on Provisioning Profiles —> Distribution and click + on top right side. 

It will start a wizard to create provisioning profile. 
In Step 1 What type of provisioning profile do you need? select Distribution —> App Store and click on continue.
In Step 2 Select App ID, select App Id we created in Step 1 above and click on continue.
In Step 3: Select certificates, select the distribution certificate we created and click on continue.
In Step 4: Name this profile and generate. Give name of profile and click on continue.
In Step 5: Your provisioning profile is ready. Click on Done and your provisioning profile.

Step 3: Configure Xcode project and Generate Build

Next step is to configure Xcode project with provisioning profile and distribution certificate we created. Open your Xcode project. First we have to add your apple developer account in Xcode.
Go to Xcode —> Preference —> Accounts
Click on + sign and bottom and select Add Apple Id. It will ask for your credentials. Add  your email and password and Sign In.
Now select your project and in General tab select your Apple Developer Account.
It will download all the necessary profile and sing up your app. Now create an Archive to upload. First select Generic iOS device and then go to Product—>Archive
Now product is Archived.

Step 3: Create Application in iTunes Connect

we will upload it for the beta testing. Login to iTunes Connect with your apple development account credentials and click on My Apps. On the left side there is + sign. Click on that and choose New App. It will show following pop up, where you have to select the app and add necessary details.

This will create App. Now we will have to upload archive we created in Xcode. Go back to Xcode. Select the archive we created and Click on Upload to App Store.
It will prepare iPA file and shows you following dialog. Click on upload here. It will upload build to iTunes Connect.
Once the build is uploaded. It will take some in processing in iTunes connect. That you can select in activity screen. 
Once the build is processed, you have to submit it for beta review. For that go to TestFlight -> External Testing and click on select Add Build to Test.
Select the build you have submitted and add the necessary information on the screens which are prompted. Be specific to each information and give as much info as possible and submit for beta review. It will take couple of days to get it approved. Once approved. Add the external tester and click on Save. All the users will be notified with email and link to TestFlight app. 
Hope this helps you.

Cordova Text To Speech Plugin

Recently in one of our project we added Cordova Text To Speech using following plugin.

https://github.com/PluginCordova/cordova-plugin-tts

But during the development I faced certain issues so in this blog I am going to explain it.

1) It does not work in first attempt.

This plugin depends on Android Text to Speech class

https://developer.android.com/reference/android/speech/tts/TextToSpeech.html

And for that you need sample voice in the phone. If you are using this feature first time then first it will download sample voice from the android server. So let it get downloaded and then try it again.

2) Maximum Character Limit

There is limit of 32, 768 characters. If your string is bigger than this, it won’t work. In this case split your text to smaller chunks and play it one by one like playlist.

3) It does not stop after start playing.

With the above plugin it does not stop playing. The reason is stop method is not implemented at all in this plugin.

So you have to make two changes for it.

First open tts.js file in plugins folder and exports.stop = function ()

There check for the following line.

cordova
.exec(function () {
if (promise) {
promise.resolve();
}
}, function (reason) {
}, ‘TTS’, ‘stop’);

Here the third param options is not passed so it will give JavaScript error. Change above code to.

cordova
.exec(function () {
if (promise) {
promise.resolve();
}
}, function (reason) {
}, ‘TTS’, ‘stop’,[]);

Now go to TTS.java file in src folder of your android project and look for the following method.

public boolean execute(String action, JSONArray args, CallbackContext callbackContext)

It does not have stop implementation.

Remove code of the function and use following code.

if (action.equals(“speak”)) {
speak(args, callbackContext);
} else if (action.equals(“stop”)){
Log.v(“stop”,”stop speaking”);
tts.stop();
}else{
return false;
}
return true;

That’s it and it should work now.

Home Automation – Big Business Opportunity in 2017



Recently I read Facebook post of Mark Zuckerberg where he mentioned his personal challenge for 2016 was to build home automation. So he is working on Jarvis. You can read it at following link.

Building Jarvis


Well so if Facebook founder is working on Home automation that means there is really some interesting about it. Home automation is today a growing market globally, bringing new and exciting opportunities for technology companies. According to industry experts, the market will be driven by the trend towards energy efficient, safe, luxurious and convenient homes or smart homes. According to a report published by MarketsandMarkets, ‘APAC Smart Homes Market–By Products, Services and Geography – Analysis & Forecast (2013-2020),’ the total market for smart homes in the Asia Pacific region will be worth US$9.28 billion by 2020. With increasing availability of smart devices, wearable devices and connected devices, the demand of smart home is increasing. Consumers are really looking for automation in day to day activities in home and that creates big business opportunity in field of home automation.  Google also acquired Next lab. Nest Labs is a home automation producer of programmable, self-learning, sensor-driven, Wi-Fi-enabled thermostats, smoke detectors, and other security systems. This acquisition shows Google’s interest in smart home sector. 

The growth factors of Home Automation


Vast availability of connected consumer electronics


Connectivity is rapidly becoming a reality with the development of smart technologies allowing devices to connect and talk with one another.  Your smart phone can connect with home appliances like security cameras, your LED tv, your refrigerator etc . This gives real boost to home automation as you can control everything from your smart phone. Also with increasing use of wearable devices, this is even becoming more easy to connect and communicate with other devices. With the innovation in technologies these devices are getting affordable. 

Increased Network Infrastructure


In metro cities you can easily find a open network anywhere. Also with increase in mobile networks and its speed, most of the users are now able to communicate from anywhere. This is still growing more and will boost home automation. You can control your home even if you are far away from it.

Increasing demand for new services in the home


Over the years, the evolving needs of home buyers have translated into a whole new set of consumer preferences and expectations from real estate developers. What was earlier considered luxury has now become the standard. Not to forget the rise of a financially powerful consumer class that demands a standard of living and luxury at par with the western world.


Challenges in Home Automation


Well, this is a growing market but there are still many challenges.

  • Cyber security concerns
  • Lack of interoperability
  • Unreliable performance of gadgets
  • Perfect Implementation of Artificial Intelligence

Cordova Upload PDF File

Recently in my project I created Hybrid application using Cordova. There was a requirement where we allow user to choose PDF file or any type of file and upload it to server.

So here are two parts, first let user choose file from SD card or phone memory or from iCloud drive on iOS.

Second part is to upload file to server with progress and store it and get it’s path back in case if you want to show it some where. I will show example code on server side.

So lets first check the first part. For this we need following plugins. Please install it first.

https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin This is specifically for iOS
https://github.com/don/cordova-filechooser This is specifically for Android
https://github.com/apache/cordova-plugin-file
https://github.com/apache/cordova-plugin-file-transfer

The file picker iOS plugin which I have mentioned here will not work for local photos and videos stored in camera roll. For this you have to make certain changes in the plugin. I have mentioned this in my previous blog. Please read it here.

http://davehiren.blogspot.com/2016/12/filepicker-cordova-ios-plugin-get-files.html

Now first lets invoke the plugin.

Android Example

fileChooser.open(function(obj) {
        var filePath = obj.path;
});

iOS Example

FilePicker.pickFile(function(obj) {
        obj = obj[0];
         var filePath = obj.path;
});

In both of this case we will get absolute path of files like

/path/of/file/filename.extension

Now we will have our logic to upload file to server using Cordova File Transfer plugin.

First of all we will get extension of file and keep it separate also we will have file name extracted from the path to send it to server.

var fileType = filePath.substring(obj.path.lastIndexOf(‘.’));

var options = new FileUploadOptions();
options.fileKey = “file”;
options.fileName = filePath.substr(this.evidencePath.lastIndexOf(‘/’) + 1);
options.mimeType = “text/plain”;

var params = {};
params.fileType = type;
options.params = params;

var ft = new FileTransfer();

ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
//in case you want to show progress bar , your code goes here.
} else {
//loadingStatus.increment();
}
};

var win = function (r) {
        //success alert or your logic after successful upload
};

var fail = function (error) {
        //failure alert or your logic after successful upload
};

ft.upload(fileURI, encodeURI(“http://pathtoyourserver”), win, fail, options);

So this was on JavaScript side. Now lets see on server side. I used PHP on server side so I will give you example of that. If you are using something else on server side, please implement your own logic.

$file_type = $_POST[‘fileType’];
$fileName = time().”_”.$file_type;
move_uploaded_file($_FILES[“file”][“tmp_name”], “/your/server/path/”.$fileName);

return json_encode(array(‘success’=>true, ‘server_path’=>’http://yourserverpath.com’.$fileName));

With this logic you can upload any type of file from your cordova app.

Objective C – Record Video With AVCaptureSession

Hello,

In this blog I am going to explain how to record video with AVCaptureSession in your iOS application.

First of all add following import statements in your view controller header file.

#import <Foundation/Foundation.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

Now we will have to set preview layer for the recording in our view and also we will need input device and output file location. Also we need to add AVCaptureFileOutputRecordingDelegate to have notifications of events like recording stop.

Implement this delegate in your header file.

@interface MainViewController : CDVViewController
{
    BOOL WeAreRecording;
    BOOL ShareVideo;
    AVCaptureSession *CaptureSession;
    AVCaptureMovieFileOutput *MovieFileOutput;
    AVCaptureDeviceInput *VideoInputDevice;
}

Now we will set preview layer and init AVCaptureSession in viewDidLoad and set input and output.

CaptureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *VideoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
if (audioInput)
{
[CaptureSession addInput:audioInput];
}

[self setPreviewLayer:[[AVCaptureVideoPreviewLayer alloc] initWithSession:CaptureSession]];
PreviewLayer.orientation = AVCaptureVideoOrientationLandscapeRight;
[[self PreviewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];

Now we will setup output file and video recording settings and image quality.

MovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
Float64 TotalSeconds = 60;
int32_t preferredTimeScale = 30;
CMTime maxDuration = CMTimeMakeWithSeconds(TotalSeconds, preferredTimeScale);
MovieFileOutput.maxRecordedDuration = maxDuration;
MovieFileOutput.minFreeDiskSpaceLimit = 1024 * 1024;
   
if ([CaptureSession canAddOutput:MovieFileOutput])
    [CaptureSession addOutput:MovieFileOutput];
   
[self CameraSetOutputProperties];

[CaptureSession setSessionPreset:AVCaptureSessionPresetMedium];
if ([CaptureSession canSetSessionPreset:AVCaptureSessionPreset640x480])
    [CaptureSession setSessionPreset:AVCaptureSessionPreset640x480];
   
CGRect layerRect = [[[self view] layer] bounds];
CGRect viewBoundsPreview = [self.webView bounds];
viewBoundsPreview.origin.y = 20;
viewBoundsPreview.size.height = viewBoundsPreview.size.height – 40;
[PreviewLayer setBounds:viewBoundsPreview];
[PreviewLayer setPosition:CGPointMake(CGRectGetMidX(layerRect),
 CGRectGetMidY(layerRect))];

UIView *CameraView = [[UIView alloc] init];
[[self view] addSubview:CameraView];
[self.view sendSubviewToBack:CameraView];
[[CameraView layer] addSublayer:PreviewLayer];
[CaptureSession startRunning];

Now capture session is running, we have to start and stop recording.

To start recording, add following code to your handler.

NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
NSNumber *timeStampObj = [NSNumber numberWithInteger:timeStamp];
NSString* fileName = [timeStampObj stringValue];
fileName = [fileName stringByAppendingString:@”.mov”];
NSString *outputPath = [[NSString alloc] initWithFormat:@”%@%@”, NSTemporaryDirectory(), fileName];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:outputPath])
{
NSError *error;
if ([fileManager removeItemAtPath:outputPath error:&error] == NO)
{
//Error – handle
}
}
//Start recording
[MovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];

Above code will start recording. Add following code to stop recording.

[MovieFileOutput stopRecording];

This will stop recording and save video to Photos library.

Objective C – Play Video From Application Temp Folder

Recently in one of my iOS project , there was requirement to play Video stored in temporary folder of Application data. After some hours of struggle I managed to get it working.

So the problem I was facing is I have absolute URL of the video that I was trying to play in MPMoviePlayerController but it was not working as the player was displayed for couple of seconds and it’s dismissed automatically and there was a black screen.

So after sometime I found out that MPMoviePlayerController is deprecated, instead of it we shall use AVPlayer and that too was not working if I give absolute path to initialize a player. So first of all I just extracted file name fro the absolute path will following code.

NSRange range = [filePath rangeOfString:@”/” options:NSBackwardsSearch];
NSUInteger index = range.location;      
filename = [filePath substringFromIndex:index+1];

Now we will initialize player. Please note you have to import AVKIt first in your header file.

#import <AVKit/AVKit.h>

Now initialize player.

NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
AVAsset *asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:outputPath]];
AVPlayer *_avPlayer = [[AVPlayer alloc]initWithPlayerItem:[[AVPlayerItem alloc]initWithAsset:asset]];

movieLayer = [AVPlayerLayer playerLayerWithPlayer:_avPlayer];
movieLayer.frame = self.view.bounds;
[self.view.layer addSublayer:movieLayer];

So player will be added as sublayer on the view so we have to dismiss it when video finished playing.

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(videoDidFinish:)
name:AVPlayerItemDidPlayToEndTimeNotification
  object:[_avPlayer currentItem]];

And add callback function to remove player layer.

– (void)videoDidFinish:(id)notification
{
    NSLog(@”finsihed”);
    [movieLayer removeFromSuperlayer];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

That’s it. Hope this will help you.