一.描述
Android实现获取网络摄像头的视频流并且播放,以便实现手机实时监控。
网络摄像头:EsayN(普顺达)。
网络:内网。外网应该也也一样,没有测试。
协议文档:ip Camera视音频访问协议。
此文档主要是实现协议文档中发送 http get请求到网络摄像头,获取媒体数据响应包。
代码中摄像头的IP和端口分别是192.168.10.253 81。
二.发送http get请求包
1.使用Socket建立与摄像头的连接。
2.获得socket的OutputStream流。
3.StringBuffer中写要发送的请求包的内容。
4.OutputStream对象write StringBuffer中的数据。
三.获取媒体数据响应数据
1.获得socket的InputStream流。
2.根据InputStream流获取BufferedReader对象。
3.读取响应数据。
四.代码如下:
<span style="font-family:Microsoft YaHei;font-size:18px;"> Socket socket = new Socket("192.168.10.253", 81); OutputStream out = socket.getOutputStream(); InputStream in = socket.getInputStream(); StringBuffer sb = new StringBuffer(); sb.append("GET http://192.168.10.253:81/livestream/11?action=play&media=video_audio_data HTTP/1.1\r\n"); sb.append("User-Agent: HiIpcam/V100R003 VodClient/1.0.0\r\n"); sb.append("Connection: Keep-Alive\r\n"); sb.append("Cache-Control: no-cache\r\n"); sb.append("Authorization: admin admin\r\n"); sb.append("Content-Length: 57\r\n"); sb.append("Cseq: 1\r\n"); sb.append("Transport:RTP/AVP/TCP;unicast;interleaved=0-1\r\n"); sb.append("\r\n"); out.write(sb.toString().getBytes()); out.flush(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String tmp = ""; System.out.println("response:\r\n"); /*for(int i = 0;i<20;i++){ tmp = reader.readLine(); System.out.println(tmp); }*/ while ((tmp = reader.readLine()) != null) { System.out.println(tmp); } socket.close();</span>
五.问题
1.发送请求包之后响应包一直为空,获取不到数据。
原因:Authorization: admin admin,账号,也就是第一个admin之前必须要有空格。
2.针对上述代码在使用Juit测试的时候被卡死。
原因:查看Logcat发现一直在输出数据,不是在http包结束之后就停止输出了。,在http包之后输出的数据应该就是视频流数据。
六.总结
看到文档时的第一思路就是首先要获取响应包,但是在获取响应包之后不知道该怎么做,怎么处理获得的视频流,最后发现EasyN支持rtsp获得视频流,视频流地址格式为rtsp://[account]:[password]@[ip][port]/11
account: 账号
Password 密码
Ip 网络摄像头的ip
Port rtsp端口。默认是554
11代表主码流,12代表次码流。
例如:rtsp://admin:[email protected]:554/11 一定要注意端口。
七. ip Camera视音频访问协议文档
IP Camera 视音频访问协议
此文档描述了如何获取网络摄像机的视音频及其他媒体数据。网络摄像机支持公用通信
协议和私有通信协议,此文档主要描述私有协议的内容和协议的实现方式。
1. 公用通信协议 RTSP Over Http
Quicktime 支持此协议。详细请参考RTSP 协议,RTP 协议和http 协议。
2. 公用通信协议 RTSP Over UDP
Quicktime, VLC 支持此协议。详细请参考RTSP 协议,RTP 协议。
3. 私有通信协议
通过此协议实现获取媒体数据。
媒体数据包括,视频数据,音频数据,移动检测报警数据,外置报警数据。
此协议建立在 TCP/IP 之上。
3.1 通信协议工作流程
1). 媒体数据接收流程
发送媒体数据请求包
循环接收媒体数据
关闭 TCP 连接
接收响应包
建立 TCP 连接
3.2 通信协议详细说明
1). 媒体数据
a.媒体数据请求包
GET http://[IP]:[port]/livestream/[number]?action=play&media=[type] HTTP/1.1\r\n
User-Agent: HiIpcam/V100R003 VodClient/1.0.0\r\n
Connection: Keep-Alive\r\n
Cache-Control: no-cache\r\n
Authorization: [username] [password] \r\n
Content-Length: [length] \r\n
\r\n
Cseq: 1\r\n
Transport: RTP/AVP/TCP;unicast;interleaved=0-1\r\n
\r\n
字段
说明
IP
设备IP地址。
port
设备端口号。
number
码流号。
11: 第一通道主码流。
12: 第一通道次码流。
21: 第二通道主码流。
22: 第二通道次码流。
注意:目前设备只有第一个通道
type
请求数据类型
video 仅视频数据
audio 仅音频数据
data 仅报警数据(目前不支持)
video_audio 音视频数据
video_data 视频报警数据
audio_data 音频报警数据
video_audio_data 音视频,报警数据
username
用户名
password
密码
length
该字段以后数据的长度(从Cseq开始的字节数),可以使用strlen()函数
示例:
GET http://192.168.1.88:80/livestream/11?action=play&media=video_audio_data HTTP/1.1\r\n
User-Agent: HiIpcam/V100R003 VodClient/1.0.0\r\n
Connection: Keep-Alive\r\n
Cache-Control: no-cache\r\n
Authorization: guest guest\r\n
Content-Length: 57\r\n
Cseq: 1\r\n
Transport: RTP/AVP/TCP;unicast;interleaved=0-1\r\n
\r\n\
b. 媒体数据响应包
1). 用户名密码校验错误
示例:
HTTP/1.1 401 Unauthorized\r\n
Host: 192.168.1.88\r\n
Connection: Keep-Alive\r\n
2). 权限校验成功,返回音视频类型
HTTP/1.1 200 OK\r\n Host: [IP]\r\n Connection: Keep-Alive\r\n Server: HiIpcam/V100R003 VodServer/1.0.0\r\n Cache-Control: no-cache\r\n Accept-Ranges: Bytes\r\n Content-Type: application/octet-stream\r\n Connection: close\r\n
\r\n
Session: 15547656\r\n
Cseq: 1\r\n
m=video 96 H264/90000/[Width]/[Height]\r\n
m=audio 97 G726/8000/1\r\n
Transport: RTP/AVP/TCP;unicast;hisiinterleaved=0-1;ssrc=614fd4a1\r\n
\r\n
字段
说明
video
Width:视频宽。
Height:视频高。
视频只有H264
audio
97 G726
8 G711a
所有音频,都是单声道,8K采样,16位宽。
G711a码流64kbps
G726 码流16kbps
示例:
HTTP/1.1 200 OK\r\n Host: 192.168.1.88\r\n Connection: Keep-Alive\r\n Server: HiIpcam/V100R003 VodServer/1.0.0\r\n Cache-Control: no-cache\r\n Accept-Ranges: Bytes\r\n Content-Type: application/octet-stream\r\n Connection: close\r\n
\r\n
Session: 15547656\r\n
Cseq: 1\r\n
m=video 96 H264/90000/704/576\r\n
m=audio 97 G726/8000/1\r\n
Transport: RTP/AVP/TCP;unicast;hisiinterleaved=0-1;ssrc=614fd4a1\r\n
\r\n
注意:一定按照HTTP协议判断HTTP包结束。
c. 媒体数据包内容
1). 数据包头结构图
1. RTSP数据包头格式:
typedef struct
{
Unsigned char daollar; /*8, $:dollar sign(24 decimal)*/
Unsigned char channelid; /*8, channel id*/
Unsigned short resv; /*16, reseved*/
Unsigned int payloadLen; /*32, payload length*/
RTP_HDR_S rtpHead; /*rtp head*/
}RTSP_ITLEAVED_HDR_S;
字段
说明
payloadLen
代表后面的RTP数据包的长度(包括RTP_HDR_S头的长度)
注意:该字段为网络字节序
其他值可暂时不处理
2. RTP数据包头格式:
typedef struct
{
/* byte 0 */
Unsigned short cc :4; /* CSRC count */
Unsigned short x :1; /* header extension flag */
Unsigned short p :1; /* padding flag */
Unsigned short version :2; /* protocol version */
/* byte 1 */
Unsigned short pt :7; /* payload type */
Unsigned short marker :1; /* marker bit */
/* bytes 2, 3 */
Unsigned short seqno :16; /* sequence number */
/* bytes 4-7 */
Unsigned int ts; /* timestamp in ms */
/* bytes 8-11 */
Unsigned int ssrc; /* synchronization source */
} RTP_HDR_S;
字段
说明
音频编码数据或视频编码数据或报警数据
RTP数据包头
RTSP数据包头
pt
96 H.264
97 G.726
8 G.711a
100 报警数据
ts
时间戳,单位为毫秒
注意:该字段为网络字节序
其他值可暂时不处理
3. 视频编码数据
每次收到的视频数据为H.264的一个Nalu包。它可能是一个完整帧也可能不是.
当要
多个Nalu包组成一个完整帧时,就要进行组帧操作。
有一
个简便的方法可以组帧,判断时间戳,时间戳相同为一帧。
4. 音频编码数据
音频数据解码时,要先去掉4字节的私有数据头。
5. 报警数据
移动检测数据内容
当4个报警区域都有报警时如下:
“MDName1-x-y-width-height| MDName2-x-y-width-height| MDName3-x-y-width-height|MDName4-x-y-width-height|”
字段
说明
MDName
移动检测区域名称(值:1, 2, 3, 4)
x
X坐
标
y
Y坐
标
width
宽度
height
高度
“|”
数据分隔符
示例:
1-10-10-20-20|
外置报警数据内容
alarmin:1