一、前言
传统安防的摄像机基本都只是支持RTSP的方式查看视频,一般要实现播放视频的功能主要都以PC软件,或者OCX的方式,PC软件门槛相对比较高,可移植性差,每次需要修改点页面需要整一堆开发环境,对于嵌入式特别不友好;于是调研了一下无插件播放的技术,用的比较多的基本都是http-flv,wasm封装ffmpeg等;基于调研找了一个对于嵌入式最简单的解决方案,独立进程的方式实现;
二、仓库地址:
https://gitee.com/apchy_ll/WebRtsp.git
具体编译的方法见仓库里面内容
三、调试记录
1.live555拉流的时候,每次输入的都是一个nal帧,sps pps i p帧都是分开数据;
2.http-flv返回数据要求
1.第一次访问.flv的时候需要返回chunk
if (mg_vcmp(&hm->uri, "/live/stream.flv") == 0) {
mg_printf(nc,
"HTTP/1.1 200 OK\r\n"
"Content-Type: video/x-flv\r\n"
"Connection: Keep-Alive\r\n"
"Transfer-Encoding: chunked\r\n\r\n");
2..flv header 9个字节和 第一tag 0000需要分两行发送(就是要整成两个回车换行),否则flv.js解析不出来,代码参考如下
bool FlvStreamServer::SendFlvHeaderTag(struct mg_connection* nc) {
uint8_t header[9];
header[0] = 'F'; // FLV signature
header[1] = 'L';
header[2] = 'V';
header[3] = 0x01; // File version
header[4] = 0x01; // Type flags (audio & video)
header[5] = 0x00;
header[6] = 0x00;
header[7] = 0x00; // File version
header[8] = 0x09;
SendDataFlv(nc, (const char*)header, sizeof(header));
header[0] = 0x00; // FLV signature
header[1] = 0x00;
header[2] = 0x00;
header[3] = 0x00; // File version
SendDataFlv(nc, (const char*)header, 4);
return true;
}
3.每次发送flv tag 前面的格式都是长度 +"\r\n" + 数据,这个长度是十进制的,比如1890个字节数据必须为0x31 0x 38 0x90 0x30,
bool FlvStreamServer::SendDataFlv(struct mg_connection* nc, const char* pData,
int len, bool needheader) {
if (!needheader) {
return HttpSend(nc, pData, len);
}
std::stringstream decSize;
decSize << std::dec << len;
std::string chunkHeader = decSize.str() + "\r\n";
HttpSend(nc, chunkHeader.c_str(), chunkHeader.size());
if (pData) {
HttpSend(nc, pData, len);
HttpSend(nc, "\r\n", 2);
}
return true;
}
4.其它flv都是用libflv封装的.
四、效果
用手机的微信浏览器测试如下。
手机上看RTSP效果