I am using Opentok v2.0 in my iOS App for the chat/call purposes with other online users. Application has a feature of recording videos too when internet is absent so they can be uploaded later on. Everything is working accordingly but when I record videos after using Opentok features, UIImagePickerController opens Picture mode instead of Video mode. Here is my code of invoking camera for the video recording.
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.allowsEditing = NO;
self.picker.delegate = self;
self.picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
self.picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
[self presentViewController:self.picker animated:YES completion:nil];
}
Is it Opentok bug or am I doing something wrong? Please share your thoughts
Regards
This is a bug as of OpenTok iOS SDK version 2.3.1. To work around the issue, you can use the code below after exiting your OpenTok Session and before opening the UIImagePickerController. I would suggest placing this in your sessionDidDisconnect method
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:nil];
don't forget to set your Session object to nil for cleanup.
Now, if you want to be able to enter back into a Session and have proper audio, you will need to call:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
You can place this line of code before connecting with the Session Object's connectWithToken method.
Related
I'm trying to get a custom sound working on a UILocalNotification, and I'm just getting no sound at all. If I use UILocalNotificationDefaultSoundName, I indeed get the default sound, but when the custom sound is specified, there is no sound, just the message. The sound is less than 30 seconds and it's in the right format, as far as I can tell. Here's a screenshot of the file info:
I've inspected the .app directory in XCode's DerivedData directory, and the alarm.caf file is at the root of the app, which I believe means it's in the bundle (right?).
I'm pretty sure this was working a while ago, and I've since upgraded Xcode. Maybe that is a hint?
I've also tried deleting/reinstalling/rebooting as mentioned in other answers. As you can see, I'm calling cancelAllLocalNotifications first.
Does anyone have any idea what could be wrong?
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSLog(#"installing alarm");
[arguments pop]; // name
[arguments pop]; // title
alarm.alertBody = [arguments pop];
alarm.fireDate = [[NSDate date] addTimeInterval:[[arguments pop] intValue]/1000];
//alarm.soundName = UILocalNotificationDefaultSoundName;
alarm.soundName = #"alarm.caf";
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
Your code seems to be good.
Try to clean your project, uninstall your app from your device/simulator, then re-install it. It could help maybe :)
I don't know the reason (and I didn't read documentation too), I just turned on the action property notification setHasAction:YES and the sound began to play.
please make sure that the iPhone is not in silent mode( because your code seems to be good )
just check the button on the side of your iPhone
Ok, so here's what happened. I forgot how the app handles the notification itself if it is still running. My code was only displaying a UIAlertView and not playing the sound. I'm not sure why it worked with the default sound. In any case, I added code like this to my AppDelegate:
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"didReceiveLocalNotification");
if (application.applicationState == UIApplicationStateActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"MarkMyTime"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
NSString *soundFilePath = [[NSBundle mainBundle]
pathForResource:notification.soundName ofType:nil];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
[fileURL release];
player.delegate = self;
[player prepareToPlay];
[player play];
[alertView show];
if (alertView) {
[alertView release];
}
}
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog(#"Releasing player");
[player release];
}
This will show a UIAlertView and play the sound on the notification object. You also need to add the AVAudioPlayerDelegate interface to the AppDelegate to be able to assign the delegat to the player. I think if you are using ARC, this code could be simplified a bit.
#interface AppDelegate : PhoneGapDelegate <AVAudioPlayerDelegate> {
I'm not sure if this is the best approach, so feel free to chime in with any improvements.
Maybe you do not add the sound file (*.caf) in Xcode project: Build Phases/Copy Bundle Resources.
Your code is good, but check your iPhone setting
setting -> Notification center -> Your App -> Sound - > "On"
the sound should be "On".
So, to enable this, checked Inter App Audio at Capabilities in Targets of the application and it was Off Capabilities in Inter-app audio
change this to On.
Then local notification sound is working.
I want to record a video with UIImagePickerController. My Problem is that the method [imagePickerController startVideoCapture]; always returns 0. I am testing the application with an iPhone 4S running iOS 5.1. Could somebody please help me with this:
- (IBAction)playButtonPushed:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIView *videoView = self.videoViewController.view;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] >init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString >*)kUTTypeMovie, nil];
imagePickerController.showsCameraControls = NO;
imagePickerController.toolbarHidden = NO;
imagePickerController.wantsFullScreenLayout = YES;
imagePickerController.allowsEditing = YES;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
imagePickerController.videoMaximumDuration = 30;
[imagePickerController startVideoCapture];
imagePickerController.cameraViewTransform = > CGAffineTransformScale(self.imagePickerViewController.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);
imagePickerController.delegate = self;
[self.imagePickerViewController setCameraOverlayView:videoView];
NSLog(#"%s videoCapture: %d", __PRETTY_FUNCTION__, [imagePickerController > startVideoCapture]
);
[self presentModalViewController:imagePickerViewController animated:YES];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSLog(#"didFinishPickingMediaWithInfo");
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
NSLog(#"Cancel");
}
I had the same problem and Apple's documentation didn't help. That's because they missed to mention that startVideoCapture() can return false if you haven't set the capture mode to .video like this:
picker.cameraCaptureMode = .video
This worked for me and I'm able to capture videos now.
If im not mistaken, the "startVideoCapture" method is a bool
Taken straight from apple documentation:
startVideoCapture
Starts video capture using the camera specified by the UIImagePickerControllerCameraDevice property.
- (BOOL)startVideoCapture
Return Value
YES on success or NO on failure. This method may return a value of NO for various reasons, among them the following:
Movie capture is already in progress
The device does not support movie capture
The device is out of disk space
Discussion
Use this method in conjunction with a custom overlay view to initiate the programmatic capture of a movie. You can take more than one movie without leaving the interface, but to do so requires you to hide the default image picker controls.
Calling this method while a movie is being captured has no effect. You must call the stopVideoCapture method, and then wait until the associated delegate object receives an imagePickerController:didFinishPickingMediaWithInfo: message, before you can capture another movie.
Calling this method when the source type of the image picker is set to a value other than UIImagePickerControllerSourceTypeCamera results in the throwing of an NSInvalidArgumentException exception.
If you require additional options or more control over movie capture, use the movie capture methods in the AV Foundation framework. Refer to AV Foundation Framework Reference.
Availability
Available in iOS 4.0 and later.
Declared In
UIImagePickerController.h
stopVideoCapture
Stops video capture.
- (void)stopVideoCapture
Discussion
After you call this method to stop video capture, the system calls the image picker delegate’s imagePickerController:didFinishPickingMediaWithInfo: method.
Availability
Available in iOS 4.0 and later.
Declared In
UIImagePickerController.h
Think you need to call the startVideoCapture method after calling presentModalViewController:animated: and not before.
You probably also need a short delay (<1s?) after the UIImagePickerController has been presented on-screen and the animation has stopped, then call startVideoCapture, otherwise there are times where it will not start recording.
I had exactly the same problem. AndyV has it right, the recording won't start until the picker has been presented. I spent a lot of time trying to introduce a delay with sleep, but the simplest solution is to start a timer after displaying the picker using
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:#selector(startRecording) userInfo:nil repeats: NO];
Then ..
- (void)startRecording
{
BOOL result = [picker startVideoCapture];
}
I login to my server using a SOAP web service. Once logged in, many of the files that I am viewing are only available to the logged in user, so iOS must create a session in NSURL or something.
When trying to preview a video file using MPMoviePlayerViewController it will not work, it just loads up the viewController, then dismisses it.
If I use QuickLook it does work, probably because I download the video locally first, then view it.
But, I don't want to do it this way, I want to stream the video using MPMoviePlayerViewController because I don't want the user to have to download an entire video file. I have seen posts about using NSURLCredential but that doesn't seem to work for me. I used (added my own personal info obviously):
/**
* Play media session
*
* #version $Revision: 0.1
*/
- (void)playMediaWithURL:(NSString *)mediaURL {
// Authenticate
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"myusername"
password:#"mypassword"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"mysite.com"
port:80
protocol:#"http"
realm:nil
authenticationMethod:NSURLAuthenticationMethodDefault];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
// The movie player
NSURL *movieURL = [NSURL URLWithString:[mediaURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
MPMoviePlayerViewController *tempPlayer = [[MPMoviePlayerViewController alloc]initWithContentURL:movieURL];
// Add observer
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
// Properties
tempPlayer.moviePlayer.allowsAirPlay = YES;
tempPlayer.moviePlayer.shouldAutoplay = YES;
tempPlayer.moviePlayer.useApplicationAudioSession = NO;
[self presentMoviePlayerViewControllerAnimated:tempPlayer];
[tempPlayer.moviePlayer play];
}//end
Since this video is only viewable by a logged in user, if the video URL is accessed by a public user, they are presented with an HTML form to login. Does NSURLCredential not work in this case?
Why do all calls to NSURLConnection work, using my logged in credentials (such as downloading the video), but MPMoviePlayerViewController doesn't seem to use those same credentials, and refuses to play the video (probably because it gets the login page)?
Is there a solution to this?
Recently, I had a similar problem not being able to pass cookies to MPMoviePlayerController. I found from stack overflow that the solution is to use NSURLProtocol. Still, it was painful figuring out how to do it, so I thought I'd save people some time by sharing the coded solution: https://stackoverflow.com/a/23261001/3547099
I am using AVAudioPlayer in my application. When I select a song it plays, but my problem is, it is not playing when the device gets locked.
You need to read Executing Code in the Background in Apple's documentation. If you set the UIBackgroundModes key in you app's Info.plist to audio, audio will keep playing while backgrounded.
See the sections Declaring the Background Tasks You Support and Playing Background Audio in the aforementioned documentation.
All we need to make music play in the background with AVAudioPlayer by two step:
Step 1: Choose Project -> Capabilities -> Enable Background Modes -> Select Audio Mode
Step 2: Use this code:
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"demo" withExtension:#"mp3"];
avSound = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[avSound setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[avSound prepareToPlay];
[avSound setNumberOfLoops:-1];
[avSound setVolume:1.0];
Note that with this line the music can start even if the app was in the background:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
As per my knowledge it is not possible to play sound when device locked. Can't you just disallow device to lock and alive apps active always until user close it manually ?
I am building an application for iPod.
When running it, the native iPod music app should continue play in background, but this is not happening.
I think it might have something to do with the sound that it is played by my app. For playing a short sound at a certain point, I am using AVAudioPlayer. The code looks like this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"mp3"];
NSLog(#"%#", path);
player = [[AVAudioPlayer alloc] initWithData:[NSData dataWithContentsOfFile:path] error:nil];
[player prepareToPlay];
[player play];
Could this interfere with the native music player on iPod?
And another thing. In my app, I have integrated AdWhirl and it appears to use AudioToolbox.
Thanks a lot,
George
You must set up your AVAudioSession to use the Ambient category. This tells the system that your sound should blend with any already playing sound. The best way to do this in iOS 4 is in the app delegate, like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
// ...
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// reactivate audio session
[[AVAudioSession sharedInstance] setActive: YES error: nil];
}
Read up on Audio Sessions. If your app produces sound, you always want be conscious of and in control of your audio session.