1

I've a question in Objective-C, I'm working on an iOS application that should play a specific mp3 set of files -242 mp3 files exactly-, So could someone tell me what is the best way to play them all, I mean should I put them in a server, making them all local or what ? and how should I code them in Xcode.

3 Answers3

5

Apple provide many ways to play audio on the iPhone – System Sound Services, AVAudioPlayer, Audio Queue Services, and OpenAL. Without outside support libraries, the two easiest ways by far are System Sound Services and AVAudioPlayer.

  1. System Sound Services

    It is useful for audio alerts and simple game sounds.

    NSString *pewPewPath = [[NSBundle mainBundle] 
    pathForResource:@"pew-pew-lei" ofType:@"caf"];
    NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL,  
    &self.pewPewSound);
    AudioServicesPlaySystemSound(self.pewPewSound);
    

It is important to define pewPewSound as an iVar or property, and not as a local variable so that you can dispose of it later in dealloc. It is declared as a SystemSoundID. If you were to dispose of it immediately after AudioServicesPlaySystemSound(self.pewPewSound), then the sound would never play.

2. AVAudioPlayer

It allow to play several sounds at once (using a different AVAudioPlayer for each sound), and you can play sounds even when your app is in the background..The AVAudioPlayer class is part of AVFoundation, you will need to @import AVFoundation into your project.

 NSError *error;
self.backgroundMusicPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundMusicURL error:&error];
[self.backgroundMusicPlayer prepareToPlay];
[self.backgroundMusicPlayer play];

ATBViewController.h

#import <UIKit/UIKit.h>

@interface ATBViewController : UIViewController

@end

ATBViewController.m

#import "ATBViewController.h"
#import "AudioController.h"

@interface ATBViewController ()

@property (strong, nonatomic) AudioController *audioController;

@end

@implementation ATBViewController

#pragma mark - Lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];

    self.audioController = [[AudioController alloc] init];
    [self.audioController tryPlayMusic];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - IBAction

- (IBAction)spaceshipTapped:(id)sender {
    //The call below uses AudioServicesPlaySystemSound to play
    //the short pew-pew sound.
    [self.audioController playSystemSound];
    [self fireBullet];
}

- (void)fireBullet {
    // In IB, the button to top layout guide constraint is set to 229, so
    // the bullets appear in the correct place, on both 3.5" and 4" screens
    UIImageView *bullets = [[UIImageView alloc] initWithFrame:CGRectMake(84, 256, 147, 29)];
    bullets.image = [UIImage imageNamed:@"bullets.png"];
    [self.view addSubview:bullets];
    [self.view sendSubviewToBack:bullets];
    [UIView beginAnimations:@"shoot" context:(__bridge void *)(bullets)];
    CGRect frame = bullets.frame;
    frame.origin.y = -29;
    bullets.frame = frame;
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView commitAnimations];
}

- (void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    UIImageView *bullets = (__bridge UIImageView *)context;
    [bullets removeFromSuperview];
}

@end

AudioController.h

#import <Foundation/Foundation.h>

@interface AudioController : NSObject

- (instancetype)init;
- (void)tryPlayMusic;
- (void)playSystemSound;

@end

AudioController.m

#import "AudioController.h"
@import AVFoundation;

@interface AudioController () <AVAudioPlayerDelegate>

@property (strong, nonatomic) AVAudioSession *audioSession;
@property (strong, nonatomic) AVAudioPlayer *backgroundMusicPlayer;
@property (assign) BOOL backgroundMusicPlaying;
@property (assign) BOOL backgroundMusicInterrupted;
@property (assign) SystemSoundID pewPewSound;

@end

@implementation AudioController

#pragma mark - Public

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self configureAudioSession];
        [self configureAudioPlayer];
        [self configureSystemSound];
    }
    return self;
}

- (void)tryPlayMusic {
    // If background music or other music is already playing, nothing more to do here
    if (self.backgroundMusicPlaying || [self.audioSession isOtherAudioPlaying]) {
        return;
    }

       [self.backgroundMusicPlayer prepareToPlay];
    [self.backgroundMusicPlayer play];
     self.backgroundMusicPlaying = YES;
}

- (void)playSystemSound {
    AudioServicesPlaySystemSound(self.pewPewSound);
}

#pragma mark - Private

- (void) configureAudioSession {
    // Implicit initialization of audio session
    self.audioSession = [AVAudioSession sharedInstance];


    NSError *setCategoryError = nil;
    if ([self.audioSession isOtherAudioPlaying]) { // mix sound effects with music already playing
        [self.audioSession setCategory:AVAudioSessionCategorySoloAmbient error:&setCategoryError];
        self.backgroundMusicPlaying = NO;
    } else {
        [self.audioSession setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
    }
    if (setCategoryError) {
        NSLog(@"Error setting category! %ld", (long)[setCategoryError code]);
    }
}

- (void)configureAudioPlayer {
    // Create audio player with background music
    NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:@"background-music-aac" ofType:@"caf"];
    NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath];
    self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:nil];
    self.backgroundMusicPlayer.delegate = self;  // We need this so we can restart after interruptions
    self.backgroundMusicPlayer.numberOfLoops = -1;  // Negative number means loop forever
}

- (void)configureSystemSound {

    NSString *pewPewPath = [[NSBundle mainBundle] pathForResource:@"pew-pew-lei" ofType:@"caf"];
    NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL, &_pewPewSound);
}

#pragma mark - AVAudioPlayerDelegate methods

- (void) audioPlayerBeginInterruption: (AVAudioPlayer *) player {
        self.backgroundMusicInterrupted = YES;
    self.backgroundMusicPlaying = NO;
}

- (void) audioPlayerEndInterruption: (AVAudioPlayer *) player withOptions:(NSUInteger) flags{

      [self tryPlayMusic];
      self.backgroundMusicInterrupted = NO;
}

@end
Anand Prakash
  • 470
  • 6
  • 21
1

Apple provides AVAudioPlayer for handling audio media files. Another library you could use that works with Core Audio under the hood is EZAudio

Antonis
  • 114
  • 7
0

You could do something like this:

NSUrl *videoUrl = [NSUrl urlWithString:@"url"];
MPMoviePlayerViewController *playerViewController = 
    [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString: videoUrl]];
[self presentMoviePlayerViewControllerAnimated:playerViewController];
Epicblood
  • 1,146
  • 2
  • 10
  • 29
Burning
  • 26
  • 1