AVAudioPlayer is causing leaks under ARC - objective-c

I have a class that provides a Music Player, compiled under ARC. This is the init code:
- (id) init{
self = [super init];
runningVolumeNotification = FALSE;
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
systemVolume = musicPlayer.volume;
NSString *myExamplePath = [[NSBundle mainBundle] pathForResource:#"servo" ofType:#"mp3"];
AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:myExamplePath] error:NULL];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[p prepareToPlay];
[p stop];
return self;
}
Instruments reports a 100% leak on the line:
AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:myExamplePath] error:NULL];
I can't figure out where the problem is!

Related

How do I play a video from Cloudkit on tvOS?

I have a problem i have been trying to solve for a day and i tired of beating my head aaginst the wall. Anyone know how to do this?
Number 1 Works Great
Works Great
- (void) viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"http://techslides.com/demos/sample-videos/small.mp4"];
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:url];
self.player = avPlayer;
[self.player play];
}
Does not work
- (void) viewDidLoad {
[super viewDidLoad];
CKAsset *asset = record[#"VideoFile"];
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:asset.fileURL];
self.player = avPlayer;
[self.player play];
}
Does not work
- (void) viewDidLoad {
[super viewDidLoad];
CKAsset *asset = record[#"VideoFile"];
NSString *fileName = record[#"videoFileKey"];
NSData *data = [NSData dataWithContentsOfURL:asset.fileURL];
NSString *cachesDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *path = [cachesDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.mp4", fileName]];
[data writeToFile:path atomically:YES];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSURL *url = [NSURL URLWithString:path];
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:url];
self.player = avPlayer;
[self.player play];
}
}

Trouble hooking up AVAudioUnitEffect with AVAudioEngine

I've been poking around with AVAudioEngine and I'm having trouble integrating AVAudioUnitEffect classes. For example, with AVAudioUnitDelay...
#implementation ViewController {
AVAudioEngine *engine;
AVAudioPlayerNode *player;
}
...
- (IBAction)playButtonHit:(id)sender {
if (!player){
NSURL *bandsURL = [[NSBundle mainBundle] URLForResource:#"Bands With Managers" withExtension:#"mp3"];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:bandsURL error:nil];
engine = [[AVAudioEngine alloc] init];
player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
AVAudioUnitDelay *delay = [[AVAudioUnitDelay alloc] init];
delay.wetDryMix = 50;
[engine connect:player to:delay format:file.processingFormat];
[engine connect:delay to:[engine outputNode] format:file.processingFormat];
[player scheduleFile:file atTime:nil completionHandler:nil];
[engine prepare];
[engine startAndReturnError:nil];
}
[player play];
}
When the method is called the app crashes and I get this error: "* Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: [_nodes containsObject: node1] && [_nodes containsObject: node2]'"
I'm modeling this after some of the examples from the "AVAudioEngine in Practice" session from WWDC. I know there's probably something obvious I'm missing but can't figure it out....
You forgot to attach your AvAudioUnitDelay object to your AvAudioEngine nodes before linking them ;)
Here is the working code :
- (IBAction)playMusic:(id)sender {
if (!player){
NSURL *bandsURL = [[NSBundle mainBundle] URLForResource:#"Bands With Managers" withExtension:#"mp3"];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:bandsURL error:nil];
engine = [[AVAudioEngine alloc] init];
player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
AVAudioUnitDelay *delay = [[AVAudioUnitDelay alloc] init];
delay.wetDryMix = 50;
[engine attachNode:delay];
[engine connect:player to:delay format:file.processingFormat];
[engine connect:delay to:[engine outputNode] format:file.processingFormat];
[player scheduleFile:file atTime:nil completionHandler:nil];
[engine prepare];
[engine startAndReturnError:nil];
}
[player play];
}
It is not a problem of the AVAudioUnitEffect! I tried it with that code
NSError *err = nil;
self.engine = [[AVAudioEngine alloc] init];
AVAudioPlayerNode *player = [[AVAudioPlayerNode alloc] init];
[self.engine attachNode:player];
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:#"sound" withExtension:#"m4a"];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:fileURL error:&err];
AVAudioMixerNode *mainMixer = [self.engine mainMixerNode];
[self.engine connect:player to:mainMixer format:file.processingFormat];
[player scheduleFile:file atTime:nil completionHandler:nil];
[self.engine startAndReturnError:&err];
if (err != nil) {
NSLog(#"An error occured");
}
[player play];
while self.engine is defined by
#property (nonatomic, strong) AVAudioEngine *engine;
I think that is a bug in AVAudioEngine, because it causes a memory leak: It starts playing the first samples and then it crashes because of heavy memory usage (more than 300 MB in my case of a 16 kB m4a file).
Update 12/07/2014: Apple fixed this issue with iOS 8 Seed 3 (Build 12A4318c)!

Getting my AVAudio player to work

I'm trying to use AVAudioPlayer to play an mp3. Here is the code that I have:
- (void) playClip {
NSString *mp3File = [[NSBundle mainBundle] pathForResource:#"inFavor" ofType:#"mp3"];
AVAudioPlayer *avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];
[avPlayer play];
}
the name of the file that I'm referencing is "inFavor.mp3"
I'm a bit new to Objective-C so I'm not exactly sure why this isn't working. I'm using Xcode 5.
Make the AVAudioPlayer a property of the class so that it is not released when the function goes out of scope.
#property (strong, nonatomic) AVAudioPlayer* avPlayer;
Then initialize with
self.avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];
try this code, you need to check the error. paste the log you are getting in error
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource:#"inFavor"
ofType:#"mp3"];
AVAudioPlayer* avPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:&error];
if (error) {
NSLog(#"failed playing error: %#", error);
}else{
//avPlayer.delegate = self;
[avPlayer play];
}

Objective C error when playing multiple sounds

Hi i am trying to play many sounds using AVAudioPlayer and foundation.
The code is this
- (IBAction)pushButton19 {
NSString *path = [[NSBundle mainBundle] pathForResource:#"The Terminator" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
- (IBAction)pushButton20 {
NSString *path = [[NSBundle mainBundle] pathForResource:#"The Wizard of Oz" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
on the line theAudio.delegate = self;
it says
class * does not implement the
protocol
as well as
Semantic Issue Assigning to ID
from
incompatible type MainView *
what do i need to do to fix it and can u show me the correct code as im a noob at this?
Your controller must conforms to the AVAudioPlayerDelegate protocol and implements its necessary methods. This is a sample code for playing sound.

Cocoa Touch - Loading AVAudioPlayer

I have this code to play a sound but the first time you play it it takes a good 5 seconds to load...
How can I speed this up?
-(IBAction)playSound{ //play the cricket noise
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Cricket_Sound" ofType:#"mp3"];
audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundPath] error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
}
You can try by putting the following section of your code in viewDidLoad so that the audioPlayer instance is ready to play before it is asked to actually play the audio:
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Cricket_Sound" ofType:#"mp3"];
audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundPath] error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
audioPlayer.numberOfLoops = 0;