I have been quite bored lately. When you are bored you want to make things. One thing I have always wanted to do is programmatically take a photo (that means to have my code use the built-in camera to take photos and use in my application) using my Mac’s built in iSight-camera for some fun manipulation. A simple search on Google returns some outdated results on old programs and other stuff related to capturing video using old APIs. However, when I recently dove into (QuickTime’s API) I found some promising things.
Sep 17, 2013 - Can somebody help me with the following code snippet to capture part of. In Objective-C) but I think the method ScreenImage you're using. AVCapture Screen Input is a concrete subclass of AVCaptureInput that provides an interface for capturing media from a screen or a portion of a screen. Instances of AVCapture Screen Input are input sources for AVCapture Session objects that provide media data from one of the screens connected to the system, represented by CGDirect Display ID s. Grab, the built-in Mac OS X service that captures screenshots, might be sufficient for most people. If you're looking to pair an upload service to it, you can just add the great and free Cloud App.
This post will be a straightforward demo of how to grab photos from your iSight camera (or any other connected cameras). I’ll post some code and explain the different steps and what they mean. And The best parts about reading tutorials on QTKit and using the computers camera are that you get to see a lot of random pictures by the demoer himself. And here is my contribution: I.e, what you should have at the end of this tutorial. Yours truly, testing some code Doing this you notice how silly you look while compiling code. Prerequisites You should know some Objective-C, how to use XCode and have some basic knowledge of (or Cocoa touch, for iOS, but this code will not work on iOS) Code The first thing you have to do is include the QTKit-framework in your Xcode-project.
While your at it you’ll need the QuartzCore-framework too (for image processing). Adding frameworks in Xcode 4 is a bit different from 3. You press the project name in the file navigator and there you get a list of frameworks for your project.
Adding is simply pressing the +-sign and finding your framework. To keep this simple I’ll just post a working code sample with lots and lots of comments.
This class presents you with an easy interface for grabbing photos. As illustrated.
Thank you Erik – very good of you to publish a complete class. Are you happy for people to use this in commercial projects (with credit of course). Dat – I have tried what you have asked.
By grabbing an image from the camera, reducing it to a single pixel and then measuring the brightness of that pixel. It works to a point, but the problem is that the camera adjusts its exposure for the light conditions. So you can measure very light and very dark but it’s very flat in between.
Much better to access the computer’s ambient light sensor (Google IOServiceGetMatchingService and AppleLMUController). This works really well but I believe the calibration is different on different models of computer.
Thanks for the feedback. I was able to confirm your memory leak, and the code should be fixed now. The problem was that the data allocated to back the temporary graphics context was never being released. In my defense, the code which introduced this leak was taken from a popular example I found online. Given its popularity I assumed that it must include proper memory management.
In any case, the memory leak should be fixed now if you take the current version of the code. If it isn’t please let me know. I’m sorry to comment again and again. One is information, About this code //not sure why this is necessaryimage renders upside-down and mirrored CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height); CGContextConcatCTM(context, flipVertical); UIView CGContextRef is different than the orientation of the coordinate system.
UIView (UIImage) coordinate system as against the increase down to Y, CGContextRef coordinate system is on the increase in Y. Although written in Japanese, the reference site. I used to translate Google. Sorry bad English. Hey aroth, Great writeup.
I’m getting some errors when trying to build (request for member not a union or stucture) and I think I do not have my superview setup in IB correctly. Can you explain how I do the following from your post? Simply set it up as the superview of the UIView(s) that you want to record, add a reference to it in your corresponding UIViewController (using Interface Builder or whatever your preferred method happens to be) I have a view inside of another view, but can’t figure out how to reference that in IB. Tried connecting it to File’s Owner, but still get the errors. Hello, I’ve been trying to do this myself with my own code, but consistently had an issue on the device (more about that in a sec). So, I unwired my code and plugged in yours.
Low and behold, the same issue occurs. It’s this: I start recording using your code, but as soon as I play audio with AVAudioPlayer WHILE recording, the very next attempt to grab a frame, this dies: int status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, avAdaptor.pixelBufferPool, &pixelBuffer); The avAdaptor.pixelBufferPool which was there and fine all along, suddenly gets set to nil and disappears once the audio starts. Exactly the same problem I had with my own code. This only occurs on the device, and not the sim. Which led me to think it’s some type of memory issue, but profiling reveals nothing relevant in instruments. I even left in the allocation of AVAudioPlayer, but once you call the ‘play’ method, boom. Any clues would be greatly appreciated.
Its a very neat and clean code plus pretty easy in reusability sense. I am just recording what user is doing. The user sees a view which is a “ScreenCaptureView” and there is a button on this view which on tap opens the photo library. The problem is that when the library is opened. It is not recorded and only the output(selected image) is shown as I am displaying the selected image on the “ScreenCaptureView”.
Any ideas how to tackle this problem? How can I record the photolibrary picker too? HmI think you’d have to get the photo picker set up as a subview of the ScreenCaptureView.
I’m not sure how doable that is. Alternately, you might try creating a UIWindow subclass which manages a ScreenCaptureView instance and which forces the ScreenCaptureView to be used as the root view of whatever the currently active view controller happens to be.
This would obviously involve a lot of shuffling around of subviews if/when the view controller changes, but if it works it should let you record pretty much anything that happens in the application. Hey aroth, Thanks for the code sample. I am trying to implement the above but as soon as I start recording I get a never-ending stream of log messages saying: “Not ready for video data” Then when I stop recording I get just a black video. I am trying the following: capture = HBIScreenCaptureView alloc initWithFrame:CGRectMake(0, 0, 1024, 768); self.view addSubview:capture; playerView = MRSPlayerView alloc initWithFrame:CGRectMake(0, 0, 1024, 768); playerView setBackgroundColor:UIColor clearColor; playerView setTag:1; capture addSubview:playerView; capture performSelector:@selector(startRecording) withObject:nil afterDelay:1.0; My MRSPlayerView plays a video using AVFoundation and AVPlayer. Hey, this is awesome stuff: I used it to grab video from a simulator I’m working on. A question: I’d actually prefer to capture one frame of the video each time the simulation updates (which can be a while for some sims–so boring to watch an unchanging screen). The way I copy/pasted your code, I could fire off a writeVideoFrameAtTime at each sim update, but when I (probably naively) tried to do this, the video is unplayable.
I expect this has something to do with frame rates and when the mp4 file expects itself to be fed new data. Do you see a quick way to redo your code to allow me to capture each frame when I prefer, rather than at a preset time interval? Will this screw up the resulting file’s timecode? Neophyte questions, I’m sure! Thanks again for the code! So yeah, this code is wonderful, I’ve learned quite a bit from it but alas the way renderInContext is called any CATransform3Ds that have been applied to the layer are not rendered.
This means that all the perspective transforms I’ve put into my app don’t show up in the video. I’ve tried called renderInContext on presentationLayer, and on superLayer.presentationLayer, both with the same results. I really can’t rewrite the application ground up with OpenGL, and I’ve been chugging on strong for about 6 hours trying to find a solution.
I did manage to augment this code to record audio playing from the speakers, however it’s a bit of a hack, if anyone needs it. Hi Aroth Very nice sample and its working well and good in normal case. But i tried to record a screen on which several animations are going on and it was not able to record the animations running on it.
I hope this line of the code is used to enable capturing of screen on certain interval? videoWriter startSessionAtSourceTime:CMTimeMake(0, 1000); So i tried it after changing the value as below also but no success. videoWriter startSessionAtSourceTime:CMTimeMake(0, 10); Can you suggest me what could be the problem.
Regards Jalan. Hey, I am having trouble connecting the code to the corresponding parts in interface builder. I am building a tabbed bar application and I would like to record every view the user clicks on simultaneously. So, I figured that I would need to add the screenCaptureView to every tab I have and then connect it in interface builder but for some reason when I click on the connects outlets under files owner and try to drag it to the view nothing happens. Can you help with with this problem? Thanks in advance, T.D.