каковы функции запуска и остановки изолированного AVPlayer?

Как запустить segued iOS AVPlayer для запуска и остановки воспроизведения (с использованием Swift 2.2)?

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

Сообщения о подключении Watch работают правильно для воспроизведения звука с помощью 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" в строках player.Play () и player.StopPlay (). Я попытался заменить player на AVPlayer, destination и AVPlayerViewController, но это не исправляет.


person Dimitri T    schedule 17.08.2016    source источник


Ответы (2)


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

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

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

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

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

  • Есть несколько сообщений, а также Интернет-руководства, в которых рассказывается, как настроить WCSession менеджер.

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

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

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

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

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

person Community    schedule 17.08.2016
comment
спасибо, я изучаю это, очень полезно. Идея передачи URL-адреса контроллеру представления для AV-плеера - хорошая идея, я попробую это сейчас. Это кодирование для прототипа (для образцов / целей тестирования), поэтому `` быстрый и грязный взлом '' путем срезания углов по-прежнему имеет значение (как бизнес-решение, это тот случай, когда, когда `` застряли '', сначала имеет значение прототипирование с быстрое и грязное решение / обходной путь, пока я рассматриваю ваши мудрые предложения для более устойчивых решений). Я попробую использовать код в диспетчере сеансов просмотра и передать URL-адрес другому VC. Спасибо еще раз - person Dimitri T; 18.08.2016
comment
Без проблем! Хотя в прототипировании есть ценность, имейте в виду, что технический долг быстро накапливается! Быстрый и грязный код часто неожиданно попадает в готовую версию, потому что люди слишком заняты реализацией других функций и у них не хватает времени, чтобы также переписать хак. Ну что ж, мы должным образом позаботимся об этом в следующей версии. И затем им приходится иметь дело с ошибками / сбоями в поставляемом приложении из-за утечек памяти, условий гонки, работы на более быстрых / медленных устройствах / сетях и т. Д. - person ; 18.08.2016

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

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 ()' или сообщение паузы, мои часы приложение вылетает, поэтому - согласно ответу / мудрому совету @PetahChristian, это кажется конфликтует с другим кодом, и «автовоспроизведение» работает только как быстрое и грязное решение.

person Dimitri T    schedule 17.08.2016
comment
Метод play() будет проблематичным. Учтите, что вы вызываете его в момент, когда система готовится к тому, чтобы произошел переход. Целевой контроллер представления, возможно, еще не был представлен, его представление могло еще не быть загружено и т. Д. Если вы хотите, чтобы видео воспроизводилось автоматически, лучший способ сделать это - заставить целевой контроллер представления воспроизвести его, после появляется его вид. - person ; 18.08.2016