QTCaptureDevice Closing By itself (FaceTime Camera) Mac - objective-c

I have a mac app that writes camera data to a file then uploads that file on an [NSTimer] to a server. However, after the camera runs for a while it closes itself and I see this in the log: * QTCaptureDeviceInput warning: The device "FaceTime HD Camera (Built-in)" was closed while still being used in a capture session. Make sure that the session is not running before closing any devices it is using.
No other apps are open that can use the camera in the test case and the object for the device is not being released by me. I have gone so far as to call retain on it to prevent this, to no avail.
I looked at Apple's docs and nowhere that I found did it talk about the camera being shut off by the system, so what could be causing this. In the meantime I have some code that periodically checks if it is open and if it isn't calls open on it.
One thing I forgot I am using this notification and it is being fired: QTCaptureDeviceWasDisconnectedNotification

Well, it took a while but I found the issue. When you you are pulling image data from a running QTCaptureDevice you need to work with individual frames via the following delegate method. If you fail to properly release the buffers on each run the camera will eventually close by itself. Please note the code below is CORRECt; I attached it to help anyone else reading this question. Hope this saves someone the time it costed me...
- (void) captureOutput:(QTCaptureOutput *)captureOutput didOutputVideoFrame:(CVImageBufferRef)videoFrame withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection {
CVBufferRef bufferToBeReleased;
CVBufferRetain(videoFrame);
#synchronized (self) {
imageBufferToRelease = imageIWanted;
imageIWanted = videoFrame;
}
CVBufferRelease(bufferToBeReleased);
}

Related

FirebaseStorage Completion block not called. Objective-C

