锡珠华航 發表於 2019-6-6 22:09:00

Android开发——通过wifi接收IPCamera视频流

<p>前面,我们已经了解了怎么在android app上打开关闭和扫描,搜索wifi,现在,我来写一下怎么通过连接wifi来使app获取到IPCamera摄像头的视频。</p>
<p>一、通过URL获取视频的地址</p>
<p>二、创建输入流</p>
<p>三、解析图片</p>
<p>&nbsp;</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&amp;pwd=&amp;resolution=32&amp;rate=1,<span style="color: rgba(0, 0, 0, 1)">主要是注意修改地址后面为/videostream.cgi,user和pwd是这个网页登入的账号和密码,就可以开始创建URL连接了。代码如下:</span></span></p>
<p>&nbsp;</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&amp;pwd=&amp;resolution=32&amp;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>&nbsp;</p>
<p>&nbsp;</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>&nbsp;</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 &lt; 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 &gt; 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()) &gt; 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 &gt; 0<span style="color: rgba(0, 0, 0, 1)">) {
                              </span><span style="color: rgba(0, 0, 255, 1)">if</span> ((index1 + 4) &lt;<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 &lt;<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>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/lwkdbk/p/10986960.html
頁: [1]
查看完整版本: Android开发——通过wifi接收IPCamera视频流