2016-09-18 1 views
0

Вопрос:Как заставить анимацию работать в точках во время воспроизведения музыкального файла?

В Swift код, кроме использования в NSTimer, как я могу получить анимации начать в точных точках во время воспроизведения музыкального файла воспроизводится с помощью AVFoundation?


фон

У меня есть метод, который играет музыкальный файл, используя AVFoundation (ниже). У меня также есть анимации UIView, которые я хочу начать с точных точек во время воспроизведения музыкального файла.

Один из способов добиться этого - использовать NSTimer, но у этого есть потенциал, чтобы выйти из синхронизации или не быть достаточно точным.

Есть ли способ, с помощью которого я могу использовать AVFoundation, чтобы получить доступ к времени музыкального файла (счетчик времени), поэтому, когда появляются определенные моменты во время воспроизведения музыки, начинается анимация?

Есть ли событие/уведомление, что триггеры AVFoundation, которые дают постоянный поток времени, прошедший с момента начала воспроизведения музыкального файла?


Например

При 0: 52.50 (52 секунд и 1/2), называют startAnimation1(), в соотношении 1: 20.75 (1 минута, 20 секунд и 3/4), звоните startAnimation2() и так далее?

switch musicPlayingTimeElapsed { 

case 0:52.50: 
    startAnimation1() 

case 1:20.75: 
    startAnimation2() 

default: 
    () 

} 

Воспроизведение музыки с помощью AVFoundation

import AVFoundation 
var myMusic : AVAudioPlayer? 

func playMusic() { 
    if let musicFile = self.setupAudioPlayerWithFile("fileName", type:"mp3") { 
     self.myMusic = musicFile 
    } 
    myMusic?.play() 
} 

func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer? { 
    let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String) 
    let url = NSURL.fileURLWithPath(path!) 
    var audioPlayer:AVAudioPlayer? 
    do { 
     try audioPlayer = AVAudioPlayer(contentsOfURL: url) 
    } catch { 
     print("AVAudioPlayer not available") 
    } 
    return audioPlayer 
} 

ответ

2

Если вы используете AVPlayer вместо AVAudioPlayer, вы можете использовать метод (ТВН немного неудобный) addBoundaryTimeObserverForTimes:

let times = [ 
    NSValue(CMTime:CMTimeMake(...)), 
    NSValue(CMTime:CMTimeMake(...)), 
    NSValue(CMTime:CMTimeMake(...)), 
    // etc 
]; 

var observer: AnyObject? = nil // instance variable 

self.observer = self.player.addBoundaryTimeObserverForTimes(times, queue: nil) { 
    switch self.player.currentTime() { 
    case 0:52.50: 
     startAnimation1() 
    case 1:20.75: 
     startAnimation2() 
    default: 
     break 
    } 
} 


// call this to stop observer 
self.player.removeTimeObserver(self.observer) 
+0

Спасибо, этот подход может работать. – user4806509

0

Вы можете попробовать использовать значение ключа Соблюдая соблюдать продолжительность свойства вашего звука, как он играет. Когда продолжительность достигает ваших пороговых значений времени, вы будете запускать каждую анимацию. Вам нужно, чтобы временные пороги совпадали с временем> = время запуска, так как вы, вероятно, не получите идеального соответствия с вашим желаемым временем.

Я не знаю, как хорошо это работает. Во-первых, я не уверен, что продолжительность звукового проигрывателя соответствует KVO.

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

2

Как я решить это разделить музыку на отдельные сегменты заранее.Затем я использую один из двух подходов:

  • Я проигрываю сегменты по одному, каждый в своем собственном аудиоплеере. Делегат аудиоплеера уведомляется, когда сегмент заканчивается, и поэтому начало следующего сегмента - вместе с сопровождающим действием - зависит от меня.

  • В качестве альтернативы, я помещаю все сегменты в AVQueuePlayer. Затем я использую KVO на. Таким образом, я уведомляюсь точно, когда мы переходим к новому сегменту.

+0

Интересно. Там нет заметных пробелов в воспроизведении сегментированного аудио, он просто играет гладко? – user4806509

+1

Если вы используете AVQueuePlayer, не будет пробелов. Это то, что AVQueuePlayer _is_. – matt

+0

Спасибо за это описание. – user4806509

Смежные вопросы