I am trying to simply load in a picture from firebase storage into my IOS app, but my completion block is not being called.
I use a TableViewController initially which loads plenty of pictures just fine. When I click on an item in the tableview it presents a simple view controller modally. I use the same code that successfully loads pictures in the TableViewController. In this modally presented view controller, my FirebaseStorage completion blocks do not execute. When I exit this view controller, the TableViewController can still load load pictures as necessary as I request.
I have enabled logging with -FIRAnalyticsDebugEnabled
and still do not receive any errors in my log.
I have allowed all read and writes temporarily in my rules for FirebaseStorage.
I have seen this question iOS setValue withCompletionBlock not called which states in the comments that a specific version of firebase had some issue with FirebaseDatabase blocking some other completion blocks.
The documentation said "Fixed a race condition where performing a transaction or adding an event observer immediately after connecting to the Firebase Realtime Database service could cause completion blocks for other operations to not be executed." from https://firebase.google.com/support/release-notes/ios#3.6.0
In the above question the asker fixed the problem by upgrading to Firebase 3.7.1, I am using 5.0.1
Here are the versions I am using
Using Firebase (5.0.1)
Using FirebaseAnalytics (5.0.0)
Using FirebaseAuth (5.0.0)
Using FirebaseCore (5.0.1)
Using FirebaseDatabase (5.0.0)
Using FirebaseInstanceID (3.0.0)
Using FirebaseStorage (3.0.0)
Using GTMSessionFetcher (1.1.15)
Using GoogleToolboxForMac (2.1.4)
Using leveldb-library (1.20)
Using nanopb (0.3.8)
Generating Pods project
I have logged all along my code to find that my code is being called, but the completion block is never executed. I am using the proper children ids, so I know that the storage reference does exist. I also know it is not a connection problem because the other pictures load fine just seconds before.
- (void)loadPicture {
NSLog(#"Attempting to load picture");
FIRStorageReference *ref = [[self.storageRef child:self.detailItem.faction] child:[self.detailItem firebaseEntry]];
[ref dataWithMaxSize:1024*1024 completion:^(NSData * _Nullable data, NSError * _Nullable error) {
NSLog(#"Got a result!");
}];
I am completely lost on what steps to take next. Has anyone experienced something similar or have any advice?
I appreciate any feedback that might help! Thanks!
Import this first
#import "UIImageView+FirebaseStorage.h"
and then for load image From reference use this
FIRStorageReference *gsReference = [[self.storageRef child:self.detailItem.faction] child:[self.detailItem firebaseEntry]];
[yourImage sd_setImageWithStorageReference:gsReference placeholderImage:nil];
I have solved the problem by creating a new ViewController to do the same action from scratch. Unfortunately I don't know what the original problem was or how to reproduce it. My original ViewController was about as simple as possible. The problem seemed like a strange glitch/flaw in the API, xcode, or emulator since no errors were present and it fixed itself in the new ViewController using the same exact code.
Everything else I saw online pointed to a issue involving Firebase 3.6.0 and below. Make sure you are using a recent Firebase version and then recreate the same ViewController and your problem will likely be fixed.

10.9 CoreBluetooth RetrivePeriperals

Im developing an app on OSX that uses CoreBluetooth. I have encountered a problem on OSX Mavericks that i cant seem to get around. (All of this works perfectly on OSX 10.8).
First lets go through the flow of the application
This flow is fairly established and has been used used successfully in iOS apps and works on 10.8. So on Mavericks, the first run completes successfully. It scans, finds and connects to the device correctly. It also saves out the UUID of the device to a .plist file along with other properties.
Upon relaunch of the app, it attempts to go down the left hand column of the flow which is where the problems seem to occur.
So the first issue i noticed was that my call to self.central retrievePeripherals: never calls my delegate callback of -(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals
. It simply never gets the callback on Mavericks.
My next thought was "oh they have a new API for fetching peripherals on Mavericks and the old one is deprecated, lets try that". So i added in my calls to NSArray *identifiers = [self.central retrievePeripheralsWithIdentifiers:#[uuid]]; and i get caught in a sempahore wait trap. Upon closer debugging of what was going on it turned out that sometimes my CBCentralManager gets into a state of CBCentralManagerStateUnknown and never updates the state to a newer one.
The next thing i tried was to fire up Activity Monitor and kill the blued process. Finally, my delegate callback for -(void)centralManagerDidUpdateState:(CBCentralManager *)central was called with the correct CBCentralManagerStatePoweredOn so i performed retrievePeripheralsWithIdentifiers again and received an empty array.
So all of these problems seem to be linked to blued in some way. Does anyone have more insight into this process to elude as to what is going on?
My main question is. Why does this work the first time through the app but not the second? Upon quitting the app after the initial scan and connection it seems i can no longer use the system bluetooth for anything without resetting blued (which even then doesn't retrieve peripherals). Is there some sort of shutdown sequence i need to do on the CBCentralManager to keep blued from going AWOL?
Any advice would be greatly apprecciated!
While this is obviously a very old thread, I stumbled upon the same issue today and decided to post a fix for posterity.
I was trying to hack together a simple app based on the HeartRateMonitor example provided by Apple. Unfortunately, it does not work on 10.9 if autoConnect is set to TRUE, what's worse, it brings blued down on its knees.
In 10.9, a call to the (deprecated) retrievePeripherals freezes blued without a chance to restore. CBCentralManager goes into CBCentralManagerStateUnknown, Bluetooth cannot be turned on/off using OS functions etc. The only solution that I found is to killall -9 blued.
However, the synchronous retrievePeripheralsWithIdentifiers worked well for me (on 10.9.4). Here's the relevant excerpt from the modified HeartRateMonitor code:
/* Retreive already known devices */
if(autoConnect)
{
NSArray *peripherals = [manager retrievePeripheralsWithIdentifiers:[NSArray arrayWithObject:(id)aPeripheral.identifier]];
NSLog(#"Retrieved peripheral: %lu - %#", [peripherals count], peripherals);
[self stopScan];
/* If there are any known devices, automatically connect to it.*/
if([peripherals count] >=1)
{
[indicatorButton setHidden:FALSE];
[progressIndicator setHidden:FALSE];
[progressIndicator startAnimation:self];
peripheral = [peripherals objectAtIndex:0];
[peripheral retain];
[connectButton setTitle:#"Cancel"];
[manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}
}

Testing internet connection on iPad app using ios5

I have been searching through the forum regarding how to check whether there is internet or not in my ipad app. I just created a simple webview project with other view controllers and I need to display a UIAlert message when the internet is not available. In my case it is displaying the message when I run the app. When I run the app with internet and then deactivate the internet, it does not show the UIAlert message, that is if I switch between the views, it does not any more show the no internet connection.
I have followed this way of implementation in my project: (sorry my mistake this is the link I followed) http://mozymac.com/forums/f54/how-check-if-there-internet-connection-iphone-os-devices-595/ [This is the new edited question]
Apart from that I went through some of the previous questions in Stackoverflow forum like for ex: How to check for an active Internet connection on iOS or OSX?
But everybody has their own version. If any one has a much more updated method for ios5, xcode 4.2.1 of how to accomplish this then would be helpful for me.
Thanks
Is there a reason why you want to check for internet connection before actually trying to load a request in the UIWebView?
Best practice is to just start loading, and use your UIWebViewDelegate/NURLConnectionDelegate to inspect the NSError to see what is wrong. In case of network failure you will receive an error with a domain equal to NSURLErrorDomain. The error code will indicate what the problem is, see the NSError codes enum.
And only after the first error start your reachability to see when the internet connection becomes available again. Or easier, just let the user retry.
Using the Reachability code will actually cause some overhead. It takes time to check if the internet is available, which you could just have used to set up the actual connection as well.
Example
Since you are using a UIWebView you should implement the following delegate method to be notified of errors.
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if (![[error domain] isEqualToString:NSURLErrorDomain]) {
// not a nsurl error, take other appropriate action
return;
}
NSInteger code = [error code];
// show appropriate error to user, based on code
}
In this delegate method you should do whatever is needed to achieve what you want. You could retry the request yourself, show a message to the user or start listening for reachability changes using the code from the Reachability example provided by Apple.
Apple has one, it's called Reachability. Here's the link to it.
http://developer.apple.com/library/ios/ipad/#samplecode/Reachability/Introduction/Intro.html
Best way to check internet connection is Reachibility application
link
Or else
+ (BOOL)isNetworkAvailable
{
CFNetDiagnosticRef diag;
diag = CFNetDiagnosticCreateWithURL (NULL, (CFURLRef)[NSURL URLWithString:#"www.apple.com"]);
CFNetDiagnosticStatus status;
status = CFNetDiagnosticCopyNetworkStatusPassively (diag, NULL);
CFRelease (diag);
if ( status == kCFNetDiagnosticConnectionUp )
{
//NSLog (#"Connection is up");
return YES;
} else {
NSLog (#"Connection is down");
return NO;
}
}

Objective-c -> class method to main file query

Sorry to bug twice so quickly, but since people were so kind in their informative responces, I figured it couldnt hurt to ask another question.
The same program i tried to make it rather swanky and have a main screen which allows you to click on a button which leads to a limited options screen. This lets you switch the music on or off. Or at least it should do.
The music running code is in the main file (game.m), under the following:
//Music
[Settings setMusicEnabled:YES];
music = [SPSound soundWithContentsOfFile:#"music.caf"];
channel = [[music createChannel] retain];
channel.loop = YES;
channel.volume = 0.25;
if([Settings musicEnabled]){
[channel play];
}
I apologize for the strange format, but it is Sparrow framework. basically, the Settings file contains the class methods I am trying to use. If the methods cause YES, the music is on. If it is No, then the music is off.
settings.m
static BOOL isMusicEnabled;
#implementation Settings
+ (BOOL)musicEnabled
{
return isMusicEnabled;
}
+ (void)setMusicEnabled:(BOOL)value
{
isMusicEnabled = value;
NSLog(#"SME? %i", isMusicEnabled);
}
#end
Now, the options file is working and i tested that section. The program is reading that isMusicEnabled is getting a new value, thus musicEnabled is being altered as well, so there should be a change and the music should be switched off.
However, nothing happens. I have tried to use debugger, but I am not very good at it and I dont understand a lot of the information i am given. I do understand that the problem is sending the message from Settings file to the main/Game file.
I would appriciate anyone's help who could enlighten me as to how this could be solved.
I'm not familiar with Sparrow Framework, but let me make a guess anyway.
[channel play]; starts playing the music in background until the channel is asked to stop playing.
Changing the isMusicEnabled does not trigger any code to stop the currently playing music. When you change the value in Settings, you should inform the channel to stop (most probably by somehow accessing the channel and calling [channel stop].
There's another problem - isMusicEnabled is just a variable in memory, your program will not remember its state between restarts. And Settings are usually supposed to be remembered.
To summarize I see two problems: persisting settings between restarts first and informing about change of settings second. To remember settings I suggest you look into NSUserDefaults class. To inform the channel to stop playing you have couple of options - depending on you skills. Easiest is to simply access the channel variable from within the setMusicEnabled and call stop. Another option would be to use notifications, but for a beginner programmer that is more complicated (look for NSNotificationCenter if interested).

How to know a video source (webcam) is available or not without creating capture window?

It is quite tricky because I wanna to take the result as a sign for later process. If a window flashes, it would be weird to user.
(This is not an answer, just refreshing the question and adding some details:)
Suppose you need to open a video capture driver (webcam) with code like this (delphi, but easy understandable):
result:= SendMessage(hCapWnd, WM_CAP_DRIVER_CONNECT, FDriverNo, 0);
It works fine, except when camera/webcam is busy (opened by another application, for example moviemaker). Then the capture driver suddenly shows a "select video source" window that blocks your application (but not moviemaker, which keeps recording). SendMessage function becomes modal and will not return until undesired window is closed.
Is there a way to detect if a capture driver is busy with another application before connecting to it?
Thanks
This function return number of available webcams and scanners on your mashine(с++).
int GetNumCam()
{
int MemberIndex = 0;
HDEVINFO dev;
SP_DEVINFO_DATA DeviceInfoData;
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
dev = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_IMAGE, NULL,NULL,DIGCF_PRESENT);
if (dev == NULL)
{
MessageBoxA(0,"it is null..","vse propalo",0);
return -1;
}
else
{
while(SetupDiEnumDeviceInfo(dev,MemberIndex, &DeviceInfoData))
{
MemberIndex++;
}
}
return MemberIndex;
}
I wonder if sending a broadcast message could do. I mean, suppose you send a VFW info request message to all windows in system. Then, all windows actually doing VFW processing will answer their status info and you will know which of them are doing video processing; some kind of shouting "anybody here...?"
But it looks like brute force, or even hacking. May be I'll test it... may be not. I am sure there must be a smarter way to know if a video capture driver is busy with another application.
(btw... anybody here?)
I was afraid it would happen.
First I enumerated all opened windows in system, then executed this instruction for each HWND, which just asks for driver information (pascal syntax):
SendMessage(h, WM_CAP_DRIVER_GET_NAME, length(driver)*sizeof(char), LPARAM(PChar(driver))
According to Msdn help, WM_CAP_DRIVER_GET_NAME results are:
"Returns TRUE if successful or FALSE if the capture window is not connected to a capture driver"
(Bold is mine). So it appears a good way to know:
1-If the window is capturing. So it is applyable to ALL windows, don't matter if they are capturing or not.
2-And if so, it tells you which driver is using.
However, after first test round, the results were:
- Task Manager (it was running) crashed and closed
- Explorer crashed and closed (reopened again automatically)
- Belkin Wireless monitor (my pc's WiFi driver) crashed and closed
- Eset Nod32 antivirus crashed, did not closed
The first conclussion can be that this is a bad way to locate which applications are capturing video in a system. But I must ensure to dismiss the possibility of a bug.
I'll keep reporting.
This is not a good solution my any means but I found out that if you disable and enable the camera in device manager immediately before sending the WM_CAP_DRIVER_CONNECT message then for some reason the video source window does not appear and the function returns and works OK.
So for a script I was working on I had to download devcon.exe and I put "devcon disable *PID_3450*MI_00*" and "devcon enable *PID_3450*MI_00*" immediately before my WM_CAP_DRIVER_CONNECT and it seems to work consistently. Unfortunately you need to run as administrator to be able to disable/enable devices. Again not a proper fix by any means...
(Hardware ID of my cam is USB\VID_0AC8&PID_3450&MI_00)