Android视频监控实现(一)

作者:华清远见

第一章 系统简介

近年来,视频监控市场的发展已经进入高速时期,与此同时,随着国内各大运营商对基础网络建设的巨大投入,快速地推动了网络摄像机在各个领域的快速发展应用。安卓在Google的推进以及本身的开放性作用下,已经延生到生活的各个方面,从安卓智能手机、平板,到可穿戴的Android Ware、眼镜、手表、再到Android汽车、智能家居、电视,甚至日本出的几款机器人都是Android系统的,传统监控中的移动终端设备,例如:单兵设备、手持设备、车载终端设备,包括家庭监控中用到的智能设备,都可以用Android系统替代了,不仅开发容易,而且易扩展,设备也更加智能了。在此思路下我们实现了Android手机的音视频采集与上传、流媒体服务器转发、多平台播放器播放的实时监控系统。

1.1 视频采集安卓端(spydroid)

Google Code上有一个开源项目:spydroid-ipcamera,spydroid能在Android手机中建立一个精简的HTTP Server和RTSP Server,功能类似于一般的IpCamera,既能够通过网页访问摄像机并修改监控配置,还能通过http或者rtsp协议,获取监控的实时音视频。具体原理是,通过android手机对mediaRecorder录制视频,把localsocket传输到本地的流经过硬编码,添加RTP头,分离NALU包,根据RTSP协议交互过程把数据发送到对方。而且从其代码结构中,spydroid已经实现了RTSPServer、RTSPClient、RTP、RTCP、H264、AAC...等等功能,总之,音视频采集与上传需要的Utility都已经具备了,我们将这些功能组合到一块实现了直播需求。

1.2 流媒体服务器(Darwin Streaming Server)

Darwin Streaming Server简称DSS。DSS是Apple公司提供的开源实时流媒体播放服务器程序。整个程序使用C++编写,在设计上遵循高性能,简单,模块化等程序设计原则,务求做到程序高效,可扩充性好。并且DSS是一个开放源代码的,基于标准的流媒体服务器,可以运行在Windows NT和Windows 2000,以及几个UNIX实现上,包括Mac OS X,Linux,FreeBSD,和Solaris操作系统上的。

1.2.1 主体框架

DSS的核心服务器部分是由一个父进程所fork出的一个子进程构成,该父进程就构成了整合流媒体服务器。父进程会等待子进程的退出,如果在运行的时候子进程产生了错误从而退出,那么父进程就会fork出一个新的子进程。可以看出,网络客户和服务器直接的对接是由核心服务器来完成的。网络客户RTSPoverRTP来发送或者接受请求。服务器就通过模块来处理相应的请求并向客户端发送数据包。

核心流媒体服务通过创建四种类型的线程来完成自己的工作,具体如下:

服务器自己拥有的主线程。当服务器需要关闭检查,以及在关闭之前记录相关状态打印相关统计信息等任务处理时,一般都是通过这个线程来完成的。

空闲任务线程。这个任务线程是用来对一个周期任务队列的管理,主要管理两种任务,超时任务和Socket任务。

事件线程。套接口相关事件由事件线程负责监听,当有RTSP请求或者收到RTP数据包时,事件线程就会把这些实践交给任务线程来处理。

任务线程。任务线程会把事件从事件线程中取出,并把处理请求传递到对应的服务器模块进行处理,比如把数据包发送给客户端的模块,在默认情况下,核心服务器会为每个处理器核创建一个任务线程。

1.2.2 相关协议

如果要使用QuickTime流媒体服务器的编程接口,您应该熟悉该服务器实现的互联网工程组织(Internet Engineering Task Force,简称IETF)协议,列举如下:

实时流媒体协议(Real Time Streaming Protocol,简称RTSP)

实时传输协议(Real Time Transport Protocol,简称RTP)

实时传输控制协议(Real Time Transport Control Protocol,简称RTCP)

对话描述协议(Session Description Protocol,简称SDP)

1. 实时流媒体协议

当我们需要创建并且对一个或多个时间的同步且连续的音视频的媒体数据流控制的时候,我们需要用到RTSP协议,也就是实时流协议。RTSP并不是通过连续的数据流来创建并控制媒体流数据的,所以不会产生媒体流与控制流的交叉。用另外一种说法就是,RTSP本身是对流媒体服务器的远程控制。为了时间实时音视频数据的受控(快进,暂停)以及按需分配流,这个协议为我们提供了可实现的框架。实时流控制协议可以用在对多个数据发送的会话,通过UDP或者TCP方式,以及基于RTP发送方式来实现。

