質問に対する適切な回答を検索しましたが、これまでのところ役に立ちませんでした。環境内のデシベルを記録したい。特定のしきい値を超えると、アプリはサウンドまたは曲のファイルを再生します。これまでのところすべて正常に動作していますが、アプリをバックグラウンドで実行し続けるのに問題があります。「アプリケーションはバックグラウンドで実行されません」という属性を既に追加し、その値を「NO」に設定しました。「必要なバックグラウンド モード」に「external-accessory」要素を追加する必要があることを読みました。それも追加しましたが、それでも機能しません。を使用しAVAudioRecorder
てサウンドを録音し、 を使用しAVPlayer
てサウンド/音楽ファイルを再生しています。最初に を使用しましたMPMediaController
iPodMusicPlayer
が、属性「必要なバックグラウンド モード」と共に例外がスローされます。
編集: iOS 6 で xCode 4.5 を使用しています
編集 2: 文字列 viop を「必要なバックグラウンド モード」に追加すると、バックグラウンドで記録が続行されるようです。ただし、バックグラウンドで音楽ファイルを再生することはできません。「オーディオ」値も追加しようとしましたが、役に立ちませんでした。
EDIT 3:リンゴ開発者リファレンスを調べました。AVAudioSession を設定する必要があるようです。それでうまくいくようです(参照へのリンク)。しかし、最初のトラックの再生が終了するとすぐに、アプリが再び一時停止モードになるため、複数のファイルを再生する際に問題が発生しました。私の知る限り、AVPlayer または AVAudioPlayer を複数のファイルで初期化する可能性はありません。デリゲート メソッドの audioPlayerDidFinishPlaying:successfully: を使用して次のトラックを設定しましたが、機能しませんでした。
編集 4: 1 つの可能性は、レコーダーの停止を回避することです。つまり、[record stop] を削除して、音楽の再生時にサウンドを録音することもできます。これは回避策ですが、これに対する他の(より良い)解決策に感謝します。レコーダーを常時稼働させておく必要のないソリューション。
関連するコード: 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];
}
}
}
誰でも私の問題を解決できますか? 他に何か見逃しましたか?