Using AVCaptureSession and AVAudioPlayer together - iphone

I am able to record video and output the movie to a file correctly. However, I have a problem with video recording (no video ouput) when trying to use AVAudioPlayer to play some audio. Does it mean that I cannot use AVCaptureSession and AVAudioPlayer at the same time? Here is my code to create the capture session and to play the audio. The video capture is started first, then during the capturing, I want to play some audio. Thanks so much for any help.
Code to create the capture session to record video (with audio) - output to a .mov file:
- (void)addVideoInput
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
//... also some code for setting up videoDevice/frontCamera
NSError *error;
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput
deviceInputWithDevice:frontCamera error:&error];
AVCaptureDeviceInput *audioIn = [AVCaptureDeviceInput
deviceInputWithDevice:audioDevice error:&error];
if (!error) {
if ([captureSession canAddInput:audioIn])
[captureSession addInput:audioIn];
else
NSLog(#"Couldn't add audio input.");
if ([captureSession canAddInput:videoIn])
[captureSession addInput:videoIn];
else
NSLog(#"Couldn't add video input.");
}
- (void)addVideoOutput
{
AVCaptureMovieFileOutput *m_captureFileOutput = [[AVCaptureMovieFileOutput alloc] init];
[captureSession addOutput:m_captureFileOutput];
[captureSession startRunning];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSMutableString *filePath = [NSMutableString stringWithString:#"Movie.mov"];
NSString* fileRoot = [docDir stringByAppendingPathComponent:filePath];
NSURL *fileURL = [NSURL fileURLWithPath:fileRoot];
AVCaptureConnection *videoConnection = NULL;
for ( AVCaptureConnection *connection in [m_captureFileOutput connections] )
{
for ( AVCaptureInputPort *port in [connection inputPorts] )
{
if ( [[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
}
}
}
[videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
[m_captureFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:self];
[m_captureFileOutput release];
}
Code to play the audio, this function is call during the video capture session. If I don't call this function, the video is recorded and I am able to save to the .mov file. However, if I call this function, there's no output .mov file.
- (void)playAudio
{
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"AudioFile" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[fileURL release];
self.audioPlayer = newPlayer;
[newPlayer release];
[audioPlayer setDelegate:self];
[audioPlayer prepareToPlay];
[audioPlayer play];
}

I fixed the problem by setting up the audio session. I called the following function before creating the audio player object to play the audio. That way, I was able to record video (with audio) and play audio at the same time.
- (void)setupAudioSession {
static BOOL audioSessionSetup = NO;
if (audioSessionSetup) {
return;
}
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
[[AVAudioSession sharedInstance] setActive: YES error: nil];
audioSessionSetup = YES;
}
- (void)playAudio
{
[self setupAudioSession];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"AudioFile" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[fileURL release];
self.audioPlayer = newPlayer;
[newPlayer release];
[audioPlayer setDelegate:self];
[audioPlayer prepareToPlay];
[audioPlayer play];
}

Related

IPhone, Audio MP3 or M4A audio file plays no sound

I'm trying to play a sound method within the object didSelectedIndex UITableViewController
The audio files are files with extension m4a, but I also tried with mp3 files and the result does not change.
Below I post the code that I have implemented in the method of TableViewController:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *soundFilePath = [NSString stringWithFormat:#"%#/testaudio.m4a", [[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(#"soundFileURL %#",soundFileURL);
NSError *error;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if(!player){
NSLog(#"ERRORE: %#",error);
}
[player setDelegate:self];
[player prepareToPlay];
[player play];
}
I also tried directly on the device and it still does not play any sound.
I also added a class AVSession as follows:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
The result did not change, does anyone know what the problem is?
Try this (tested):
Set a property for your AVAudioPlayer object in your .m:
#property(strong, nonatomic) AVAudioPlayer *player;
Then add this in your:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *soundFilePath;
if ((soundFilePath = [[NSBundle mainBundle] pathForResource:#"testaudio" ofType:#"m4a"]))
{
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if(self.player)
{
[self.player setDelegate:self];
[self.player prepareToPlay];
[self.player play];
}
else
{
NSLog(#"ERRORE: %#", error);
}
}
}
You don't need AVAudioSession in your case.

How to set level meter on sound recording in iphone?

For recording sound, I am using the following code:
- (IBAction) recordClicked:(id)sender {
NSLog(#"play Record");
if (audioPlayerRecord) {
if (audioPlayerRecord.isPlaying) [audioPlayerRecord stop];
else {
[audioPlayerRecord play];
[self updateCurrentTimeForPlayer:audioPlayerRecord];
}
return;
}
//Initialize playback audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/recordTest.caf", recDir]];
NSError *error;
audioPlayerRecord = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[audioPlayerRecord play];
duration.text = [NSString stringWithFormat:#"%d:%02d", (int)audioPlayerRecord.duration / 60, (int)audioPlayerRecord.duration % 60, nil];
progressBar.maximumValue = audioPlayerRecord.duration;
[self updateViewForPlayerState:audioPlayerRecord];
NSLog(#"Recoder file >");
}
When recording is on going , I want to show the following type of level meter
So is there any other simplified way to achieve this problem?
check AQRecorder.mm ...
find: void AQRecorder::StartRecord(CFStringRef inRecordFile)
here you must comment / remove de line
url = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)recordFile, NULL);
with
url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)recordFile, kCFURLPOSIXPathStyle, false);

How to play a music file using URL link in iPhone?

I want to play a music file using URL Link in the iPhone. But when I use the below code I am getting error I am not getting where I am going wrong. Can anyone Correct me?
-(void)viewDidLoad
{
[super viewDidLoad];
NSString* resourcePath = #"http://192.167.1.104:8888/SHREYA.mp3"; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:_objectData error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
}
This should work:
NSURL *url = [NSURL URLWithString:#"<#Live stream URL#>];
// You may find a test stream at <http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8>.
self.playerItem = [AVPlayerItem playerItemWithURL:url];
//(optional) [playerItem addObserver:self forKeyPath:#"status" options:0 context:&ItemStatusContext];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.player = [AVPlayer playerWithURL:<#Live stream URL#>];
//(optional) [player addObserver:self forKeyPath:#"status" options:0 context:&PlayerStatusContext];
Use the following code to play the music:
[self.player play];
Try the following:
-(void)viewDidLoad
{
[super viewDidLoad];
NSString* resourcePath = #"your url"; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
audioPlayer.numberOfLoops = 1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
Try my code:
NSURL *filepath = [NSURL fileURLWithPath:audioFilePath];
[yourMediaPlayer setContentURL:filepath];
//set player.
yourMediaPlayer.controlStyle = MPMovieControlStyleNone;
yourMediaPlayer.currentPlaybackTime = 0;
yourMediaPlayer.shouldAutoplay = FALSE;
[yourMediaPlayer play];
^-^,I use MPMoviePlayerController with above code.
Current Answer:
Now consider Why does AVAudioPlayer initWithContentsOfURL always fail with error code=-43 link. its solution is avplayer link
Earlier Answer
//You have to pass NSURL not NSData
NSString* resourcePath = #"http://192.167.1.104:8888/SHREYA.mp3"; //your url
NSURL *url = [NSURL alloc]initWithString:resourcePath];
audioPlayer = [[AVAudioPlayer alloc] initWithURL:url error:&error];
audioPlayer.delegate = self;
[url release];
[audioPlayer prepareToPlay];
[audioPlayer play];
I guess you are sending
audioPlayer.numberOfLoops = -1;
to receive NSInvalidArgumentException change it to
audioPlayer.numberOfLoops = 1;
and check apple's documentation here

Sound does not play while using AVAudioPlayer

Here is my code on button click
- (void)playButton:(id)sender
{
NSLog(#"Play Button Clicked!!!...");
audioPlayer = [self setUpAudioPlayer:[songs objectAtIndex:i]];
}
-(AVAudioPlayer *)setUpAudioPlayer:(NSString *)filename
{
NSLog(#"File name : %#",filename);
NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:#"caf"];
NSLog(#"File path = %#",path);
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];
//audioPlayer.volume = 0.5;
[audioPlayer prepareToPlay];
[audioPlayer play];
NSLog(#"Song is playing....");
return [audioPlayer autorelease];
}
here songs is NSMutableArray which contains file name... All things go correct with NSLog... But no sound is coming and no error comes.. What is wrong with the code..???
Your audio player is probably getting released as soon as it starts playing. Try to retain it after setUpAudioPlayer is called.
Most probably you need to initialize an audio session, some like this
- (void)setupAudioSession
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error = nil;
[session setCategory: AVAudioSessionCategoryPlayback error: &error];
if (error != nil)
NSLog(#"Failed to set category on AVAudioSession");
// AudioSession and AVAudioSession calls can be used interchangeably
OSStatus result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self);
if (result) NSLog(#"Could not add property listener! %d\n", result);
BOOL active = [session setActive: YES error: nil];
if (!active)
NSLog(#"Failed to set category on AVAudioSession");
}

restarting a (audio) loop after it has finished

I want to play an audio loop by turning on a switch but i do not want the loop to end until the switch is turned off. When the loop ends i want it to simply start back at the beginning as to be continuos.
Try something like this. Note the -1 tells the music to repeat indefinitely:
Import this file at the top of your file:
#import <AVFoundation/AVFoundation.h>
Then to use it:
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:resourcePath ofType:#"caf"];
NSError *activationError = nil;
NSError *audioPlayerInitError = nil;
[[AVAudioSession sharedInstance] setActive: YES error:&activationError];
NSURL *newURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:newURL error:&audioPlayerInitError];
[newPlayer prepareToPlay];
[newPlayer setVolume:.8];
[newPlayer setNumberOfLoops:-1]; // -1 means play indefintely
[newPlayer setDelegate: self];
[newPlayer play];
[newPlayer release];
And then to stop it you would do:
if ([newPlayer isPlaying]) {
[newPlayer stop];
}