https://a.storyblok.com/f/270183/990463/dc329fd4df/fb_opentoklinux.png

Como adicionar streaming de video no Linux com o SDK do OpenTok para Linux

Publicado em May 7, 2021

Tempo de leitura: 5 minutos

Como adicionar streaming de video no Linux com o SDK do OpenTok para Linux

Como parte da nossa iniciativa OpenTok Labs, temos o prazer de compartilhar os novos exemplos de código do nosso SDK para Linux. Com o SDK para Linux, você poderá criar applications para desktop que ofereçam suporte a soluções de vigilância por Video em sistemas Linux embarcados e outros aplicativos nos quais seja necessária a transmissão de áudio e vídeo. A marca OpenTok Labs indica que o SDK está atualmente em fase de desenvolvimento, sem suporte oficial, portanto, adoraríamos que você contribuísse relatando problemas e enviando pull requests para aprimorá-lo. O SDK do OpenTok para Linux foi projetado para funcionar com consumo reduzido de recursos do sistema e baixo consumo de memória. Você pode usar o SDK para Linux por meio de uma API em C, o que permitirá que os desenvolvedores o integrem praticamente em qualquer lugar. Como o Linux tem sido amplamente adotado para diversos casos de uso, agora você pode ampliar seu alcance e adicionar comunicações em tempo real a dispositivos baseados em Linux usando a plataforma OpenTok.

Como funciona

Se você já está familiarizado com as APIs e os Concepts do SDK do OpenTok, será fácil começar a usar o SDK para Linux, pois ele utiliza os mesmos Concepts do OpenTok, como sessões, emissores e assinantes, entre outros. Com o SDK do OpenTok para Linux, também seguimos um modelo de programação em que o aplicativo inicia ações, como conectar-se a uma sessão, começar a publicar e assinar um stream, etc. Depois que a ação é iniciada e determinados eventos ocorrem, o aplicativo é notificado por meio de callbacks. Esses eventos, por exemplo, incluem:

  • quando uma sessão é estabelecida com sucesso ou ocorre um erro,

  • quando uma editora começa a publicar,

  • quando há um novo participante na sessão e quando um novo participante começa a publicar, o que aciona a criação de um novo assinante, etc.

Vamos começar a ver como implementar as etapas comuns utilizadas para adicionar Video ao vivo a qualquer aplicativo usando os SDKs de cliente do OpenTok.

Conectar-se a uma sessão

Ao se conectar a uma sessão, o desenvolvedor precisa fornecer as funções de retorno de chamada que implementam a resposta aos eventos de interesse do aplicativo. Os ponteiros para essas funções são fornecidos por meio de uma estrutura, que atua como um argumento para a função capaz de criar uma sessão. O ponteiro para essa nova sessão é usado posteriormente ao conectar a sessão. Assim como em nossos outros aplicativos de exemplo, o desenvolvedor precisa fornecer as credenciais do OpenTok (ou seja, chave de API, ID da sessão e token).

// ...

void onOpenTokSessionConnectedCallback(otc_session *session, void *user_data) {
}

void onOpenTokSessionStreamReceivedCallback(otc_session *session, 
                                            void *user_data,
                                            const otc_stream *stream) {
}

void onOpenTokSessionStreamDroppedCallback(otc_session *session,
                                           void *user_data,
                                           const otc_stream *stream) {
}

void onOpenTokSessionErrorCallback(otc_session *session,
                                   void *user_data,
                                   const char* error_string,
                                   enum otc_session_error error) {
}

// ...

struct otc_session_cb session_callbacks = {0};
session_callbacks.user_data = this;
session_callbacks.on_connected = onOpenTokSessionConnectedCallback;
session_callbacks.on_stream_received = onOpenTokSessionStreamReceivedCallback;
session_callbacks.on_stream_dropped = onOpenTokSessionStreamDroppedCallback;
session_callbacks.on_error = onOpenTokSessionErrorCallback;
session_ = otc_session_new(apiKey.c_str(), sessionId.c_str(), &session_callbacks);

if (session_ == nullptr) {
  return;
}

