代码之家  ›  专栏  ›  技术社区  ›  Borut Tomazin

iPhone AVAudioPlayer应用程序首次播放时冻结

  •  2
  • Borut Tomazin  · 技术社区  · 14 年前

    我使用iossdk中的AVAudioPlayer来播放tableView行中每次单击的简短声音。 我手工做的 @selector 在激发方法的每行的 playSound:(id)receiver {} . 从接收器,我得到声音的网址,所以我可以播放起来。

    - (void)playSound:(id)sender {
        [audioPlayer prepareToPlay];
        UIButton *audioButton = (UIButton *)sender;
        [audioButton setImage:[UIImage imageNamed:@"sound_preview.png"] forState:UIControlStateNormal];
        NSString *soundUrl = [[listOfItems objectForKey:[NSString stringWithFormat:@"%i",currentPlayingIndex]] objectForKey:@"sound_url"];
    
        //here I get mp3 file from http url via NSRequest in NSData
        NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
        NSError *error;
        audioPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:&error];
        audioPlayer.numberOfLoops = 0;
        if (error) {
            NSLog(@"Error: %@",[error description]);
        }
        else {
            audioPlayer.delegate = self;
            [audioPlayer play];
        }
    }
    

    除了第一次播放一些声音外,一切正常。应用程序冻结约2秒钟,然后播放声音。第二个和每一个其他的声音播放工作后,点击声音按钮。

    4 回复  |  直到 6 年前
        1
  •  2
  •   Bill Garrison    14 年前

    从你的代码片段中, audioPlayer 一定是ivar,对吧?

    在方法的顶部,调用 -prepareToPlay 音频播放器

    在后面的方法中,您将用一个全新的AVAudioPlayer实例替换现有的音频播放器。上一个 -准备游戏 是浪费。每一个新的AVAudioPlayer都在泄露内存。

    我将尝试创建一个AVAudioPlayer对象缓存,每个声音对应一个对象,而不是缓存声音数据或url。在你的 -playSound: 方法,获取对表行的相应音频播放器的引用,然后 -play .

    你可以用 -tableView:cellForRowAtIndexPath: 作为获取该行的AVAudioPlayer实例的适当点,可能会延迟地创建实例并将其缓存在那里。

    -tableView:willDisplayCell:forRowAtIndexPath: -准备游戏

    或者你可以直接做准备 -表视图:cellforrowatinexpath:

        2
  •  2
  •   Chandan Shetty SP    14 年前

    检查是否在函数中异步获取数据。。

    NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
    

    如果是异步获取,则执行将被阻止,直到它获取数据为止。

        3
  •  1
  •   M Jesse    13 年前

    如果您的音频长度小于30秒,并且是线性PCM或IMA4格式,并且打包为.caf、.wav或.aiff,则可以使用系统声音:

    导入AudioToolbox框架

    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;
    }
    

    AudioServicesPlaySystemSound(mySound);
    

    这对我来说很管用,当按下按钮的时候,播放的声音非常接近。希望这对你有帮助。

        4
  •  0
  •   Alastair Stuart    14 年前

    对我来说,这有时也发生在模拟器中。这台设备似乎一切正常。你测试过实际的硬件吗?