`
tuojian.tj
  • 浏览: 19512 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

Android用MediaRecorder实现MPEG4视频监控

阅读更多
都是摸着石头过河,花了整整一个星期,终于把技术难点给突破了,貌似网上对这个讨论的较少。

主要需要实现的功能是在android手机上实时采集视频,并在远程比如PC机上实时显示出来,也就是以android手机作为监控摄像头。

一开始查到的是smartcam的一个开源项目,看了下源代码,发现其实现原理是利用android 的camera图像的预采集,通过实现PreviewCallback类的回调函数onPreviewFrame,获得camera采集的原始图像数据之后,压成jpeg格式传到pc端。pc端对接收到的jpeg图像序列进行实时解压和显示,就达到了预想的效果。

虽然这种方式稍微显得比较笨拙,这个方式还可以接受。但是不可接受的是jpeg只是帧内压缩,320x280的图片序列,FPS大概是10上下,网络流量就到达了100kb/s以上。这个几乎是无法实际应用的。

于是必须直接传视频流,MPEG4或者H.264格式。貌似我的开发机上(HTC G8)只支持到MPEG4,所以还是选取MPEG4。但是如何实时采集视频流是一个大问题,毕竟在video方面,android并没有提供一个类似于OnPreviewFrame的回调函数。

想到用opencore或者更为新一点的stagefright,大概看看了其sdk的框架后,马上泄气了,这个太庞大了。在http://blog.csdn.net/zblue78/archive/2010/12/18/6083374.aspx的帖子中提到一个很好的解决方案,就是利用MediaRecorder:MediaRecorder的输出路径(其实叫file descriptor)除了是本地文件路径之外,还可以绑定socket端口。也就是说,通过一个socket端口,就可以实时获得MediaRecorder的视频流数据。
(其实上面博客的内容可以在开源项目sipdroid 的 videocamera文件中找到,但是非常感谢博客主人zhangzhenj对网友提问的回答,赞一个。)

通过socket接收的视频流与直接写在本地文件的视频流数据有点不一样,因为是通过socket传输,就无法对视频文件的回写,通常MediaRecorder结束录像的时候都会对视频文件进行回写处理,这样才可以被播放器播放。所以通过socket接受到的数据,保存下来是无法播放的。16进制方式查看了一下其输出文件,发现其前32byte都是00,紧接着就是mdat。问题就出现在这了:缺少了一个ftyp box 的描述(28 bytes)以及mdat的长度描述(4 bytes).网上已经有人顺利解决这样的问题,在数据中查找moov的起始位置,发现前面会有ftyp的描述,长度刚刚好28bytes。你可以copy这28bytes到文件开始的28byte中。这ftyp的描述是从moov的起始位置 的前32byte开始一直到前4byte(后面4byte是moov的长度描述)。然后mdat的长度就是 moov的起始位置 减去 0x20,道理就不解释了。然后把这个值写到mdat的前面4byte。刚刚好填满32byte,之后就能顺利播放了。

保存好的文件能播放之后,最后一个问题,如何在实时显示这个视频流呢?查看一下mpeg4的文件格式,很快就会知道答案,答案就在mdat中。mdat之后紧跟的就是视频媒体数据,每一帧以 00 00 01 b6 为开始标志,貌似没有结束标志,分帧的话估计要用这个。开始标志后紧接着的两bit就是I、P、B帧的标志了,分别对应值为00,01,10,记住是两bit不是两byte

好了,把mdat的一帧数据取出来,可以用ffmpeg解码,然后显示,这样的路子是可行的,不过细节还是有点麻烦,关键是ffmpeg在解码mpeg4的时候一定要先指定width和height,否则解码失败。

大概思路就是这样了,完整的代码还没出来。以后再说。
分享到:
评论
16 楼 chao8828276 2013-10-15  
楼主,我用MOTO的手机录制后发到PC上,发现ffty的描述符都有,只是mdat前面的长度描述(四个字节的)全部为0,其它的地方完全正常感觉。

哎,没法上图片。。。。
15 楼 super_we 2012-12-24  
tapestry1122 写道
这个是属于硬件编码吧
说到这个来气啊
android分裂的不是一点点
不同的手机产生的码流不一样啊
你的g8产生的头32个byte都是00
在i9023和htc g10上产生的就是的正常视频文件头
但是在mdat这个box后
i9023紧跟着就是视频流了
g10上还会有8个byte的占位符

i9000貌似跟9023,g10又不太一样
蛋疼无比



就是啊,不同手机不同,晕死
14 楼 cruise 2012-06-01  
楼主,您好,我是通过socket传输,在服务器上保存为文件,可是播放不了。16进制方式查看了一下其输出文件,发现只有前27byte都是00,请教如何解决,谢谢!
13 楼 tapestry1122 2012-05-16  
yf543 写道
tapestry1122 写道
yf543 写道
tapestry1122 写道
yf543 写道
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q



需要服务端支持,转换成rtsp的视频流就行
sipdroid里有

如果要在手机端进行,需要ffmpeg来解码


**********************************************
一部手机的摄像头获取视频流之后,通过Socket发送到另外一部手机,然后用ffmpeg解码播放。一定要将其转换成rtsp的视频流吗?我对rtsp不懂啊。求解!


目前android的media framework没有提供读取buffer然后显示视频的接口。所以你能做的就是
1。利用mediaplayer可以直接播放rtsp视频流的功能,要么在android手机上创建一个rtsp server将接受到的数据转换成rtsp,要么就通过服务器转换
2。利用ffmpeg,根据参数将接收到的视频流还原成图片然后显示。

可以参考spydroid-ipcamera这个开源项目,能提供你一点思路。

___________________________________________________________
非常感谢您的解答,受益匪浅。

请问,您提供的两种方法相比之下哪个简单一些呢?对android的API版本有没有要求?

第一种简单的,就是在android手机上创建一个socket server,能返回rtsp数据流就行了
不过android对rtsp的视频编码支持有限
第二种通用些,不过入门麻烦点,需要熟悉ffmpeg,要分析rtp,然后返回视频帧,通过ffmpeg解码成图片然后显示。
12 楼 yf543 2012-05-13  
tapestry1122 写道
yf543 写道
tapestry1122 写道
yf543 写道
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q



需要服务端支持,转换成rtsp的视频流就行
sipdroid里有

如果要在手机端进行,需要ffmpeg来解码


**********************************************
一部手机的摄像头获取视频流之后,通过Socket发送到另外一部手机,然后用ffmpeg解码播放。一定要将其转换成rtsp的视频流吗?我对rtsp不懂啊。求解!


目前android的media framework没有提供读取buffer然后显示视频的接口。所以你能做的就是
1。利用mediaplayer可以直接播放rtsp视频流的功能,要么在android手机上创建一个rtsp server将接受到的数据转换成rtsp,要么就通过服务器转换
2。利用ffmpeg,根据参数将接收到的视频流还原成图片然后显示。

可以参考spydroid-ipcamera这个开源项目,能提供你一点思路。

___________________________________________________________
非常感谢您的解答,受益匪浅。

请问,您提供的两种方法相比之下哪个简单一些呢?对android的API版本有没有要求?
11 楼 tapestry1122 2012-05-08  
yf543 写道
tapestry1122 写道
yf543 写道
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q



需要服务端支持,转换成rtsp的视频流就行
sipdroid里有

如果要在手机端进行,需要ffmpeg来解码


**********************************************
一部手机的摄像头获取视频流之后,通过Socket发送到另外一部手机,然后用ffmpeg解码播放。一定要将其转换成rtsp的视频流吗?我对rtsp不懂啊。求解!


目前android的media framework没有提供读取buffer然后显示视频的接口。所以你能做的就是
1。利用mediaplayer可以直接播放rtsp视频流的功能,要么在android手机上创建一个rtsp server将接受到的数据转换成rtsp,要么就通过服务器转换
2。利用ffmpeg,根据参数将接收到的视频流还原成图片然后显示。

可以参考spydroid-ipcamera这个开源项目,能提供你一点思路。
10 楼 yf543 2012-05-07  
tapestry1122 写道
yf543 写道
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q



需要服务端支持,转换成rtsp的视频流就行
sipdroid里有

如果要在手机端进行,需要ffmpeg来解码


**********************************************
一部手机的摄像头获取视频流之后,通过Socket发送到另外一部手机,然后用ffmpeg解码播放。一定要将其转换成rtsp的视频流吗?我对rtsp不懂啊。求解!
9 楼 tapestry1122 2012-05-05  
yf543 写道
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q



需要服务端支持,转换成rtsp的视频流就行
sipdroid里有

如果要在手机端进行,需要ffmpeg来解码
8 楼 yf543 2012-05-03  
你好,博主,我现在在弄一个android的实时视频传输,想请教你一下:从一个手机的摄像头通过MediaRecorder取出的视频数据,通过socket发送到另外一个手机,使其能实时播放出来,但是不进行存储,能够实现吗?望博主指点一二。3Q

7 楼 tuojian.tj 2011-07-23  
xiyou_feng 写道
不知道楼主的想法实现了没有,我也在做这方面的,想了解下你这个方法中“直接传视频流,MPEG4或者H.264格式。”的实时数据量会有多大呢。

h.263是可以实现了,准备做h.264的rtp流化时,结果boss取消了项目
想法是将实时的h.264手机视频通过转发服务器做rtp live stream转发。没办法,死在摇篮了,希望又兴趣的朋友们接着上啊。
6 楼 tuojian.tj 2011-07-23  
tapestry1122 写道
这个是属于硬件编码吧
说到这个来气啊
android分裂的不是一点点
不同的手机产生的码流不一样啊
你的g8产生的头32个byte都是00
在i9023和htc g10上产生的就是的正常视频文件头
但是在mdat这个box后
i9023紧跟着就是视频流了
g10上还会有8个byte的占位符

i9000貌似跟9023,g10又不太一样
蛋疼无比


我用g8和i9000弄h.263还是还是一样的,其它的机器也就不晓得了。g8弄不了h264,也就算了。

android分裂的不是一点点
=====================
完全同意!相当讨厌
5 楼 tuojian.tj 2011-07-23  
xiyou_feng 写道
不知道楼主的想法实现了没有,我也在做这方面的,想了解下你这个方法中“直接传视频流,MPEG4或者H.264格式。”的实时数据量会有多大呢。

你可以自己用手机拍H.264的视频看一下,320x240,fps 10 的话,也差不多是10k/s以下。
4 楼 tapestry1122 2011-07-01  
这个是属于硬件编码吧
说到这个来气啊
android分裂的不是一点点
不同的手机产生的码流不一样啊
你的g8产生的头32个byte都是00
在i9023和htc g10上产生的就是的正常视频文件头
但是在mdat这个box后
i9023紧跟着就是视频流了
g10上还会有8个byte的占位符

i9000貌似跟9023,g10又不太一样
蛋疼无比
3 楼 xiyou_feng 2011-06-16  
不知道楼主的想法实现了没有,我也在做这方面的,想了解下你这个方法中“直接传视频流,MPEG4或者H.264格式。”的实时数据量会有多大呢。
2 楼 tuojian.tj 2011-03-25  
代码还很零散,用socket接收视频流数据的代码这里有
http://blog.csdn.net/zblue78/archive/2010/12/18/6083374.aspx
1 楼 kldwq2002 2011-03-25  
灰常好,正是俺现在在找的内容。我一开始也想从onPreviewFrame想办法来着。后来发现数据量真的很大。博主写出例子没呢,有的话可否共享。万分感谢。

相关推荐

    mediarecorder获取视频数据

    在Android开发中,`MediaRecorder` 是一个非常重要的类,用于录制音频、视频或同时录制。这个类使得开发者能够直接处理编码后的数据,而无需直接操作SD卡,从而简化了视频录制过程。在这个主题中,我们将深入探讨...

    Android视频监控源码

    在Android平台上实现视频监控功能,通常涉及到多个技术领域,包括网络通信、音视频编解码、设备控制以及用户界面设计等。以下是对"Android视频监控源码"的详细解析: 1. **网络通信**:在Android视频监控系统中,...

    Android 远程视频 监控程序 源码

    此外,MediaRecorder也可能被用于录制视频,实现双向的视频监控功能。 源码中可能包含以下几个关键组件: 1. `VideoStreamService`:这是一个后台服务,负责持续接收并处理视频流。它可能通过HTTP、RTSP或WebRTC等...

    Android 系统自带视频压缩录制

    本文将详细解析如何利用Android系统自带的功能实现视频的高效压缩录制。 一、Android视频录制基础 在Android中,视频录制主要通过MediaRecorder类来实现。MediaRecorder是一个用于音频、视频录制的API,它可以配置...

    android 录制视频代码 自动录制

    在Android平台上,录制视频是一项常见的功能,用于创建用户生成的内容或实现各种应用程序的功能。下面将详细介绍如何在Android中实现自动录制视频,以及相关的知识点。 **一、准备工作** 1. **权限声明**:在...

    android实时监控

    在Android平台上实现实时监控涉及到多个关键技术环节,包括视频采集、编码、传输、解码和播放。下面我们将逐一探讨这些步骤。 一、实时监控系统概述 Android实时监控系统主要是利用手机的摄像头进行视频采集,通过...

    Android rtsp camera

    在Android应用中,RTSP常用于实现远程视频监控、视频会议等场景,因为它能有效地处理网络延迟,确保视频流的稳定传输。 要实现Android RTSP相机,首先需要理解Android的Camera API。Android提供了两个版本的Camera ...

    Qt for Android 调用原生系统摄像头进行录像并保存输出

    本文将详细介绍如何使用Qt for Android调用原生系统的摄像头进行录像,并保存录制的视频输出。 首先,我们需要理解Qt中的多媒体模块,即`Q Multimedia`框架。这个模块提供了与多媒体内容交互的能力,包括音频、视频...

    基于Android4.2系统的H.264视频数据的获取.pdf

    摘要中提到的问题是,在Android系统中,通常使用MediaRecorder和LocalSocket类来从MPEG4文件中提取H.264原始数据。然而,这种方法存在两个主要缺陷:一是需要手动填充SPS(Sequence Parameter Set)和PPS(Picture ...

    RtspMediaRecorder:libstreaming 源码分析一之RTSP连接,]libstreaming源码分析二之MediaRecorder编码

    在Android平台上,实时流媒体传输协议(RTSP)被广泛用于视频直播和远程监控等应用场景。`libstreaming`是一个开源库,它允许开发者通过RTSP协议将Android设备的摄像头内容推送到网络服务器。本篇文章将对`...

Global site tag (gtag.js) - Google Analytics