otc_session_connect(session_, token.c_str());

Publicar áudio e Video em uma sessão

Para os editores, seguimos a mesma abordagem e fornecemos funções de retorno de chamada que implementam a resposta aos eventos de interesse do aplicativo. Para o editor, o desenvolvedor é responsável por criar essas funções de retorno de chamada. Elas implementam a resposta a determinados eventos, por exemplo: quando o editor começa a publicar (o fluxo é criado e, em seguida, um evento é disparado), ou quando há um novo quadro do fluxo de Video do editor que pode ser renderizado, ou ainda quando ocorre um erro. Os ponteiros para essas funções de retorno de chamada são fornecidos por meio de outra estrutura que é passada como argumento para a função que cria um novo editor.

void onOpenTokPublisherStreamCreatedCallback(otc_publisher *publisher, 
                                             void *user_data, 
                                             const otc_stream *stream) {
}

void onOpenTokPublisherRenderFrameCallback(otc_publisher *publisher,
                                           void *user_data,
                                           const otc_video_frame *frame) {
}

void onOpenTokPublisherErrorCallback(otc_publisher *publisher,
                                     void *user_data,
                                     const char* error_string,
                                     enum otc_publisher_error error_code) {
}

struct otc_publisher_cb publisher_cb = {0};
publisher_cb.user_data = this;
publisher_cb.on_stream_created = onOpenTokPublisherStreamCreatedCallback;
publisher_cb.on_render_frame = onOpenTokPublisherRenderFrameCallback;
publisher_cb.on_error = onOpenTokPublisherErrorCallback;
publisher_ = otc_publisher_new(name_.c_str(), nullptr, &publisher_cb);

if (publisher_ == nullptr) {
  return;
}

Assim que a função de retorno de chamada de conexão da sessão for chamada, o aplicativo poderá começar a publicar. Isso pode ser implementado dentro da própria função de retorno de chamada. Observação: esta é uma função de retorno de chamada para a sessão. Um ponteiro para ela foi fornecido ao criar a sessão acima.

void onOpenTokSessionConnectedCallback(otc_session *session, void *user_data) {
  // ...
  if ((session_ != nullptr) && (publisher_ != nullptr)) {
    otc_session_publish(session_, publisher_);
  }
  // ...
}

The application should not allow the editor to publish anything until the session is connected.

Inscreva-se em um stream de áudio e Video

Sempre que um novo participante se conecta à sessão e esse participante está publicando, a sessão é notificada por meio da função de retorno de chamada recebida pelo fluxo da sessão. Podemos implementar a criação de um assinante dentro da função de retorno de chamada da sessão. Observe que essa função de callback pertence à sessão criada acima, e um ponteiro para ela foi fornecido ao criar a sessão. Assim como nos objetos de sessão e de publicador, o desenvolvedor precisa implementar as funções de callback. Sempre deve ser fornecida uma função de retorno de chamada de erro para acionar as notificações de erro. Isso se refere à função de retorno de chamada de erro. Se ocorrer um erro, a função de retorno de chamada é acionada. Quando o assinante é criado, a sessão pode se conectar ao novo assinante e começar a receber o fluxo de áudio e Video do novo participante.

// ...

void onOpenTokSubscriberRenderFrameCallback(otc_subscriber *subscriber,
					    void *user_data,
					    const otc_video_frame *frame) {
}

void onOpenTokSubscriberErrorCallback(otc_subscriber *subscriber,
                                      void *user_data,
                                      const char* error_string,
                                      enum otc_subscriber_error error_code) {
}

// ...

void onOpenTokSessionStreamReceivedCallback(otc_session *session,
					    void *user_data,
					    const otc_stream *stream) {
  // ...
  struct otc_subscriber_cb subscriber_cb = {0};
  subscriber_cb.user_data = conference;
  subscriber_cb.on_render_frame = onOpenTokSubscriberRenderFrameCallback;
  subscriber_cb.on_error = onOpenTokSubscriberErrorCallback;
  otc_subscriber* subscriber = otc_subscriber_new((otc_stream*)stream, &subscriber_cb);
  if (subscriber == nullptr) {
    return;
  }
  otc_session_subscribe(session, subscriber);
  // ...
}

