基于安卓平台,客户端视频监控的实现(二)
关于如何编译在官方有介绍,网上也有很多教程,不做赘述。
目前博主水平有限,目前主要是分析java部分代码和如何使用解码库。
先看下目录结构:
LibVLC是load解码库和so库的,提供调用的方法。
/* Load library before object instantiation */static {try {if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1)System.loadLibrary("iomx-gingerbread");else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2)System.loadLibrary("iomx-hc");else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2)System.loadLibrary("iomx-ics");} catch (Throwable t) {Log.w(TAG, "Unable to load the iomx library: " + t);}try {System.loadLibrary("vlcjni");} catch (UnsatisfiedLinkError ule) {Log.e(TAG, "Can't load vlcjni library: " + ule);/// FIXME Alert userSystem.exit(1);} catch (SecurityException se) {Log.e(TAG, "Encountered a security issue when loading vlcjni library: " + se);/// FIXME Alert userSystem.exit(1);}}//调用所有libvlc的方法之前必须进行init操作/*** Initialize the libVLC class.** This function must be called before using any libVLC functions.** @throws LibVlcException*/public void init(Context context) throws LibVlcException {Log.v(TAG, "Initializing LibVLC");mDebugLogBuffer = new StringBuffer();if (!mIsInitialized) {if(!LibVlcUtil.hasCompatibleCPU(context)) {Log.e(TAG, LibVlcUtil.getErrorMsg());throw new LibVlcException();}nativeInit();mMediaList = mPrimaryList = new MediaList(this);setEventHandler(EventHandler.getInstance());mIsInitialized = true;}}
播放实时视频,只需调用如下方法,传入一个rtps的url
/*** Play an MRL directly.** @param mrl MRL of the media to play.*/public void playMyMRL(String mrl) {// index=-1 will return options from libvlc instance without relying on MediaListString[] options = new String[0]; mInternalMediaPlayerIndex = 0;playMRL(mLibVlcInstance, mrl, options);}
LibVlcUtil 主要是对设备CPU的检查。ABI,CPU_ABI是我们经常都会碰见的,例如我们在Android工程里面的libs库下面就有armeabi-v7a类型的库。这里的ABI是指Application Binary Interface。
ABI描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低层接口。ABI不同于应用程序接口(API),API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。
ABI掩盖了各种细节,例如:调用约定(控制着函数的参数如何传送以及如何接受返回值);系统调用的编码和一个应用如何向操作系统进行系统调用;以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库等等。一个完整的ABI,像Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。其他的 ABI 标准化细节包括 C++ name decoration 和同一个平台上的编译器之间的调用约定,但是不包括跨平台的兼容性。
简单的说,ABI规范了应用程序对寄存器的使用方法,Call procedure,以及如何进入trap。符合某一平台ABI规范的应用程序就可以在这一平台上运行。这一规范是针对binary,而不是source的。所以同样的高级语言代码,使用不同的toolchain,可以得到符合不同ABI规范的binary。关于这部分,还不明白的,自行Google(我也不是很清楚,免得误人子弟)。
VLCApplication做的事情不多,简单来说,做了两件事。第一个是一个本地配置的初始化,主要是Locale的配置,而且都是针对中文做特别处理,另外就是当系统内存不多的时候,回收一些bitmap的内存。剩下的就是保存一个全局的静态对象供其他类使用。下面给出系统内存低的时候,回收bitmap缓存。代码如下:
// Are we using advanced debugging - locale?SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);String p = pref.getString("set_locale", "");if (p != null && !p.equals("")) {Locale locale;// workaround due to region codeif(p.equals("zh-TW")) {locale = Locale.TRADITIONAL_CHINESE;} else if(p.startsWith("zh")) {locale = Locale.CHINA;} else if(p.equals("pt-BR")) {locale = new Locale("pt", "BR");} else if(p.equals("bn-IN") || p.startsWith("bn")) {locale = new Locale("bn", "IN");} else {/*** Avoid a crash of* java.lang.AssertionError: couldn't initialize LocaleData for locale* if the user enters nonsensical region codes.*/if(p.contains("-"))p = p.substring(0, p.indexOf('-'));locale = new Locale(p);}Locale.setDefault(locale);Configuration config = new Configuration();config.locale = locale;getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());}低内存的时候/*** Called when the overall system is running low on memory*/@Overridepublic void onLowMemory() {super.onLowMemory();Log.w(TAG, "System is running low on memory");BitmapCache.getInstance().clear();}
具体的调用:
try {EventHandler em = EventHandler.getInstance();em.addHandler(handler);mLoadingDialog = DialogUtil.createLoadingDialog(MainActivity.this,"正在获取信息,请稍后...");mLoadingDialog.show();mLibVLC = Util.getLibVlcInstance();mLibVLC.init(getApplicationContext());if (mLibVLC != null) {String pathUri = "rtsp://192.168.103.39:10554/654321.sdp";
// String pathUri = "http://vod.cntv.lxdns.com/flash/mp4video50/TMS/2016/04/19/f1db9354900946a19a7fefc3bf040593_h264200000nero_aac16.mp4";
// String pathUri = "/storage/emulated/0/DCIM/Camera/VID_20170511_103045.mp4"; mLibVLC.playMyMRL(pathUri);}} catch (LibVlcException e) {e.printStackTrace();}
初始化handler,libvlc初始化的时候,往下一层层调用,最后handler将信息返回,调用play播放方法的时候,我也没有搞清楚为什么那么慢,可能和网络有关,还是和服务器那边推流的速度,关于这一点仍然在研究,目前给的措施就是loading加载。
当接收到handler传来的信息,对此进行相应的操作:
Handler handler = new Handler() {public void handleMessage(Message msg) {Log.d(TAG, "Event = " + msg.getData().getInt("event"));switch (msg.getData().getInt("event")) {case EventHandler.MediaPlayerPlaying:break;case EventHandler.MediaPlayerPaused:break;case EventHandler.MediaPlayerStopped:break;case EventHandler.MediaPlayerEndReached:break;case EventHandler.MediaPlayerVout:if (mLoadingDialog != null) {mLoadingDialog.dismiss();mLoadingDialog = null;}if (msg.getData().getInt("data") > 0) {Intent intent = new Intent();intent.setClass(getApplicationContext(),VideoPlayerActivity.class);startActivity(intent);MainActivity.this.finish();}break;case EventHandler.MediaPlayerPositionChanged:break;case EventHandler.MediaPlayerEncounteredError:AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setTitle("提示信息").setMessage("无法连接到摄像头,请检查设备是否已经连接到摄像头所在的wifi热点").setNegativeButton("知道了",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {MainActivity.this.finish();}}).create();dialog.setCanceledOnTouchOutside(false);dialog.show();break;default:Log.d(TAG, "Event not handled ");break;}}};
EventHandler类里面定义很多常量,根据项目的需求选择:
/** Be sure to subscribe to events you need in the JNI too.*///public static final int MediaMetaChanged = 0;//public static final int MediaSubItemAdded = 1;//public static final int MediaDurationChanged = 2;//public static final int MediaParsedChanged = 3;//public static final int MediaFreed = 4;//public static final int MediaStateChanged = 5;//public static final int MediaPlayerMediaChanged = 0x100;//public static final int MediaPlayerNothingSpecial = 0x101;//public static final int MediaPlayerOpening = 0x102;//public static final int MediaPlayerBuffering = 0x103;public static final int MediaPlayerPlaying = 0x104;public static final int MediaPlayerPaused = 0x105;public static final int MediaPlayerStopped = 0x106;//public static final int MediaPlayerForward = 0x107;//public static final int MediaPlayerBackward = 0x108;public static final int MediaPlayerEndReached = 0x109;public static final int MediaPlayerEncounteredError = 0x10a;//public static final int MediaPlayerTimeChanged = 0x10b;public static final int MediaPlayerPositionChanged = 0x10c;//public static final int MediaPlayerSeekableChanged = 0x10d;//public static final int MediaPlayerPausableChanged = 0x10e;//public static final int MediaPlayerTitleChanged = 0x10f;//public static final int MediaPlayerSnapshotTaken = 0x110;//public static final int MediaPlayerLengthChanged = 0x111;public static final int MediaPlayerVout = 0x112;//public static final int MediaListItemAdded = 0x200;//public static final int MediaListWillAddItem = 0x201;//public static final int MediaListItemDeleted = 0x202;//public static final int MediaListWillDeleteItem = 0x203;//public static final int MediaListViewItemAdded = 0x300;//public static final int MediaListViewWillAddItem = 0x301;//public static final int MediaListViewItemDeleted = 0x302;//public static final int MediaListViewWillDeleteItem = 0x303;//public static final int MediaListPlayerPlayed = 0x400;//public static final int MediaListPlayerNextItemSet = 0x401;//public static final int MediaListPlayerStopped = 0x402;//public static final int MediaDiscovererStarted = 0x500;//public static final int MediaDiscovererEnded = 0x501;//public static final int VlmMediaAdded = 0x600;//public static final int VlmMediaRemoved = 0x601;//public static final int VlmMediaChanged = 0x602;//public static final int VlmMediaInstanceStarted = 0x603;//public static final int VlmMediaInstanceStopped = 0x604;//public static final int VlmMediaInstanceStatusInit = 0x605;//public static final int VlmMediaInstanceStatusOpening = 0x606;//public static final int VlmMediaInstanceStatusPlaying = 0x607;//public static final int VlmMediaInstanceStatusPause = 0x608;//public static final int VlmMediaInstanceStatusEnd = 0x609;//public static final int VlmMediaInstanceStatusError = 0x60a;public static final int CustomMediaListExpanding = 0x2000;public static final int CustomMediaListExpandingEnd = 0x2001;public static final int CustomMediaListItemAdded = 0x2002;public static final int CustomMediaListItemDeleted = 0x2003;
但是必须确保jni中存在。其余就是添加移除handler的方法:
public void addHandler(Handler handler) {if (!mEventHandler.contains(handler))mEventHandler.add(handler);}public void removeHandler(Handler handler) {mEventHandler.remove(handler);}/** This method is called by a native thread **/public void callback(int event, Bundle b) {b.putInt("event", event);for (int i = 0; i < mEventHandler.size(); i++) {Message msg = Message.obtain();msg.setData(b);mEventHandler.get(i).sendMessage(msg);}}
最后就是VideoPlayerActivity,视频播放的页面。其实我也不太会写博客,总想记录一些,学习一些,也知道自己写的不好,基本都是复制粘贴,只是遇到的一些坑能够写出来,让大家少走弯路,还是希望大神可以指点指点。不喜勿喷。
基于安卓平台,客户端视频监控的实现(二)相关推荐
- linux 车载视频监控,基于Linux平台车载视频监控系统研发-计算机科学与技术专业论文.docx...
基于Linux平台车载视频监控系统研发-计算机科学与技术专业论文 目录 HYPERLINK \l "_bookmark0" 第一章 绪论1 HYPERLINK \l "_ ...
- 基于ARM的移动视频监控系统
http://www.eeworld.com.cn/qrs/2010/0409/article_2439_1.html 0 引 言 传统的视频监控系统一般采用PC服务器的C/S(Client/Serv ...
- 介绍基于ARM的移动视频监控系统
摘要:将嵌入式Linux和无线网络引入到视频监控系统,阐述了系统的硬件组成:介绍了USB无线网卡驱动实现的过程:从嵌入式Linux开发环境的搭建.嵌入式流媒体服务器的设计和动态网页的设计等方面介绍了软 ...
- 智慧建造管理平台施工现场视频监控系统
建筑施工现场环境复杂.安全事故频发.建筑质量问题频出,建筑工地扬尘.人员复杂的区域,存在施工地点分散.施工安全管理难.文明施工监管难.人员管理难.调查取证难等特点.如何对建筑工地施工现场全方位.全过程 ...
- 基于安卓平台的校园社交app设计
目 录 1 绪论 3 1.1 研究背景和意义 3 1.2 研究现状 3 1.3 研究内容 4 1.4 论文结构 4 2 系统设计 5 2.1 总体功能模块设计 5 2.2 服务端模块 5 2.3 安卓 ...
- 基于云平台的光伏监控系统是怎样的?
摘要:针对国内光伏发电监控系统的研究现状,文中提出了基于云平台的光伏发电监控体系.构建基于B/S架构的数据实时采集与推送,以SSH(struts+spring+hibernate)作为Web开发框架, ...
- 嵌入式项目实战——基于QT的视频监控系统设计(二)
嵌入式项目实战--基于QT的视频监控系统设计(二) 昨天我分享了关于QT的基本使用方法,掌握了这些基本的方法就可以设计一个简单的视频监控界面.下面我们开始分享完成这个嵌入式项目同样重要的知识点--UD ...
- 基于QT的多线程视频监控的实现(一)
<基于QT的多线程视频监控的实现(一)> <基于QT的多线程视频监控的实现(二)> <基于QT的多线程视频监控的实现(三)> 本系统是采用的Windows的开发环境 ...
- 基于ARM的远程视频监控系统的设计
http://www.21ic.com/app/mcu/201208/135975.htm 摘要:在ARM 微处理器平台上移植嵌入式Linux 操作系统,完成视频采集任务,并以服务器方式将图像发送到网 ...
- b s架构监控java,基于B/S的视频监控系统的设计与实现
基于B/S的视频监控系统的设计与实现 本文分析了基于C/S架构的视频监控系统的缺点和B/S结构的诸多优点,通过需求分析,设计实现了一种以B/S为架构的视频监控系统,并针对现存视频监控系统在权限控制方面 ...
最新文章
- Redeclared ‘list_b‘ defined above without usage
- 【arduino】nodemcu(ESP8266)发送邮件库测试笔记,SMTP email
- StoreFront 登陆页面的话持续时间
- SAP 报表程序的一些标准功能码
- Python定义点击右上角关闭按钮事件
- jQuery页面顶部下拉广告
- 什么是交叉编译?个人对交叉编译的理解
- 斐波那契数列连续十项的和
- Vuex getters 基础使用
- Windows安装Linux, (WSL)Windows Subsystem for Linux
- 【Python】python网络协议
- java static final泛型类对象
- R2CNN 算法笔记
- Xsens MVN Analyze高精度惯性动作捕捉系统Link版
- 了解传销系列之三 : 开心门
- YDOOK:版权C符号:怎样在任何地方 任何位置快速输入版权符号 © 快捷键
- Excel的筛选功能应用教你在大数据中筛选出需要的数据
- 销售书籍推荐,这本书做销售的必看!
- 哈尔滨计算机毛校长国二,【实验视角】静待紫冰花开 知行合一 且行且知 ——记哈尔滨市实验学校校长王媛参加第二届中国阳明心学高峰论坛...
- 迄今为止见过最好的职业规划