2. 实时传输协议

RTP协议是互联网上进行媒体数据的一种传输协议,为了实现一对一或者一对多的同步传输和提供时间信息,我们就会采用RTP协议。由于其典型应用建立在UDP传输之上,但也能在TCP或者ATM等其他协议上使用这个协议。实时传输协议本身只能对确保数据的实时性以及完整性,但并不对传输的顺序以及传输可靠性提供保障。由于是建立在UDP协议之上,所以RTP协议本身并没有提供流量控制或者阻塞控制,所以在一般情况下我们需要使用RTCP来进行这些帮助。由于DSS本身默认的传输协议就是RTP协议,而RTP协议需要通过RTCP协议进行流量控制,这样很大程度上增加了机顶盒也就是解码端的CPU处理压力,因此本设计采用UDP协议直接对TS包进行发送,不使用RTP协议进行数据封装,由于UDP协议也缺少流量控制机制,我们使用PCR值来对发送流量进行控制以防止接收端出现缓存溢出影响播放质量。

3. 实时传输控制协议

实时传输控制协议的作用是管理传输的质量,也就是在进程间传输的同时相互交换信息。在建立RTP会话的时候,参与传输的双方周期性的传输RTCP包,这个数据包中包含了所有相关传输的信息,比如数据包大小,丢失的数据包数量等等。因此通常我们利用RTCP来对传输流量或有效载荷进行动态调整,同时与RTP配合有效的控制传输速率,所以特别适合传送实时数据。

4. 对话描述协议

对话描述协议(SDP)就是用来描述多媒体会话通告,多媒体会话邀请和其他形式的多媒体会话初始化的协议。SDP协议对流媒体描述的具体信息如下:会话名和会话目的,会话发起时间,会话中相关的网络信息,会话发起者的相关信息,媒体类型,传输所使用的协议,流媒体编码格式,传输时所使用的端口号,IP网络地址。因此我们可以通过解析SDP协议来获取我们所需要的一些必要的相关信息。

其中RTSP是非常重要的协议,因此后面会结合原代码做一个详细的分析,这个结果对设计模块有着非常重要的影响,也可以说是本设计的关键。

1.2.3 模块

流媒体服务器使用模块来响应各种请求及完成任务。有三种类型的模块:

1. 内容管理模块

媒体源相关的RTSP请求与响应,我们通过内容管理模块来管理,每个模块都用来对客户的需求进行解释并做相应处理,例如读取和解析模块支持的文件,或者请求的网络源信息,并通过RTP等方式响应。

内容管理模块有以下几个:

QTSSFileModule,

QTSSReflectorModule,

QTSSRelayModule,

QTSSMP3StreamingModule。

2. 服务器支持模块

服务器支持模块执行服务器数据的收集和记录功能。

服务器模块包括:

QTSSErrorLogModule,

QTSSAccessLogModule,

QTSSWebStatsModule,

QTSSWebDebugModule,

QTSSAdminModule,

QTSSPOSIXFileSystemModule。

3. 访问控制模块

访问控制模块提供鉴权和授权功能,以及操作URL路径提供支持。

访问控制模块包括:

QTSSAccessModule,

QTSSHomeDirectoryModule,

QTSSHttpFileModule,

QTSSSpamDefenseModule。

1.2.4 工作流程

在DSS中的模块分为动态模块和静态模块,动态模块在服务器启动时会首先装载动态模块,之后才会装载一部分静态模块。我们一般建议将我们自己书写的功能模块编译为动态模块来替换或扩展现有的服务器模块,因为它会被优先装载。在QTSS的模块中必须包含Register这个角色,这也是每个模块所必须支持的角色。在模块被装载之后服务器会调用每个模块的Register角色。在这个角色当中,模块会调用QTSS_AddRole函数来记录这个模块所支持的其他角色。然后服务器就将初始化角色来调用每一个拥有这个角色的模块。这个角色主要是做一些初始化的任务,比如说内存的分配或者对数据结构的初始化等等。在关闭服务器的时候,所有模块的Shutdown角色将被调用,这个角色主要是为了结束工作后处理现场,比如释放内存等等。流媒体服务器主要就是通过这种角色来完成相应任务的。

1.3 视频播放器(VLC)