// ...

Renderizar fluxo de Video

Se você deseja renderizar o fluxo de Video para emissores e assinantes usando o SDK do OpenTok para Linux, existem vários recursos úteis, como a biblioteca Simple DirectMedia Layer e outras bibliotecas de terceiros bem conhecidas que podem ajudar. As duas funções de retorno de chamada abaixo são chamadas quando há um novo quadro a ser renderizado para emissores e assinantes.

void onOpenTokSubscriberRenderFrameCallback(otc_subscriber *subscriber,
					    void *user_data,
					    const otc_video_frame *frame) {
}

void onOpenTokPublisherRenderFrameCallback(otc_publisher *publisher,
                                           void *user_data,
                                           const otc_video_frame *frame) {
}

Podemos usar um gerenciador de renderização, ou algo semelhante, que se encarregue de renderizar o quadro para nós. No exemplo abaixo, estamos usando a biblioteca Simple DirectMedia Layer.

void Renderer::onFrame(otc_video_frame* frame) {
  if (!window_) {
    return;
  }
  SDL_Surface* surface_ =  SDL_GetWindowSurface(window_);

  auto pixels = otc_video_frame_get_plane(frame, 0);
  SDL_Surface* sdl_frame = SDL_CreateRGBSurfaceFrom(
      const_cast<unsigned char*>(pixels),
      otc_video_frame_get_width(frame),
      otc_video_frame_get_height(frame),
      32,
      otc_video_frame_get_width(frame) * 4,
      0,0,0,0);

  SDL_BlitScaled(sdl_frame, NULL, surface_, nullptr);
  SDL_FreeSurface(sdl_frame);

  SDL_UpdateWindowSurface(window_);
}

Exemplos do SDK do OpenTok para Linux

Há algumas semanas, divulgamos um repositório no GitHub para o SDK do OpenTok para Linux com alguns exemplos para ajudar a entender melhor os recursos e as melhores práticas. Até o momento, temos três exemplos diferentes; no entanto, estamos trabalhando para adicionar muitos mais. Em um dos exemplos, é possível implementar um aplicativo básico de chat por vídeo que pode ser executado em um ambiente de desktop Linux comum (por exemplo, Ubuntu 18.04.2 LTS, Bionic Beaver). Como mencionamos anteriormente, o SDK do OpenTok para Linux pode ser usado para implementar uma solução de vigilância por vídeo, utilizando um minúsculo computador de placa única, como o Raspberry Pi, para transmitir vídeo como um endpoint exclusivamente de publicação. Essa funcionalidade de endpoint exclusivamente de publicação faz parte do exemplo que disponibilizamos.

Ciclo de vida das versões do SDK do OpenTok para Linux

Até o momento, o SDK do OpenTok para Linux está em beta fechado (beta privado). Nosso novo SDK já oferece valor, e é por isso que estamos lançando-o agora. No entanto, ele ainda não está pronto para uso em produção. Ainda estamos trabalhando na criação de todos os elementos necessários, como documentação para desenvolvedores e recursos para o nosso centro de desenvolvedores. Enquanto isso, adoraríamos receber seu feedback! Convidamos você a experimentar nosso novo SDK e nos dizer o que achou. SDK do OpenTok para Linux podem ser encontradas em nosso repositório no GitHub. Comece a usar qualquer uma das três compilações incluídas no GitHub, incluindo x86_64, armv7 e arm64. Fique ligado para mais novidades sobre o SDK do OpenTok para Linux.

Compartilhar:

https://a.storyblok.com/f/270183/400x400/5163f63112/jose-antonio.png
Jose Antonio Olivera Ortega

Based in Madrid, Spain, Jose Antonio is a Sr. Software Engineer at Vonage, contributing to the OpenTok Client SDKs and native codebase. He loves cross-platform and test-driven development, but hates pair programming. As an avid learner and programmer, Jose Antonio enjoys discovering more ways to create and innovate with technology, including mobile operating systems, WebRTC apps, Web APIs, IoT, and more.