文档章节

C#调用libEasyPlayer动态库,实现RTSP流播放

janl
 janl
发布于 2016/01/08 18:08
字数 1363
阅读 6140
收藏 13

一、项目背景:

        由于一个项目的附加部分,客户要求实现一个关于视频流媒体的方面内容,而且没有经费,且做为项目的附加条款,采购现成的系统,由于经费的问题,不太现实,所以上到开源社区寻找视频流媒体方面的开源项目,经过一番比较,选中了EasyDarwin。

二、布署服务器端

       下载了服务器端的编译版本直截在本地的Linux服务器上进行了布署。为了方便启动服务器,写了一个脚本。

#!/bin/bash
#file name start_easydarwin_server.sh
sudo ~/EasyDarwin-CentOS-x64-7.0.3-Build15.1130/easydarwin -c ~/EasyDarwin-CentOS-x64-7.0.3-Build15.1130/easydarwin.xml -d

       运行后,结果如下:

[janl@svr1 sh]$ ./start_easydarwin_server.sh
[sudo] password for janl:
WARNING: No module folder exists.
INFO: Module Loaded...QTSSFileModule [static]
INFO: Module Loaded...QTSSReflectorModule [static]
INFO: Module Loaded...EasyRelayModule [static]
INFO: Module Loaded...EasyHLSModule [static]
INFO: Module Loaded...QTSSAccessLogModule [static]
INFO: Module Loaded...QTSSFlowControlModule [static]
INFO: Module Loaded...QTSSPosixFileSysModule [static]
INFO: Module Loaded...QTSSAdminModule [static]
INFO: Module Loaded...QTSSMP3StreamingModule [static]
INFO: Module Loaded...QTSSAccessModule [static]
WARNING: No users file found at ./qtusers.
WARNING: No groups file found at ./qtgroups.
Streaming Server done starting up

    到这服务器端就能运行了。

三、实现我需要的客户端:

    先看一下最后的运行结果:

     从官方下载了EasyClient,这个没有编译好的版本,直截下载了源码,在Win7 x64下用VS2013编译。

     值得注意的一点是,源生下截的代码EasyClient在编译时会报错,提示找不libmp4creator,经过群主帮忙指点,其实

libmp4creator在下边的EasyPlayer项目中就有,直截Copy到EasyClient项目中就可以了。

    后面一切顺利,编译成功,后运行EasyClient可以用了。

四、实现自已想要的客户端:

      EasyClient客户端虽然不错,但是并不是我可以交付给客户的东西,所以实现自已的客户端就成为主要难点。

      EasyClient是用C++编写的,而我对C++并不熟,凭着多年工作经验,只能看懂个大概,最优的方案就是调用EasyClient类库,前端界面用C#重新实现。

     废话不多说了,本着从最容易的着手,就从EasyPlayer着手,从EasyClient目录,Copy了libEasyPlayer.dll及其它动态库,新建了c#项目,解决方案。

     第一个要解决的是,导出函数的定义,在c#中导入libEasyPlayer.dll的API导出函数,这里不得不说,EasyPlayer的作者把EasyPlayer的导出函,封装的很清晰:

    

typedef int (CALLBACK *MediaSourceCallBack)( int _channelId, int *_channelPtr, int _frameType, char *pBuf, RTSP_FRAME_INFO* _frameInfo);
LIB_EASYPLAYER_API int EasyPlayer_Init();
LIB_EASYPLAYER_API void EasyPlayer_Release();
LIB_EASYPLAYER_API int EasyPlayer_OpenStream(const char *url, HWND hWnd, RENDER_FORMAT renderFormat, int rtpovertcp, const char *username, const char *password, MediaSourceCallBack callback=NULL, void *userPtr=NULL);
LIB_EASYPLAYER_API void EasyPlayer_CloseStream(int channelId);
LIB_EASYPLAYER_API int EasyPlayer_SetFrameCache(int channelId, int cache);
LIB_EASYPLAYER_API int EasyPlayer_SetShownToScale(int channelId, int shownToScale);
LIB_EASYPLAYER_API int EasyPlayer_SetDecodeType(int channelId, int decodeKeyframeOnly);
LIB_EASYPLAYER_API int EasyPlayer_SetRenderRect(int channelId, LPRECT lpSrcRect);
LIB_EASYPLAYER_API int EasyPlayer_ShowStatisticalInfo(int channelId, int show);
LIB_EASYPLAYER_API int EasyPlayer_SetDragStartPoint(int channelId, POINT pt);
LIB_EASYPLAYER_API int EasyPlayer_SetDragEndPoint(int channelId, POINT pt);
LIB_EASYPLAYER_API int EasyPlayer_ResetDragPoint(int channelId);
LIB_EASYPLAYER_API int EasyPlayer_StartManuRecording(int channelId);
LIB_EASYPLAYER_API int EasyPlayer_StopManuRecording(int channelId);
LIB_EASYPLAYER_API int EasyPlayer_PlaySound(int channelId);
LIB_EASYPLAYER_API int EasyPlayer_StopSound();

   导入到c#的代码中,具体就是如这个样子。 

