Ios AVAudioPlayer不会在一个项目中播放参数正确的音频,但在另一个项目中可以正常工作

Ios AVAudioPlayer不会在一个项目中播放参数正确的音频,但在另一个项目中可以正常工作,ios,objective-c,avaudioplayer,Ios,Objective C,Avaudioplayer,我有一个巨大的Xcode项目,我一直在更新它。安装iOS 7.1 SDK后,在此项目中在AVAudioPlayer上播放音频不再有效。我创建了一个新的空白项目来测试完全相同的代码,它工作得非常好 我确信文件是在捆绑资源下复制的,文件被添加到目标中,URL是完美的,因为我能够从文件的NSURL获取NSData,并且它是匹配的。AVAudioPlayer是一个具有强属性和非原子属性的属性,但它不会在这个项目中使用。我还确保将AVAudioSession设置为播放模式 我甚至创建了一些blank vi

我有一个巨大的Xcode项目,我一直在更新它。安装iOS 7.1 SDK后,在此项目中在AVAudioPlayer上播放音频不再有效。我创建了一个新的空白项目来测试完全相同的代码,它工作得非常好

我确信文件是在捆绑资源下复制的,文件被添加到目标中,URL是完美的,因为我能够从文件的NSURL获取NSData,并且它是匹配的。AVAudioPlayer是一个具有强属性和非原子属性的属性,但它不会在这个项目中使用。我还确保将AVAudioSession设置为播放模式

我甚至创建了一些blank view controller类来测试项目中的AVAudioPlayer,但在任何一个项目中都不起作用,但在我制作的新的空白iOS项目中,声音播放效果很好

在.h中

NSURL *soundUrl;
@property (nonatomic, strong) AVAudioPlayer *soundPlayer;
在.m中

@synthesize soundPlayer = _soundPlayer;

- (void)playSomeSound {
     NSError *audioError;
     soundUrl = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:soundFile ofType:@"m4a"]];
     _soundPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:&audioError];
     [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:NULL];
     _soundPlayer.delegate = self;
     [_soundPlayer play];
}
soundFile只是我试图播放的声音文件名称的字符串

我尝试记录音频播放器的所有委托方法和音频播放器初始化中的错误。所有错误返回(null)

在iOS 6.1上,与iOS 7上的音频根本不播放不同,初始化音频播放器会导致故障,故障代码为EXC_BAD_ACCESS code 2

此外,CocosDenshion中的AVAudioPlayer似乎也能工作。(我的部分项目中使用了cocos2d,但它不是游戏。)


另一个(可能是重要的)注意事项是,我在我的项目中也使用了AVAudioRecorder。这完全可以正常工作,没有任何问题,我确保在不录音时将AVAudioSessionCategory切换为playback。

这是由于苹果在iOS 7中对AVAudioSession属性所做的更改

根据苹果公司的文件:

音频类别已更改(例如AVAudioSessionCategoryPlayback 已更改为AVAudioSessionCategoryPlayAndRecord)


因此,更改行
[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayback错误:NULL]
[[AVAudioSession sharedInstance]设置类别:AvaudioSessionCategoryPlay和记录错误:NULL]

考虑到完全相同的代码在您的其他项目中工作,很难判断此项目中的问题是什么。但是我可以给你一些关于进一步调试它的建议:

  • 调用您的
    -playSomeSound
    ,这是您在
    应用程序中执行的第一件事:使用选项完成启动。
    。这样,在调用之前,您将看到它是否因为您所做的其他事情而不起作用
  • 在项目中添加另一个声音,并尝试播放该声音。也许问题仍然在于原始声音
  • 还有几个问题:

  • 哪里声明了
    audioError
  • [\u soundPlayer play]
    的结果是什么(应在 成功
  • 试试看:

        [_soundPlayer prepareToPlay];
        [_soundPlayer play];
    

    谢谢大家,但不知怎的,它最终导致了一些框架之间的冲突。Kamcord SDK for iOS中有一个bug,但我正在与他们的开发团队联系,他们正在努力修复它。

    这个问题在最新版本中仍然很明显,因此,不是每个遇到这个问题的人都必须联系他们,这里是修复AVAudioPlayer所需的最小代码/更改,而且Kamcord还将AVAudioPlayer的音频包含在其录音中


    首先,将OpenAL添加到框架中

    在AppDelegate.m中导入OpenAL头文件

    创建两个函数来启动和停止OpenAL

    - (void)startOpenAL
    {
        NSLog(@"OpenAL: Starting");
    
        openALDevice = alcOpenDevice(NULL);
        openALContext = alcCreateContext(openALDevice, NULL);
        alcMakeContextCurrent(openALContext);
    }
    - (void)stopOpenAL
    {
        NSLog(@"OpenAL: Stopping");
    
        alcMakeContextCurrent(NULL);
        alcDestroyContext(openALContext);
        alcCloseDevice(openALDevice);
    }
    
    在AppDelegate.m的didFinishLaunchingWithOptions中,启动OpenAL(我在初始化Kamcord之前启动)

    最后,在applicationWillTerminate中,调用stop OpenAL

    [self stopOpenAL];
    


    你完了。AVAudioPlayer现在应该重新开始工作,您的所有音频都被Kamcord正确录制。

    但这并没有解决问题。这实际上是我测试的许多东西之一。我测试了所有播放类别,包括PlayAndRecord。此外,这也不会帮助iOS 6崩溃错误。[[AVAudioSession sharedInstance]设置活动:是错误:&sessionError];在代码中也添加这一行,然后重试。这也不起作用。它很可能与AVAudioSession无关,因为我已经尝试了所有这些。请记住,我的代码在另一个项目中工作得很好,但它在我需要它的项目中无法工作。我在应用程序启动的一开始就输入了要调用的声音代码,就像你建议的那样,其中包含播放器上调用的播放方法的结果。声音没有播放,但它返回“是”。我也尝试了多种声音,但都不起作用。音频错误实际上是在顶部的同一个方法中声明的,但我似乎无意中遗漏了这个错误。这个问题已经为您解决了吗?我经历了一些非常相似的事情(除了SKActions之外,无法播放任何类型的音频),我正在使用Kamcord。嘿,我最终联系了Kamcord团队,一位工程师建议在课堂上初始化需要播放音频的OpenAL。基本上,我只是把本教程中的一些代码放进去,我的项目就这样结束了。我还必须联系他们的支持,这并没有我想象的那么有用,因为他们只是说“你需要初始化OpenAL”。经过一番研究,我成功地使它工作了,我只是用最简单的代码发布了一个关于这个问题的答案。:)
    - (void)startOpenAL
    {
        NSLog(@"OpenAL: Starting");
    
        openALDevice = alcOpenDevice(NULL);
        openALContext = alcCreateContext(openALDevice, NULL);
        alcMakeContextCurrent(openALContext);
    }
    - (void)stopOpenAL
    {
        NSLog(@"OpenAL: Stopping");
    
        alcMakeContextCurrent(NULL);
        alcDestroyContext(openALContext);
        alcCloseDevice(openALDevice);
    }
    
    [self startOpenAL];
    
    [self stopOpenAL];