我已经搜索了我的问题的合适答案,但到目前为止我没有找到任何帮助。
我想在环境中记录分贝。如果超过特定阈值,应用程序将播放声音或歌曲文件。到目前为止一切正常但我有麻烦让应用程序在后台运行。
我已经添加了属性“应用程序不在后台运行”并将其值设置为“NO”。我已经读过,应该将“external-accessory”元素添加到“Required background modes”中。我也补充说,但它仍然不起作用。
我使用AVAudioRecorder
录制声音,AVPlayer
播放声音/音乐文件。首先,我使用MPMediaController
iPodMusicPlayer
,但它会抛出异常以及属性“必需的背景模式”。
编辑: 我正在使用xCode 4.5和iOS 6
编辑2: 当我将字符串viop添加到“所需的背景模式”时,它似乎在后台继续录制。但它在后台时仍然不播放音乐文件。我也尝试添加“音频”值,但没有帮助。
编辑3: 我咨询了苹果开发人员的参考资料。您似乎必须配置AVAudioSession。有了它似乎工作(link to reference)。但是现在我在播放多个文件时遇到了麻烦,因为只要第一首曲目播放完毕,该应用就会再次进入暂停模式。据我所知,不可能用多个文件初始化AVPlayer或AVAudioPlayer。我使用了委托方法methode audioPlayerDidFinishPlaying:成功:设置下一首曲目,但它没有用。
编辑4:好的,一种可能性是避免停止录音机,即删除[录音停止],以便它甚至可以在播放音乐时录制声音。这是一个有效的工作,但我仍然感谢任何其他(更好的)解决方案。一种不需要让录音机一直运行的解决方案。
相关代码: 我初始化viewDidLoad方法中的所有内容:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//[MPMusicPlayerController applicationMusicPlayer];
NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey,
nil];
NSError *error;
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
lowPassResults = -120.0;
thresholdExceeded = NO;
if (recorder) {
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
[recorder record];
levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
} else {
NSString* errorDescription = [error description];
NSLog(errorDescription);
}
}
每0.03秒调用一次的levelTimer回调:
- (void)levelTimerCallback:(NSTimer *)timer {
//refreshes the average and peak power meters (the meter uses a logarithmic scale, with -160 being complete quiet and zero being maximum input
[recorder updateMeters];
const double ALPHA = 0.05;
float averagePowerForChannel = [recorder averagePowerForChannel:0];
//adjust the referential
averagePowerForChannel = averagePowerForChannel / 0.6;
//converts the values
lowPassResults = ALPHA * averagePowerForChannel + (1.0 - ALPHA) * lowPassResults;
float db = lowPassResults + 120;
db = db < 0? 0: db;
if(db >= THRESHOLD)
{
[self playFile];
}
}
最后播放音乐文件的playFile方法:
- (void) playFile {
NSString* title = @"(You came down) For a day";
NSString* artist = @"Forge";
NSMutableArray *songItemsArray = [[NSMutableArray alloc] init];
MPMediaQuery *loadSongsQuery = [[MPMediaQuery alloc] init];
MPMediaPropertyPredicate *artistPredicate = [MPMediaPropertyPredicate predicateWithValue:artist forProperty:MPMediaItemPropertyArtist];
MPMediaPropertyPredicate *titlePredicate = [MPMediaPropertyPredicate predicateWithValue:title forProperty:MPMediaItemPropertyTitle];
[loadSongsQuery addFilterPredicate:artistPredicate];
[loadSongsQuery addFilterPredicate:titlePredicate];
NSArray *itemsFromGenericQuery = [loadSongsQuery items];
if([itemsFromGenericQuery count])
[songItemsArray addObject: [itemsFromGenericQuery objectAtIndex:0]];
if([songItemsArray count])
{
MPMediaItemCollection *collection = [[MPMediaItemCollection alloc] initWithItems:songItemsArray];
if ([collection count]) {
MPMediaItem* mpItem = [[collection items]objectAtIndex:0];
NSURL* mediaUrl = [mpItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem* item = [AVPlayerItem playerItemWithURL:mediaUrl];
musicPlayer = [[AVPlayer alloc] initWithPlayerItem:item];
[musicPlayer play];
}
}
}
有人能解决我的问题吗?我错过了什么吗?
答案 0 :(得分:1)
试试这个,
<强> AppDelegate.m 强>
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__block UIBackgroundTaskIdentifier task = 0;
task=[application beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Expiration handler called %f",[application backgroundTimeRemaining]);
[application endBackgroundTask:task];
task=UIBackgroundTaskInvalid;
}];
}