/// Return Type: int
        [System.Runtime.InteropServices.DllImportAttribute("libEasyPlayer.dll", EntryPoint = "?EasyPlayer_Init@@YAHXZ")]
        //[DllImport("libEasyPlayer.dll", EntryPoint = "EasyPlayer_Init", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int EasyPlayer_Init();
        /// Return Type: void
        [System.Runtime.InteropServices.DllImportAttribute("libEasyPlayer.dll", EntryPoint = "?EasyPlayer_Release@@YAXXZ")]
        public static extern void EasyPlayer_Release();

   这里我要提到一个工具,叫Invoke Interop Assistant 这个工具可以帮我将C++的头件,转换为c#的导入代码就是上边的代码,这个工具我是在CSDN上下载的,不过有点遗憾的是,最复杂并且带回调函数的EasyPlayer_OpenStream,无法自动生成,工具报了一个错误,具体错误信息是:

Error: Error processing procedure EasyPlayer_OpenStream: Expected token of type ParenClose but found ParenOpen instead.

我在Baidu上查了一下,没有什么有效的解决办法,而且我也没有弄清 ParenClose 与ParenOpen是否c++的专用术语或是什么,导出函出的定义方式,总之问题没有解决。EasyPlayer_OpenStream 和 回调函数 只好手动来码。

如果谁知道是怎么回事,一定要告诉我一下。

完成的导入函数如下,超长了,贴不上来,我一会传到群空吧。

程序的调试过程遇到两个问题要提醒注意一下:

 1. 找不到动态库,明明libEasyPlayer.dll就在可执行目录,系统提示找不到。经过尝试后我把项目编译配置由AnyCPU改为X86后终于不再报找不到动态库了。

 2. 提示找不动态库的入口点,这个把我郁闷坏了,明明比较和定义一样,就是提示找不到入口点,后来实在没办法了,只好上看雪下了一个Dll导出表查看器,具体的名字叫ExportList,有图有真相啊!

 看到第一行那个函数符号了吗? 我想可能是因为编译字符集或者是什么原因引起的吧,照这个定义就能找到入口点了。

如果你有更好的办法,请不要忘记告诉我一声。

看到大家找不到这个源码给我的留言,我首先感谢大家,让我知道这个东西还是有一点点用。

为了方便大家,我把源码整理了一下,放到了github上,以方便大家下载。

对于给我留言,需要发源码的朋友,我因为时间有限就不给大家一一回邮件了,请大家到github上去下载吧,在此报歉了。下载地址:

https://github.com/janl99/EasyClient.Net.git

© 著作权归作者所有

共有 人打赏支持
janl
粉丝 4
博文 55
码字总数 27349
作品 0
石家庄
程序员
私信 提问
加载中

评论(18)

janl
janl

引用来自“codinglove”的评论

各位大佬!为什么源码说找不到EasyClient.Net.dll,我找了确实每个文件夹里也没有
EasyClient.Net.dll是项目EasyClient.Net 项目编译后生成的程序,我现在手上没有那个项目的代码了,你重新生成一下那个项目,应该就会生成那个dll文件了。
codinglove
codinglove
各位大佬!为什么源码说找不到EasyClient.Net.dll,我找了确实每个文件夹里也没有
KelvinQ
KelvinQ

引用来自“KelvinQ”的评论

入口点乱码应该和程序编码有关吧,是不是你本地的程序编码和dll的不一致?

引用来自“俺叫胖子”的评论

大神您好,请问您运行成功了吗?
你的问题应该是没有安装ffmpeg吧,网上下个包安装一下就有这个dll了
俺叫胖子
俺叫胖子

引用来自“KelvinQ”的评论

入口点乱码应该和程序编码有关吧,是不是你本地的程序编码和dll的不一致?
大神您好,请问您运行成功了吗?
俺叫胖子
俺叫胖子

引用来自“KelvinQ”的评论

入口点乱码应该和程序编码有关吧,是不是你本地的程序编码和dll的不一致?

引用来自“janl”的评论

可能是,后来这一块项目的需求被砍了,我也没有再看它。本地win7的环境下默认的字符集编码应该是GB2132吧,致于dll的具本是什么编码就不知道了。
大神您好,您的代码我下载了.编译成功了.运行程序,播放推送资源的时候报错了,提示FFDecoder.dll 出错...我好迷茫,不知道怎么解决,请给我一个思路.谢谢您
janl
janl

