Android下基于Http协议的网络摄像机开发

本文总结了在Android下开发基于Http协议的网络摄像机时遇到的挑战,包括Http身份认证和Rtsp数据流的处理。通过Base64加密处理身份验证,发现Java实现的Rtsp拆包组帧在处理高分辨率视频时存在效率问题,最终通过JNI底层优化实现了流畅的1280*720分辨率播放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    这段时间在做Android平台下的网络摄像机的兼容,摄像机的通讯采用Http1.1协议。现将遇到的问题简单总结一下:

1. Http协议中需要用到身份认证部分,不同厂家的摄像机所采取的方案可能有所不同,但是大体无外乎都是将摄像机的用户名和密码简单的用Base64加密转换后封装成特定字段反馈给摄像机,摄像机对接收到的加密字段进行匹配。常见的方法是:Base64(用户名:密码)(将用户名和密码用‘:’连接,然后对其进行Base64转换)。

2. 视频数据传输一般是采用Rtsp实时数据流传输协议,对Rtsp数据流进行拆包组帧转换为H264数据帧成了首要解决的问题。这个过程可以放在Android上层用Java实现,也可以放到JNI底层实现。本人最初在上层用Java实现了Rtsp的拆包组帧,最后在实际的运行当中发现:低分辨率的摄像机可以勉强运行,一旦连接高分辨率的摄像机就会出现丢帧和花屏的现象。最后不得不将该模块用C重写封装成接口放到底层,运行1280*720分辨率都很流畅。总结:Java实现数据转换的效率不高,最好放到JNI底层来实现复杂的数据运算。

3. H264解码器的问题。最初是从网上下载了一个经过裁剪的H264解码器(基于FFMPEG开源项目)。在测试中发现有时候会出现底层解码错误导致整个程序崩溃,这个问题困扰了我们很久。最后决定移植一个完整的ffmpeg解码器来解决这个问题,网上有众多网友做过相关的事情。经过漫长的接口封装调试最终成功解决。从1280*720、640*360、到320*240分辨率的测试 都很流畅(Android.mk、JNI接口文件,解码器源码等相关代码将上传到资源)

项目中后来用到的解码器为ffmpeg1.2版本,通过移植其H264视频解码模块来满足了应用项目的要求,下面贴上Jni接口的C源码:
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <android/log.h>
#include<netinet/in.h>

#include "ffmpeg/libavformat/avformat.h"
#include "ffmpeg/libavcodec/avcodec.h"
#include "ffmpeg/libswscale/swscale.h"

AVCodec *m_pCodec = NULL;
AVCodecContext *m_pCodecCtx = NULL;
AVFrame *m_pFrame = NULL;
struct SwsContext *pSwsCtx = NULL;
AVPacket m_packet;

int m_width = 0;
int m_height = 0;
const int MAX_VIDEO_W = 1280;
const int MAX_VIDEO_H = 720;
static int g_bInit = 0;
int g_iFrame = 0;

//picture
char    *fill_buffer;
AVFrame  *frame_rgb;
struct SwsContext  *img_convert_ctx;
jboolean bPicture = JNI_FALSE;
///
#define MAX_RGB_BUF 1280*720*3

// 视频参数定义
#define PT_H264 96
#define PT_G726	97	
#define PT_G711 8
#define PT_DATA 100
// global
static int g_iConnState = 0;
int ret = -1;
int outSize = 0;

const int nVideoLen = 1280 * 720;
const int nBufLen = 512000;
char *g_pVideoData = NULL;
char *g_pBufData = NULL;
int g_nCopyLen = 0;
int g_nBufLen = 0;
int g_nFullPackLen = 0;
int g_nNeedLen = 0;
unsigned int g_ts = 0;
int g_tsLen = 0;
char *m_srcInbuf = NULL;

//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 */ //pt说明: 96=>
### 回答1: 在非HTTPS页面中打开摄像头可能会存在安全隐患,因为这个操作需要访问设备的硬件资源,因此浏览器会限制此类操作。不过,有些浏览器可能允许你通过一些设置来允许在非HTTPS页面中打开摄像头。例如,Google Chrome浏览器可以通过启用“不安全内容”的选项来允许在非HTTPS页面中打开摄像头。但是,我建议你尽可能使用HTTPS页面来保护你的设备和数据安全。 ### 回答2: 要在手机浏览器的非HTTPS页面上打开摄像头,必须使用以下步骤: 首先,确保你的手机浏览器支持摄像头访问。大部分主流浏览器都支持,在上网之前,检查一下浏览器设置可以确定。 然后,在你的非HTTPS页面上添加一个调用摄像头的按钮或链接。这可以通过使用HTML5中的getUserMedia方法来实现。在按钮的点击事件中,使用相应的JavaScript代码来调用摄像头。 接下来,在调用getUserMedia方法之前,确保用户已经授权浏览器访问摄像头。这可以通过使用浏览器提供的getUserMedia方法来实现。在用户同意授权后,浏览器会返回一个包含摄像头视频流的对象。 最后,使用JavaScript将视频流显示在你的非HTTPS页面上。你可以创建一个HTML5的video元素,在JavaScript中将视频流附加到该元素上,并通过设置其属性来播放视频。 需要注意的是,在非HTTPS页面上打开摄像头存在一些安全隐患。HTTPS页面提供了更高的安全性和数据保护,因此建议尽量在HTTPS页面中进行摄像头访问。同时,用户还需保持警惕,以防止个人隐私泄露。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值