Android开发——通过wifi接收IPCamera视频流
<p>前面,我们已经了解了怎么在android app上打开关闭和扫描,搜索wifi,现在,我来写一下怎么通过连接wifi来使app获取到IPCamera摄像头的视频。</p><p>一、通过URL获取视频的地址</p>
<p>二、创建输入流</p>
<p>三、解析图片</p>
<p> </p>
<p>首先,我是通过抓包软件来抓取IPCamera摄像头的视频流,然后将其分包解析为一张一张的图片,再将其显示在界面上。由于我抓到的有GET /videostream.cgi?rate=0 HTTP/1.1 这样的字眼,所以可以知道,我所使用的是HTTP协议的摄像头。然后根据Referer: 后面的地址,可以推断出URL应为<span style="color: rgba(106, 135, 89, 1)">http://192.168.10.1/videostream.cgi?user=admin&pwd=&resolution=32&rate=1,<span style="color: rgba(0, 0, 0, 1)">主要是注意修改地址后面为/videostream.cgi,user和pwd是这个网页登入的账号和密码,就可以开始创建URL连接了。代码如下:</span></span></p>
<p> </p>
<div class="cnblogs_code">
<pre>URL url;<br>url = <span style="color: rgba(0, 0, 255, 1)">new</span> URL("http://192.168.10.1/videostream.cgi?user=admin&pwd=&resolution=32&rate=1"<span style="color: rgba(0, 0, 0, 1)">);
URLConnection conn </span>=<span style="color: rgba(0, 0, 0, 1)"> url.openConnection();
conn.connect();</span></pre>
</div>
<p> </p>
<p> </p>
<p>接下来,开始创建输入输出流。</p>
<div class="cnblogs_code">
<pre> InputStream input =<span style="color: rgba(0, 0, 0, 1)"> conn.getInputStream();
BufferedInputStream in</span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BufferedInputStream(input);
ByteArrayOutputStream outputStream </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ByteArrayOutputStream();</pre>
</div>
<p> </p>
<p>然后就可以开始分包接收到的图片了。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> readLength;
String flag </span>= "Content-Length:", flag1 = "\r\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当输入流有数据时,则创建byte数组</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (in.available() != -1<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">byte</span> buffer[] = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把读到的字节数给 readLength</span>
readLength = in.read(buffer, 0, 1024<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">让readLength读满</span>
<span style="color: rgba(0, 0, 255, 1)">while</span> (readLength < 1024<span style="color: rgba(0, 0, 0, 1)">) {
readlength </span>= in.read(buffer, readLength - 1, 1024 -<span style="color: rgba(0, 0, 0, 1)"> readLength);
readLength </span>= readLength +<span style="color: rgba(0, 0, 0, 1)"> readlength;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (readLength > 0<span style="color: rgba(0, 0, 0, 1)">) {
strData </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> String(buffer);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">标记"Content-Length: "的起始位置</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> index =<span style="color: rgba(0, 0, 0, 1)"> strData.indexOf(flag);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">标记"\r\n"的位置,注意是"Content-Length: "之后的第一个位置</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> index1 =<span style="color: rgba(0, 0, 0, 1)"> strData.indexOf(flag1, index);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (index1 != -1 || index1 - (index + flag.length()) > 0 || index != -1<span style="color: rgba(0, 0, 0, 1)">) {
String len;
len </span>= strData.substring(index +<span style="color: rgba(0, 0, 0, 1)"> flag.length(), index1);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">计算本次streamLength的长度</span>
streamLength =<span style="color: rgba(0, 0, 0, 1)"> Integer.parseInt(len.trim());
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (streamLength > 0<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ((index1 + 4) <<span style="color: rgba(0, 0, 0, 1)"> readLength) {
outputStream.write(buffer, index1 </span>+ 4, readLength - index1 - 4<span style="color: rgba(0, 0, 0, 1)">);
streamLength </span>= streamLength - readLength + index1 + 4<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将剩下读取的视频流存储到buffer1</span>
<span style="color: rgba(0, 0, 255, 1)">byte</span>[] buffer1 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> length = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (length <<span style="color: rgba(0, 0, 0, 1)"> streamLength) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (in.available() != -1<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Thread.sleep(50);</span>
length += in.read(buffer1, length, streamLength -<span style="color: rgba(0, 0, 0, 1)"> length);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
Thread.sleep(</span>150<span style="color: rgba(0, 0, 0, 1)">);
}
}
outputStream.write(buffer1, </span>0<span style="color: rgba(0, 0, 0, 1)">, streamLength);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] data =<span style="color: rgba(0, 0, 0, 1)"> outputStream.toByteArray();
BitmapFactory.Options op </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BitmapFactory.Options();
op.inSampleSize </span>= 2<span style="color: rgba(0, 0, 0, 1)">;
bitmap </span>= BitmapFactory.decodeByteArray(data, 0<span style="color: rgba(0, 0, 0, 1)">, data.length, op);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (bitmap != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">remoteSurfaceView.setImageBitmap(bitmap);</span>
<span style="color: rgba(0, 0, 0, 1)"> handler.sendEmptyMessage(MSG_ONE);
}
outputStream.reset();
}
}
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
Thread.sleep(</span>300<span style="color: rgba(0, 0, 0, 1)">);
}
} </span></pre>
</div>
<p>然后,通过handler来更新UI。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> Handler handler = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Handler() {
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> handleMessage(Message msg) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.handleMessage(msg);
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (msg.what) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> MSG_ONE:
remoteSurfaceView.setImageBitmap(bitmap);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
};</span></pre>
</div>
<p>这样,就可以显示IPCamera的视屏画面了,但是,在我的app界面上,视频始终不能一直播放下去,总是在看到几分钟的画面之后就停下了,具体原因我还没有搞清楚,也有可能是摄像头设备的问题,希望知道的高手可以解答一下。</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/lwkdbk/p/10986960.html
頁:
[1]