A biblioteca LIVE555 é um conjunto de software C++ para streaming de mídia em tempo real sobre redes IP. Ela suporta protocolos como RTSP, RTP, RTCP e SDP.
Compilação e Teste no Windows
Para compilar a biblioteca LIVE555 no Windows, é necessário configurar os caminhos de inclusão para os diretórios liveMedia, UsageEnvironment, groupsock e BasicUsageEnvironment.
..\UsageEnvironment\include
..\liveMedia\include
..\groupsock\include
..\BasicUsageEnvironment\include
O projeto mediaServer requer a mesma configuração de inclusão de cabeçalhos e a adição dos arquivos-fonte apropriados.
Solução de Erros de Compilação
Durante a compilação, podem surgir erros relacionados a funcionalidades seguras da CRT e a funções obsoletas do Winsock. Para resolvê-los:
- Adicione
_CRT_SECURE_NO_WARNINGSàs definições do pré-processador. - Adicione
_WINSOCK_DEPRECATED_NO_WARNINGSàs definições do pré-processador.
Um erro comum ocorre na função BitVector::get_expGolombSigned:
int BitVector::get_expGolombSigned() {
unsigned codeNum = get_expGolomb();
if ((codeNum&1) == 0) { // even
return -(codeNum/2); // Erro C4146: operador unário de negação aplicado a tipo sem sinal
} else { // odd
return (codeNum+1)/2;
}
}
Para corrigir o erro C4146, é necessário um cast explícito:
int BitVector::get_expGolombSigned() {
unsigned codeNum = get_expGolomb();
if ((codeNum & 1) == 0) { // even
return static_cast<int>(codeNum / 2); // Corrigido para lidar com tipos sem sinal
} else { // odd
return static_cast<int>((codeNum + 1) / 2);
}
}
</int></int>
Outra configuração importante é desativar a verificação SDL nas propriedades do projeto (Propriedades do Projeto -> Propriedades de Configuração -> C/C++ -> Verificação SDL, defina como 'Não').
Erros de Linker no MediaServer
Após compilar as bibliotecas base, ao tentar compilar o mediaServer, podem ocorrer erros de linker devido a símbolos externos não resolvidos, como _initializeWinsockIfNecessary, _our_inet_addr, _our_srandom e _our_random.
Para resolver esses erros, certifique-se de que os arquivos inet.c (em groupsock) e rtcp_from_spec.c (em liveMedia) estejam incluídos no projeto mediaServer.
Além disso, adicione as seguintes diretivas #pragma comment(lib, ...) ao arquivo live555MediaServer.cpp para linkar as bibliotecas corretamente:
#ifdef _DEBUG
#pragma comment (lib, "../Debug/BasicUsageEnvironment.lib")
#pragma comment (lib, "../Debug/groupsock.lib")
#pragma comment (lib, "../Debug/liveMedia.lib")
#pragma comment (lib, "../Debug/UsageEnvironment.lib")
#else
#pragma comment (lib, "../Release/BasicUsageEnvironment.lib")
#pragma comment (lib, "../Release/groupsock.lib")
#pragma comment (lib, "../Release/liveMedia.lib")
#pragma comment (lib, "../Release/UsageEnvironment.lib")
#endif
Utilizando os Exemplos Fornecidos
A pasta testProgs na distribuição da LIVE555 contém exemplos úteis para testar a funcionalidade da biblioteca:
testRTSPClienteopenRTSP: Clientes RTSP para conectar a servidores de streaming.testOnDemandRTSPServer: Um servidor RTSP básico para servir mídia sob demanda.
Exemplo de Uso do testRTSPClient
Para testar a conexão com um fluxo RTSP:
./testRTSPClient rtsp://admin:senha@192.168.1.68:554/h264/ch1/main/av_stream
A saída do log demonstra a troca de mensagens RTSP (DESCRIBE, SETUP, PLAY) e o recebimento de pacotes RTP. Note que o cliente pode lidar com pacotes truncados se o buffer de recebimento for insuficiente.
Análise do Código Fonte (testRTSPClient)
O ponto de entrada principal é a função main:
int main(int argc, char** argv) {
// Configura o ambiente de uso:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
if (argc < 2) {
usage(*env, argv[0]);
return 1;
}
// Abre e inicia o streaming para cada URL fornecida:
for (int i = 1; i <= argc-1; ++i) {
openURL(*env, argv[0], argv[i]);
}
// Inicia o loop de eventos:
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
return 0;
}
A função openURL é responsável por criar um cliente RTSP e enviar o comando DESCRIBE:
void openURL(UsageEnvironment& env, char const* progName, char const* rtspURL) {
RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName);
if (rtspClient == NULL) {
env << "Falha ao criar cliente RTSP para URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n";
return;
}
++rtspClientCount;
rtspClient->sendDescribeCommand(continueAfterDESCRIBE);
}
A lógica para obter os próximos quadros de dados está em FramedSource::getNextFrame e MultiFramedRTPSource::doGetNextFrame, que gerenciam a leitura de pacotes RTP, incluindo o reordenamento e o processamento de cabeçalhos específicos do formato.
Compilação e Teste no Linux
Para compilar no Linux:
- Baixe e descompacte o código-fonte:
tar -xvf live555-latest.tar.gz - Gere os Makefiles:
./genMakefiles linux-64bit(ou a variante apropriada para seu sistema) - Compile:
make
Por padrão, a compilação gera bibliotecas estáticas (.a). Para gerar bibliotecas dinâmicas (.so), use:
- Gere os Makefiles para bibliotecas compartilhadas:
./genMakefiles linux-with-shared-libraries - Compile:
make
Após a compilação, os executáveis de teste (testRTSPClient, openRTSP, etc.) estarão disponíveis no diretório testProgs.
Teste de Streaming no Linux
Execute o testRTSPClient com a URL do fluxo:
./testRTSPClient rtsp://admin:jyzbyj306@192.168.3.229:554/h264/ch1/main/av_stream
O log exibirá a sequência de comunicação RTSP e o recebimento de pacotes RTP.
Extração de Pacotes RTP
Para cenários onde um único fluxo de câmera precisa ser acessado por múltiplos clientes ou decodificadores, é necessário implementar uma solução de software. A LIVE555 pode ser usada para capturar pacotes RTP de um fluxo RTSP.
A função DummySink::afterGettingFrame no testRTSPClient é um exemplo de como os quadros RTP recebidos são processados. O método MultiFramedRTPSource::doGetNextFrame1 é crucial para o processamento desses quadros, lidando com a fragmentação e a possível perda de pacotes.
A leitura de dados em baixo nível é realizada pela função readSocket, que utiliza a chamada de sistema recvfrom (ou read em sockets TCP).
Embora o testRTSPClient receba dados que parecem ser pacotes RTP, o processamento exato desses pacotes e a lógica para retransmiti-los ou decodificá-los podem exigir manipulação adicional, pois os dados brutos podem não ser diretamente compatíveis com todos os decodificadores sem o contexto correto do RTP.