3

質問に対する適切な回答を検索しましたが、これまでのところ役に立ちませんでした。環境内のデシベルを記録したい。特定のしきい値を超えると、アプリはサウンドまたは曲のファイルを再生します。これまでのところすべて正常に動作していますが、アプリをバックグラウンドで実行し続けるのに問題があります。「アプリケーションはバックグラウンドで実行されません」という属性を既に追加し、その値を「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];
        }
    }
}

誰でも私の問題を解決できますか? 他に何か見逃しましたか?

4

1 に答える 1

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;
   }];
}
于 2013-07-26T10:49:04.627 に答える