2016-08-17 4 views
0

Как мне инициировать запуск iOS AVPlayer, чтобы начать и остановить воспроизведение (используя Swift 2.2)?Каковы функции запуска и остановки выделенного AVPlayer?

Мое наблюдение Связи посылает команды сообщения «начать» и «остановить». Как мне закодировать функции здесь, чтобы реагировать и реагировать с игроком?

Сообщения о связях с часами работают правильно, чтобы воспроизводить аудио с помощью AudioPlayer в другом контроллере. Теперь я пытаюсь адаптировать это для управления видео.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    let destination = segue.destinationViewController as! 
    AVPlayerViewController 
    let url = NSURL(string: self.specimen.filmMovieLink) 
    destination.player = AVPlayer(URL: url!) 
} 

// WATCH CONNECTIVITY MESSAGE TO TRIGGER START AND STOP VIDEO 
    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) { 
     var replyValues = Dictionary<String, AnyObject>() 
     switch message["command"] as! String { 
     case "start" : 
      //play video - correct here 
      player.Play() 
      replyValues["status"] = "Playing" 
     case "stop" : 
      //stop video - correct here 
      player.stopPlay() 
      replyValues["status"] = "Stopped" 
     case "volume" : 
      let level = message["level"] as! Float 
      //player.adjustVolume(level) 
      replyValues["status"] = "Vol = \(level)" 
     default: 
      break 
     } 
     replyHandler(replyValues) 
    } 
} 

Я получаю сообщение об ошибке «Использование неразрешенного идентификатора 'игрока на линии player.Play() и player.StopPlay(). Я попытался заменить„игрок“с„AVPlayer“,' destination 'и' AVPlayerViewController ', но это не исправляет.

ответ

3

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

Контроллер вида предназначен для управления его собственными видами. Он не должен пытаться контролировать что-то в контроллере , который он представил (через segue).

  • Я не рекомендовал бы передавая AVPlayer объект от контроллера предъявлению (источник) вида на представленном (назначения) контроллер представления. Вместо этого вы можете просто передать url в prepareForSegue.

  • Это позволит контроллеру вида назначения создать экземпляр своего собственного AVPlayer и позволить игроку быть инкапсулированным в пределах этого контроллера представления. В соответствии с инкапсуляцией никакой другой контроллер представления не должен знать (или пытаться взаимодействовать) с этим объектом.

Что касается «управления» игроком с сеанса просмотра, я бы предложил настроить диспетчер сеансов приложений. Это переносит ответственность сеанса из контроллера представления (где это действительно не так) и устраняет сложность попытки передать один (неактивный, исходный) контроллер представления WCSession сообщений от имени другого (активного, целевого) контроллера представления ,

  • Там areseveral сообщений, а также интернет-уроки, которые обсуждают, как настроить WCSession менеджера.

  • Разделение функциональности на отдельные модули также упрощает ведение кода (и позволяет вам вводить или издеваться над различными частями кода во время модульного тестирования).

Если вы перепроектировать приложение таким образом, то вы могли бы использовать уведомление сделать то, что вы хотите.Например, ваш менеджер сеансов может опубликовать соответствующее уведомление на основе сообщения, которое он получает с часами, а ваш контроллер AVPlayer может наблюдать и реагировать на уведомления «начать», «остановить» и «громкость».

Есть ли другие варианты?

Если вы просто хотите, чтобы запутанный подход работал, вы можете попробовать настроить делегат (разрешить контроллеру второго представления делегировать управление своим игроком на первый контроллер представления) или иметь первый контроллер представления ссылку на второй контроллер просмотра, чтобы он мог напрямую манипулировать своим игроком.

Но имейте в виду, что вам (или кому-то еще) придется поддерживать этот код по дороге. Каждый раз, когда вы пытаетесь сэкономить время «вырезать углы» или использовать «быстрые и грязные хаки», будет потрачено впустую позже. Не удивляйтесь, когда вы ужаснулись от старого кода, который вы (или кто-то еще) написали, или пытаетесь запомнить/понять, почему вы/они решили сделать это таким образом, и надеясь, что вы случайно не сломаете вещи из-за всех свертка.

+0

Благодарю вас, я изучаю это, очень полезно. Идея передать URL-адрес контроллеру вида для AV-плеера является хорошей, я попробую это сейчас. Это кодирование предназначено для прототипа (для целей тестирования/тестирования), поэтому «быстрый и грязный взлом» путем сокращения углов по-прежнему имеет значение (в качестве бизнес-решения это случай, когда «застревание» имеет значение в прототипировании сперва с быстрое и грязное решение/обходное решение, в то время как я смотрю ваши мудрые предложения для более устойчивых решений). Я попробую код в диспетчере сеансов и передаю URL другому VC. Еще раз спасибо –

+0

Нет проблем! Хотя в прототипировании есть * значение *, имейте в виду, что технический долг складывается быстро! Быстрый и грязный код часто неожиданно превращает его в версию доставки, потому что люди слишком заняты реализацией других функций и не имеют времени, чтобы переписать взлом. «О, хорошо, мы позаботимся об этом в следующей версии». И тогда им приходится иметь дело с ошибками/сбоями в отгруженном приложении из-за утечек памяти, условий гонки, работы на более быстрых/медленных устройствах/сетях и т. Д. –

-1

Отвечая на более простую часть вопроса о том, что функция будет вызывать воспроизведение с Segue (как автозапуск в действие), я решил это, что код:

destination.player .play()

Я попытался destination.play() и player.play(), который не работает, так как функция должна быть destination.player .play(), как показано здесь:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    let destination = segue.destinationViewController as! 
    AVPlayerViewController 
    let url = NSURL(string: self.specimen.filmMovieLink) 
    destination.player = AVPlayer(URL: url!) 
    destination.player!.play() 

}

Вызов 'destination.player! .Play()' и 'destination.player! .Pause()' в функции подключения часов не приводит к ошибкам. Однако, нажимая кнопку «Мои часы», чтобы отправить сообщение «start» для «destination.player !.play()» или «pause message», мои часы показывают, что приложение терпит крах, поэтому, как и в ответе/мудреце @ PetahChristian, это кажется быть конфликтующим с другим кодом, а «автовоспроизведение» работает только как быстрое и грязное решение.

+0

Метод 'play()' будет проблематичным. Подумайте, что вы вызываете его в тот момент, когда система *** готовит *** для перехода. Возможно, контроллер точки назначения еще не был представлен, его представление, возможно, еще не загружено, и т. Д. Если вы хотите, чтобы видео было «автовоспроизведено», лучшим способом сделать это является то, чтобы контроллер воспроизведения назначения воспроизводил его, * после * появляется его представление. –