UISlider для управления AVAudioPlayer - PullRequest
33 голосов
/ 16 апреля 2010

Я пытаюсь реализовать небольшую функцию в моем приложении. В настоящее время я играю звуки как AVAudioPlayers, и это прекрасно работает. Что я хотел бы добавить, так это управлять положением звука (currentTime) с помощью UISlider: есть ли простой способ сделать это?

Я посмотрел на проект Apple, но он был довольно грязным .... У вас есть образцы или предложения?

Спасибо всем заранее

Ответы [ 3 ]

48 голосов
/ 16 апреля 2010

Не должно быть проблемой - просто установите слайдер в непрерывное положение и установите максимальное значение продолжительности вашего плеера после загрузки звукового файла.

Редактировать

Я только что сделал это, и это работает для меня ...

- (IBAction)slide {
    player.currentTime = slider.value;
}

- (void)updateTime:(NSTimer *)timer {
    slider.value = player.currentTime;
}

- (IBAction)play:(id)sender {
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"sound.caf" ofType:nil]];
    NSError *error;
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    if (!player) NSLog(@"Error: %@", error);
    [player prepareToPlay];
    slider.maximumValue = [player duration];
    slider.value = 0.0;

    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];  
    [player play];
}

Слайдер настроен в IB, как и кнопка для начала воспроизведения.

Обновление Swift 3.0:

var player: AVAudioPlayer!
var sliderr: UISlider!

@IBAction func play(_ sender: Any) {
    var url = URL(fileURLWithPath: Bundle.main.path(forResource: "sound.caf", ofType: nil)!)
    var error: Error?
    do {
        player = try AVAudioPlayer(contentsOf: url)
    }
    catch let error {
    }
    if player == nil {
        print("Error: \(error)")
    }
    player.prepareToPlay()
    sliderr.maximumValue = Float(player.duration)
    sliderr.value = 0.0
    Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateTime), userInfo: nil, repeats: true)
    player.play()
}

func updateTime(_ timer: Timer) {
    sliderr.value = Float(player.currentTime)
}

@IBAction func slide(_ slider: UISlider) {
    player.currentTime = TimeInterval(slider.value)
}
16 голосов
/ 16 апреля 2010

Чтобы расширить ответ Пола, вы должны установить ползунок непрерывным с максимальным значением duration вашего аудиоплеера, а затем добавить свой объект (возможно, контроллер вида) в качестве цели для ползунка UIControlEventValueChanged событие; когда вы получаете сообщение о действии, вы должны установить для свойства AVAudioPlayer s currentTime значение ползунка. Вы также можете использовать NSTimer для обновления значения ползунка во время воспроизведения аудиоплеера; +scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: - самый простой способ сделать это.

7 голосов
/ 10 ноября 2012

Мне нужно было немного адаптировать приведенный выше ответ, чтобы заставить его работать. Проблема в том, что используя

slider.maximumValue = [player duration];
slider.value = player.currentTime;
player.currentTime = slider.value;

Не работает, потому что ползунок ожидает float, а игрок currentTime и dration возвращают CMTime. Чтобы заставить их работать, я адаптировал их так:

slider.maximumValue = CMTimeGetSeconds([player duration]);
slider.value = CMTimeGetSeconds(player.currentTime);
player.currentTime = CMTimeMakeWithSeconds((int)slider.value,1);
...