VLC多媒体播放器(最初命名为VideoLAN客户端)是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影音光盘及各类流式协议。它也能作为unicast或 multicast的流式服务器在IPv4或 IPv6的高速网络连接下使用。它融合了FFmpeg计划的解码器与libdvdcss程序库使其有播放多媒体文件及加密DVD影碟的功能。

优秀的开源播放器可以播放MPEG-1、MPEG-2、MPEG-4、DivX、DVD/VCD、数字卫星频道、数字地球电视频道(digital terrestial television channels)、在许多作业平台底下透过宽频 IPv4、IPv6网络播放线上影片;此软件开发项目是由法国学生所发起的,参与者来自于世界各地,设计了多平台的支持,可以用于播放网络串流及本机多媒体档案之播放。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Android平台上,实现远程视频监控可以通过以下步骤和代码来进行: 1. 首先,需要在项目的AndroidManifest.xml文件中添加网络权限,以便连接服务器进行视频流传输。 2. 创建一个布局文件,用于展示视频流。可以使用SurfaceView或者TextureView控件,在xml文件中将其声明为可见。 3. 创建一个服务类,用于处理与服务器的连接、视频流传输等相关操作,可以继承自Service类。在服务类中,需要创建一个新的线程用于接收并处理视频流。 4. 在服务类中,需要使用Socket连接到服务器,并发送请求以获取视频流。 5. 接收视频流的线程中,使用MediaPlayer或者VideoView控件来实时播放视频流。可以使用VideoView的setVideoURI方法将视频流的地址传递给它。 6. 在Activity中,启动上述服务类并绑定到Activity。可以通过调用startService和bindService方法来实现。 7. 在Activity中,根据需要,可以添加一些用户操作的按钮,例如开始监控、停止监控等。通过按钮点击事件调用服务类中的相应方法。 下面是一个简化的示例代码: 在AndroidManifest.xml中添加网络权限: <uses-permission android:name="android.permission.INTERNET" /> 在布局文件中添加用于展示视频流的控件: <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> 创建一个服务类,用于与服务器连接和处理视频流: ```java public class VideoService extends Service { private Socket socket; private SurfaceView surfaceView; private MediaPlayer mediaPlayer; @Override public int onStartCommand(Intent intent, int flags, int startId) { // 连接到服务器 // 发送请求获取视频流 // 创建MediaPlayer实例,并设置其显示的SurfaceView return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); // 释放资源,关闭连接等操作 } } ``` 在Activity中启动服务并绑定到Activity: ```java public class MainActivity extends AppCompatActivity { private VideoService videoService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, VideoService.class); startService(intent); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { VideoService.LocalBinder binder = (VideoService.LocalBinder) service; videoService = binder.getService(); } @Override public void onServiceDisconnected(ComponentName className) { videoService = null; } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } } ``` 这是一个简单的示例代码,具体实现要根据实际需求进行调整和完善。 ### 回答2: Android远程视频监控涉及到以下几个方面的代码实现: 1. 设备之间的网络通信:首先,需要确保被监控设备(例如摄像头)与监控设备(即Android设备)在同一局域网内,并且能够相互通信。可以使用Socket、HTTP、WebSocket等网络通信协议来实现设备之间的通信。例如,可以在被监控设备上实现一个服务器并监听特定端口,Android设备通过Socket连接到该服务器来获取视频流。 2. 视频流的获取:在Android设备上,可以使用Android的多媒体框架(如Camera2 API)来获取实时视频流。可以通过调用相应的方法来打开摄像头、设置预览回调,并将获取到的视频帧进行编码压缩,然后发送给被监控设备。 3. 视频流的传输与接收:在被监控设备上,可以通过接收到的视频流进行解码和解压缩,以实现实时的视频播放。可以使用FFmpeg等开源库来实现视频的解码和解压缩。在Android设备上,可以使用VideoView或SurfaceView等视图控件来显示被监控设备传输的视频流。 4. 用户界面的设计:在Android应用中,需要提供用户界面来控制远程监控功能,例如实时视频的开始、暂停、停止、录制等操作。可以使用布局文件来设计界面,通过编写相应的事件处理代码来实现功能的调用和控制。 需要注意的是,Android远程视频监控涉及到网络传输和实时视频处理,对设备的性能和网络带宽要求较高,需要进行适当的优化和测试。此外,还需要考虑到安全性和稳定性等方面,例如使用加密算法保证通信的安全性,处理网络中断和异常情况等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值