引用来自“KelvinQ”的评论

入口点乱码应该和程序编码有关吧,是不是你本地的程序编码和dll的不一致?
可能是,后来这一块项目的需求被砍了,我也没有再看它。本地win7的环境下默认的字符集编码应该是GB2132吧,致于dll的具本是什么编码就不知道了。
KelvinQ
KelvinQ
入口点乱码应该和程序编码有关吧,是不是你本地的程序编码和dll的不一致?
janl
janl

引用来自“pedoc”的评论

你好@janl ,libEasyPlayer这个库只支持rtsp吗?官网的文档太少了
最早因为项目需要, 写了这个代码,对于内部协议没有深入研究过,而且过去这么久,我确实已经记不太情楚了,https://github.com/janl99/EasyClient.Net.git,这是源码的址,应该是可以用的,你需要什么协议?说实话我对视频这一块也没有深入涉足过,不好意思,帮不了你太多。
pedoc
pedoc
你好@janl ,libEasyPlayer这个库只支持rtsp吗?官网的文档太少了
janl
janl
还是看到有人找不到源码,我特地把源码整理了一下,放到了github上,如果大家需要需源码可以到https://github.com/janl99/EasyClient.Net.git去下载。我就到一一发送了。
libEasyPlayer获得视频图像

@janl 你好,想跟你请教个问题: 我看了你的帖子,C#调用libEasyPlayer动态库,实现RTSP流播放,以下回调函数如何获取到视频每一帧图像呢? 回调函数中只看到_frameInfo有数据。 typedef in...

蘑菇喵
2016/12/01
70
0
libEasyPlayer RTSP windows播放器SDK API接口设计说明

概述 libEasyPlayer实现对RTSP直播流进行实时采集和解码显示,稳定,高效,低延时;解码可采用intel硬件解码和软件解码两种方式,能实时进行录像和快照抓图,OSD叠加等功能。 API接口函数定义...

xiejiashu
2017/12/11
0
0
如何实现RTSP/RTMP流接入到RTSP网关

好多企业或开发者给我们反映,他们期望能把外网的rtsp或rtmp流,直接拉取注入到内网流媒体服务器,保证内网用户,无需访问,直接链接到内网服务器就可以观看到公网rtmp/rtsp流。 优势如下: ...

daniulivesdk
2018/12/29
0
0
EasyPlayer RTSP播放器运行出现: Unable to load DLL 找不到指定的模块。exception from HRESULT 0x8007007E 解决方案

版权声明:本文为EasyDarwin开源社区原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiejiashu/article/details/82531715 最近有EasyPlayer RTSP播放器的开发者反馈,在一台新装的...

xiejiashu
2018/09/08
0
0
关于EasyRTSPClient、EasyPlayer RTSP流重连问题的解释

EasyPlayer、EasyRTSPClient是如何设计重连的 首先大概解释一下EasyRTSPClient与EasyPlayer间的关系:EasyRTSPClient是一个专门用于与RTSP流媒体服务器交互的RTSPClient框架,类似于live555...

xiejiashu
2017/12/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Redis之父表示ARM服务器没戏!

ARM表示Neoverse N1平台和E1 CPU即将发布,Neoverse N1和E1采用7nm制程,并且为服务器和通信设备增加重要提升,拥有高可扩展性、高处理量以及高性能,将分别在2020年和2021年投入使用。 与C...

linuxCool
16分钟前
2
0
YARN 内存参数终极详解

YARN环境中应用程序JAR包冲突问题的分析及解决 Hadoop框架自身集成了很多第三方的JAR包库。Hadoop框架自身启动或者在运行用户的MapReduce等应用程序时,会优先查找Hadoop预置的JAR包。这样的...

stys35
22分钟前
0
0
Mybatis常用总结一

这一节的学习强烈建议实际操作 主键自增和自定义主键 实现描述:我们在写程序时,时常会遇到这样的问题:插入一条数据,但因有主键的存在,而有时候会报“违反唯一性约束”的错误,我们可以使...

大笨象会跳舞吧
22分钟前
0
0
计数二进制子串

leetcode:https://leetcode.com/problems/count-binary-substrings/ 给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起...

woshixin
25分钟前
0
0
mysql utf8mb4字符集,存储emoji表情

字符集utf8mb4 utf8mb4兼容utf8,且比utf8能表示更多的字符。 看unicode编码区 从1 ~ 126就属于传统utf8区,当然utf8mb4也兼容这个区,126行以下就是utf8mb4扩充区,什么时候你需要存储那些...

我心中有猛狗
28分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部