关于如何编译在官方有介绍,网上也有很多教程,不做赘述。
目前博主水平有限,目前主要是分析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,视频播放的页面。其实我也不太会写博客,总想记录一些,学习一些,也知道自己写的不好,基本都是复制粘贴,只是遇到的一些坑能够写出来,让大家少走弯路,还是希望大神可以指点指点。不喜勿喷。

基于安卓平台,客户端视频监控的实现(二)相关推荐

  1. linux 车载视频监控,基于Linux平台车载视频监控系统研发-计算机科学与技术专业论文.docx...

    基于Linux平台车载视频监控系统研发-计算机科学与技术专业论文 目录 HYPERLINK \l "_bookmark0" 第一章 绪论1 HYPERLINK \l "_ ...

  2. 基于ARM的移动视频监控系统

    http://www.eeworld.com.cn/qrs/2010/0409/article_2439_1.html 0 引 言 传统的视频监控系统一般采用PC服务器的C/S(Client/Serv ...

  3. 介绍基于ARM的移动视频监控系统

    摘要:将嵌入式Linux和无线网络引入到视频监控系统,阐述了系统的硬件组成:介绍了USB无线网卡驱动实现的过程:从嵌入式Linux开发环境的搭建.嵌入式流媒体服务器的设计和动态网页的设计等方面介绍了软 ...

  4. 智慧建造管理平台施工现场视频监控系统

    建筑施工现场环境复杂.安全事故频发.建筑质量问题频出,建筑工地扬尘.人员复杂的区域,存在施工地点分散.施工安全管理难.文明施工监管难.人员管理难.调查取证难等特点.如何对建筑工地施工现场全方位.全过程 ...

  5. 基于安卓平台的校园社交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 安卓 ...

  6. 基于云平台的光伏监控系统是怎样的?

    摘要:针对国内光伏发电监控系统的研究现状,文中提出了基于云平台的光伏发电监控体系.构建基于B/S架构的数据实时采集与推送,以SSH(struts+spring+hibernate)作为Web开发框架, ...

  7. 嵌入式项目实战——基于QT的视频监控系统设计(二)

    嵌入式项目实战--基于QT的视频监控系统设计(二) 昨天我分享了关于QT的基本使用方法,掌握了这些基本的方法就可以设计一个简单的视频监控界面.下面我们开始分享完成这个嵌入式项目同样重要的知识点--UD ...

  8. 基于QT的多线程视频监控的实现(一)

    <基于QT的多线程视频监控的实现(一)> <基于QT的多线程视频监控的实现(二)> <基于QT的多线程视频监控的实现(三)> 本系统是采用的Windows的开发环境 ...

  9. 基于ARM的远程视频监控系统的设计

    http://www.21ic.com/app/mcu/201208/135975.htm 摘要:在ARM 微处理器平台上移植嵌入式Linux 操作系统,完成视频采集任务,并以服务器方式将图像发送到网 ...

  10. b s架构监控java,基于B/S的视频监控系统的设计与实现

    基于B/S的视频监控系统的设计与实现 本文分析了基于C/S架构的视频监控系统的缺点和B/S结构的诸多优点,通过需求分析,设计实现了一种以B/S为架构的视频监控系统,并针对现存视频监控系统在权限控制方面 ...

最新文章

  1. Redeclared ‘list_b‘ defined above without usage
  2. 【arduino】nodemcu(ESP8266)发送邮件库测试笔记,SMTP email
  3. StoreFront 登陆页面的话持续时间
  4. SAP 报表程序的一些标准功能码
  5. Python定义点击右上角关闭按钮事件
  6. jQuery页面顶部下拉广告
  7. 什么是交叉编译?个人对交叉编译的理解
  8. 斐波那契数列连续十项的和
  9. Vuex getters 基础使用
  10. Windows安装Linux, (WSL)Windows Subsystem for Linux
  11. 【Python】python网络协议
  12. java static final泛型类对象
  13. R2CNN 算法笔记
  14. Xsens MVN Analyze高精度惯性动作捕捉系统Link版
  15. 了解传销系列之三 : 开心门
  16. YDOOK:版权C符号:怎样在任何地方 任何位置快速输入版权符号 © 快捷键
  17. Excel的筛选功能应用教你在大数据中筛选出需要的数据
  18. 销售书籍推荐,这本书做销售的必看!
  19. 哈尔滨计算机毛校长国二,【实验视角】静待紫冰花开 知行合一 且行且知 ——记哈尔滨市实验学校校长王媛参加第二届中国阳明心学高峰论坛...
  20. 迄今为止见过最好的职业规划

热门文章

  1. app信息收集和waf识别
  2. 采用模块化建模方法,搭建空气悬架模型,UKF状态估计模型,可实现悬架动挠度等状态估计
  3. 隔离开关及接地开关GIM模型要求
  4. 双十一红包集结令二维码
  5. plt设置坐标轴标签倾斜
  6. N1小钢炮安装zerotier
  7. stream流操作,对List集合进行分组、求和去重
  8. Dw 2020最新版下载地址 一键安装Windows
  9. 大数据框架调研-流处理-Spark与Flink
  10. NewLink能链IPO,能源物联网的先行者?