0

AVAudioPlayer を使用して、iPhone アプリで音楽を再生しています。

私が書いたクラスには、ランダムな昇順の整数を含む配列があります。(2、4、9、17、18、20、...) これらの整数は、特定のイベントが発生する曲の時間を表します。したがって、上記の配列を使用すると、曲が再生されてから 2 秒後に何らかのメソッドが呼び出されます。4 秒後、別のメソッドを呼び出す必要があります。等々。

繰り返し NSTimer を使用してみました:

NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];

起動するたびに、Audioplayer の値と現在の arrayindex の値が同じかどうかをチェックします。

- (void) timerTick {
   if([[myArray objectAtIndex:currentIndex] intValue] == (int)(player.currentTime)) {
   //here the event-method is called
   currentIndex++;
   }
}

このコードは実際に機能しますが、しばらくの間だけです。しかし、しばらくすると、myTimer と音楽プレーヤーを制御するタイマーが同期しなくなります。そのため、myArray の要素が欠落し、無限ループが開始されます。なぜそれらが同期しなくなるのか正確にはわかりませんが、タイマーとプレーヤーがまったく同時に開始されていないか、パフォーマンスの遅れが原因である可能性があると思います.

まったく違う方法でアプローチする必要があると思います。キー値の監視はこれを行う方法ですか? クラスをオブザーバーとしてプレーヤー オブジェクトに追加して、player.currentTime の値が変更されたときに通知を受けるようにすることができます。しかし、それでは大量の通知が送信されることになり、パフォーマンスに非常に悪いと思います。

どんな助けでも大歓迎です!

4

3 に答える 3

1

これが私の解決策です。アプリが実行するのとほぼ同じことを実行するオープンソースアプリを見つけました。これは私を大いに助けてくれました。私はすでに持っているコードに固執するつもりですが、少し変更を加えるだけで、私の目的に十分正確になるはずです。ここにあります:

currentIndex = 0;
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];


- (void) timerTick {
 if(timerRunning){


     if([[myArray objectAtIndex:currentIndex] intValue] <= (int)(player.currentTime*100)) { 
         //some event code
         currentIndex++;
     }
 }
}

重要な変更は、if条件で==から<=になります。非同期になり、myArrayの要素が失われると、エラーは次の100分の1秒で修正されます。それで十分です。

ご協力いただきありがとうございます!

于 2009-10-26T20:30:40.710 に答える
0

タイマーが適度に同期している可能性がありますが、コードの実行に時間がかかるだけです(つまり、1秒より長くなります)。

ミュージックプレーヤーのタイマーを使用して、イベントが発生するたびにスレッドを生成することはできませんか?このようにして、タイマーは中断されずに維持され、スレッドは必要な処理を実行します(重いものを言いましょう)。

本当に2つのタイマーが必要な場合は、これら2つのタイマーの同期を維持するバックグラウンドスレッドを作成できると思いますが、そこで問題が発生していると思います。

于 2009-10-26T11:31:31.343 に答える
0

実際の音楽との同期は非常に困難です。ユーザーはわずか 10 分の 1 秒以下の同期ミスに気付く可能性があるからです。AVAudioPlayer は、必要なものに対して単純であることに気付くかもしれません。音楽をコードに同期させるのではなく、AudioQueueServicesを使用して音楽の再生速度を制御する必要がある場合があります。音楽が実際に再生される前に、コードを起動してメソッドを開始する時間が表示される可能性があります。これを巧みに行うと、ほとんどの場合、音楽が同期されます。

于 2009-10-26T13:51:55.617 に答える