40

iPhoneのAVAudioPlayerを介して(非常に短い-2秒未満の)オーディオファイルを再生するときの起動ラグをなくそうとしています。

まず、コード:

NSString *audioFile = [NSString stringWithFormat:@"%@/%@.caf", [[NSBundle mainBundle] resourcePath], @"audiofile"];
NSData *audioData = [NSData dataWithContentsOfMappedFile:audioFile];

NSError *err;
AVAudioPlayer *audioPlayer = [(AVAudioPlayer*)[AVAudioPlayer alloc] initWithData:audioData error:&err];

audioPlayer.delegate = self;
[audioPlayer play];

また、audioPlayerDidFinishPlayingメソッドを実装して、完了したらAVAudioPlayerを解放します。

初めてオーディオを再生するとき、ラグは明白です-少なくとも2秒。ただし、その後すぐに音が鳴ります。そのため、原因は[NSData dataWithContentsOfMappedFile]が最初にフラッシュからの読み取りに長い時間を要したが、その後の読み取りでは高速であることが原因であると思われます。ただし、それをテストする方法はわかりません。

そうですか?もしそうなら、NSDataオブジェクトを事前にキャッシュし、メモリ不足の状態でそれらをクリアすることに積極的に取り組む必要がありますか?

4

9 に答える 9

39

遅延は、初めて AVAudioPlayer をインスタンス化することに関連しているようです。オーディオをロードし、[audioPlayer prepareToPlay] を実行してからすぐにリリースすると、他のすべてのオーディオのロード時間はほとんど感知できなくなります。だから今私は applicationDidFinishLaunching でそれをやっています、そして他のすべてはうまくいきます。

ドキュメントでこれについて何も見つけることができませんが、確かにそうです。

于 2010-06-21T04:48:51.700 に答える
11

これが私がやったことです(別のスレッドで):

[audioplayer start]
[audioplayer stop]
self.audioplayer = audioplayer

[audioplayer prepareToPlay] は非同期メソッドのように見えるため、オーディオが実際に再生する準備ができているかどうかがいつ返されるかはわかりません。

私の場合、実際に再生を開始するために start を呼び出します。これは同期しているように見えます。そしたらすぐやめます。とにかく、シミュレーターでは、このアクティビティから音が聞こえません。サウンドを再生する準備が「本当に」整ったので、ローカル変数をメンバー変数に割り当てて、スレッド外のコードがそれにアクセスできるようにします。

iOS 4 でさえ、わずか 4 秒の長さのオーディオ ファイルをロードするのに 2 秒ほどかかるのは、少し驚くべきことだと言わざるを得ません。

于 2011-03-15T01:14:22.087 に答える
8

オーディオの長さが 30 秒未満で、リニア PCM または IMA4 形式であり、.caf、.wav、または .aiff としてパッケージ化されている場合は、システム サウンドを使用できます。

AudioToolbox フレームワークをインポートする

.h ファイルで、次の変数を作成します。

SystemSoundID mySound;

.m ファイルの init メソッドで実装します。

-(id)init{
if (self) {
    //Get path of VICTORY.WAV <-- the sound file in your bundle
    NSString* soundPath = [[NSBundle mainBundle] pathForResource:@"VICTORY" ofType:@"WAV"];
    //If the file is in the bundle
    if (soundPath) {
        //Create a file URL with this path
        NSURL* soundURL = [NSURL fileURLWithPath:soundPath];

        //Register sound file located at that URL as a system sound
        OSStatus err = AudioServicesCreateSystemSoundID((CFURLRef)soundURL, &mySound);

            if (err != kAudioServicesNoError) {
                NSLog(@"Could not load %@, error code: %ld", soundURL, err);
            }
        }
    }
return self;
}

IBAction メソッドでは、次のようにサウンドを呼び出します。

AudioServicesPlaySystemSound(mySound);

これは私にとってはうまくいき、ボタンが押されたときにかなり近い音を再生します。これがお役に立てば幸いです。

于 2012-01-03T04:55:23.677 に答える
4

私は自分に合った別のアプローチを採用しました。私はこのテクニックが他の場所で言及されているのを見ました(それがどこにあったかは今のところ思い出せません)。

つまり、他の作業を行う前に、短い「空白の」サウンドをロードして再生することにより、サウンドシステムをプリフライトします。viewDidLoadビューコントローラのメソッドにプリロードした、持続時間が.1秒の短いmp3ファイルのコードは次のようになります。

   NSError* error = nil;
   NSString* soundfilePath = [[NSBundle mainBundle] pathForResource:@"point1sec" ofType:@"mp3"];
   NSURL* soundfileURL = [NSURL fileURLWithPath:soundfilePath];
   AVAudioPlayer* player = [[[AVAudioPlayer alloc] initWithContentsOfURL:soundfileURL error:&error] autorelease];
   [player play];  

必要に応じて、独自の空白のmp3を作成するか、「空白のmp3」をグーグル検索して、他の誰かがすでに作成したものを見つけてダウンロードすることができます。

于 2011-10-06T16:52:54.103 に答える
3

実際に機能する prepareToPlay メソッドを提供する AVAudioPlayer の単純なラッパーを作成しました。

https://github.com/nicklockwood/SoundManager

基本的には、アプリでサウンド ファイルをスキャンし、1 つを選択して音量ゼロで再生するだけです。これにより、オーディオ ハードウェアが初期化され、次のサウンドがすぐに再生できるようになります。

于 2012-05-02T16:21:27.493 に答える
0

他の回避策は、短くて無音のオーディオを作成し、プレーヤーの初回起動時に再生することです。

  1. システム環境設定でマイクレベルを 0 に設定します。
  2. QuickTime を開きます。
  3. 新しいオーディオ録音を作成します ([ファイル] > [新しいオーディオ録音])。
  4. 1 ~ 2 秒間記録します。
  5. オーディオファイルを保存/エクスポートします。(拡張子は .m4a で、サイズは約 2 kb です)。
  6. ファイルをプロジェクトに追加して再生します。

自分で新しいサウンド ファイルを作成したくない場合は、短いサイレント オーディオ ファイルをこちらからダウンロードできます: https://www.dropbox.com/s/3u45x9v72ic70tk/silent.m4a?dl=0

于 2016-11-25T23:33:53.823 に答える
-1

確かなことはわかりませんが、NSDataオブジェクトが遅延していて、ファイルの内容をオンデマンドでロードしているのではないかと思います。[audioData getBytes:someBuffer length:1];ある早い段階で呼び出して、必要になる前にそのファイルをロードすることで、「不正行為」を試すことができます。

于 2009-05-23T00:36:32.793 に答える
-1

答えは

AVAudioPlayer *audioplayer;
[audioplayer prepareToPlay];
于 2010-07-18T23:45:37.233 に答える