Manipulando os eventos do player da Alexa

Como citado nos posts anteriores, ao ativar o AudioPlayer da Alexa, ela fornece alguns intents específicos para a obtenção do estado da execução. De modo geral, na skill da EximiaCo, utilizamos estes intents para duas tarefas principais: atualizar o estado de reprodução do episódio atual e para gerenciar o playback contínuo de episódios.

import ask_sdk_core.utils as ask_utils

from .player import Player
from ask_sdk_core.dispatch_components import AbstractRequestHandler


class PlaybackStartedHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return ask_utils.is_request_type("AudioPlayer.PlaybackStarted")(handler_input)

    def handle(self, handler_input):
        player = Player(handler_input)
        player.handle_playback_started()

        return handler_input.response_builder.response


class PlaybackNearlyFinishedHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return ask_utils.is_request_type("AudioPlayer.PlaybackNearlyFinished")(handler_input)

    def handle(self, handler_input):
        player = Player(handler_input)
        player.handle_playback_nearly_finished()

        return handler_input.response_builder.response


class PlaybackStoppedHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return ask_utils.is_request_type("AudioPlayer.PlaybackStopped")(handler_input)

    def handle(self, handler_input):
        player = Player(handler_input)
        player.handle_playback_stopped()

        return handler_input.response_builder.response


class PlaybackFinishedHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return ask_utils.is_request_type("AudioPlayer.PlaybackFinished")(handler_input)

    def handle(self, handler_input):
        player = Player(handler_input)
        player.handle_playback_finished()

        return handler_input.response_builder.response

Com o intent AudioPlayer.PlaybackStarted, simplesmente armazenamos o episódio em execução atual, para que, posteriormente, ele possa ser recuperado durante as possíveis modificações no estado do playback.

def handle_playback_started(self):
    current_token = self.handler_input.request_envelope.request.token
    self.state.set_token(current_token)
    self.state.set_current_episode(current_token)

No intent AudioPlayer.PlaybackNearlyFinished, a Alexa está informando que o episódio está perto do final, dando a possiblidade de definir o próximo episódio a ser executado. Importante reforçar a utilização do token ao enfileirar o playback. Quando é iniciada a reprodução, é informado o token da execução atual e também o token esperado da execução anterior, para garantir a ordem da execução. Caso o token anterior informado não coincida com o existente no episódio anterior (ou o atual, caso não tenha finalizado a reprodução), a diretiva PlayDirective é ignorada.

 def handle_playback_nearly_finished(self):
     current_episode = self.state.get_current_episode()
     if current_episode is None:
         return

     previous_episode = current_episode

     if not self.state.get_repeat():
         previous_episode = self.episodes_provider.get_previous(current_episode)

     if previous_episode is None and self.state.get_loop():
         previous_episode = self.episodes_provider.get_latest()

     if previous_episode is None:
         return

     self.handler_input.response_builder.add_directive(
         PlayDirective(
             play_behavior=PlayBehavior.ENQUEUE,
             audio_item=AudioItem(
                 stream=Stream(
                     token=previous_episode["pub"],
                     url=previous_episode["address"],
                     offset_in_milliseconds=0,
                     expected_previous_token=current_episode["pub"]),
                     metadata=None))
         ).set_should_end_session(True)

Quando paramos a execução do episódio com um comando como “Pare”, ou “Cancelar”, é invocado o intent AudioPlayer.PlaybackStopped. Neste intent, armazenamos o offset do episódio que está sendo reproduzido. Isto possibilita que a Alexa retome a reprodução do episódio, quando for solicitado que ela continue a reprodução.

def handle_playback_stopped(self):
    millis = self.handler_input.request_envelope.request.offset_in_milliseconds
    self.state.set_offset(millis)

Ao finalizar o episódio, a Alexa invoca o intent AudioPlayer.PlaybackFinished. Neste momento apenas zeramos o offset do playback. Isso faz com que, ao iniciar um novo episódio, a Alexa comece a reprodução do início, e não do offset supostamente armazenado no estado da execução.

def handle_playback_finished(self):
    self.reset()

Nesta etapa, a skill está pronta. No próximo post da série, falaremos sobre o seu processo de publicação.

Para quem acompanha os drops da EximiaCo, ou para aqueles que gostariam de acompanhar, a nossa skill está disponível no  Marketplace da Alexa. Gostaríamos muito de conhecer a sua opinião.

Compartilhe este insight:

Comentários

Participe deixando seu comentário sobre este artigo a seguir:

Subscribe
Notify of
guest
0 Comentários
Inline Feedbacks
View all comments

AUTOR

Douglas Picolotto
Mais de 15 anos de experiência como Engenheiro de nuvem, arquiteto de software, desenvolvedor e especialista em AWS e DevOps.

SOLUÇÕES EXIMIACO

ESTRATÉGIA & EXECUÇÃO EM TI

Simplificamos, potencializamos 
aceleramos resultados usando a tecnologia do jeito certo.

COMO PODEMOS LHE AJUDAR?

Vamos marcar uma conversa para que possamos entender melhor sua situação e juntos avaliar de que forma a tecnologia pode trazer mais resultados para o seu negócio.

COMO PODEMOS LHE AJUDAR?

Vamos marcar uma conversa para que possamos entender melhor sua situação e juntos avaliar de que forma a tecnologia pode trazer mais resultados para o seu negócio.

+55 51 3049-7890 |  contato@eximia.co

0
Queremos saber a sua opinião, deixe seu comentáriox
()
x

Tenho interesse em conversar

Se você está querendo gerar resultados através da tecnologia, preencha este formulário que um de nossos consultores entrará em contato com você:

O seu insight foi excluído com sucesso!

O seu insight foi excluído e não está mais disponível.

O seu insight foi salvo com sucesso!

Ele está na fila de espera, aguardando ser revisado para ter sua publicação programada.