ios - 如何使用 Obj-C 在 iOS 中播放 mp3

标签 ios objective-c xcode mp3 media-player

我在 Objective-C 中有一个问题,我正在开发一个 iOS 应用程序,它应该播放特定的 mp3 文件集 -242 个 mp3 文件,所以有人可以告诉我播放它们的最佳方式是什么,我意思是我应该把它们放在服务器上,让它们都在本地还是什么?以及我应该如何在 Xcode 中对它们进行编码。

最佳答案

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.


  • 系统声音服务

    它对于音频警报和简单的游戏声音很有用。
    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



    它允许一次播放多个声音(对每个声音使用不同的 AVAudioPlayer),即使您的应用程序在后台,您也可以播放声音。. AVAudioPlayer 类是 AVFoundation 的一部分,您需要将 AVFoundation @import 到您的项目。
     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
    

    关于ios - 如何使用 Obj-C 在 iOS 中播放 mp3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31666475/

    相关文章:

    iphone - UIViewController 在新的 ARC 内存管理下没有被释放

    ios - 在 iOS 中获取子模块项目的 crashlytics 日志

    xcode - 如何拖动iphoneX模拟器?

    ios - 解析ParseFacebookUtilsV4登录问题

    ios - 从相机胶卷异步获取所有图像

    ios - 使用 ios sdk 进行 Tokbox Api session 记录

    objective-c - 核心数据选择一个 fetchRequest 中的第一条和最后一条记录

    ios - 为什么 iOS6 中的 UICollectionView 框架比我定义的要小?

    iOS - 将 CAGradientLayer 集中到父 UIView

    ios - 苹果公司是否正式禁止在后台访问用于应用程序的相机?