EMIPLIB简介

sofia sip开发九 使用EMIPLIB库增加RTP流处理 sofia sip开发 阅读详情
 
EMIPLIB(http://research.edm.uhasselt.be/emiplib) 的全称是 'EDM Media over IP libray' 。 EDM 是 Hasselt University 大学的 Expertise Centre for Digital Media   ,这个库就是这里开发的。
  这个库能做什么呢?官方是这么描述的(版本 0.14.0 ):
·     Soundcard input (using OSS, WinMM and Jack)
·     Soundcard output (using OSS, ALSA, ESD, WinMM, Jack and SDL)
·     WAV file input (using libsndfile, libaudiofile or a simple internal WAV reader)
·     WAV file output (using libsndfile or a simple internal WAV writer (8 bit, mono))
·     Webcam input (using Video4Linux and DirectShow)
·     Speex compression
·     U-law audio encoding
·     H.263+ compression (using libavcodec)
·     Mixing of incoming audio streams
·     Synchronization of RTP streams based on RTCP information
·     3D sound effects using HRIR/HRTF data from the LISTEN project
·     Easy to use voice over IP (VoIP) and video over IP sessions
  基本上这个库的目的就是要完成一个多媒体的网络传输库,方便多种媒体在网络上进行传输。从上面可以看到,它提供了从底层的数据采集、编码解码、传输等功能。当然,它不是独立的,比如,我是在 window 下做一个开发,对于音频它使用了 winmm.lib 库,对于视频使用了 Dshow 以及 QT for windows 。  另外,它也依赖于下面两个库: jrtplib 以及 jthread 。比较详细的可以到官方网站找到参考。 http://research.edm.uhasselt.be/emiplib/documentation/index.html
  下面我们就针对 windows 平台下展开吧,因为我的 EMIPLIB 经验基本上是在 windows 平台地 ...
  第一步:编译库 ( 最基本编译 )
  先说说我的平台及环境: windows xp sp2 , vc8( 第一次使用这个新的 IDE ,因为这个 lib 只提供了 VC8 的项目文件,时间原因我没办法尝试 mingw 及 vc6 等 ) 。
  可以到下面地址下载到源代码:
  下载完以后,开始编译 JTHREAD ,用 vc8 打开源代码中的 sln 文件,在项目设置中 C++ 项目下代码生成中选择多线程调试( /Mtd )。以同样方法编译 JRTPLIB 。
这两个库使用 vc6 和 vc8 都可以很轻松的编译,需要注意的是生成静态库时候要统一代码生成中的选项,我这里使用了 /Mtd 。完成后,在你的 debug 或者 release 目录线面会有这两个库: JRTPLIB.LIB JTHREAD.lib 。如果编译这两个库的时候有问题,可以给我 mail ,或者直接去 mail 到作者那里,之前我也问过他一些问题,他是个不错的人。
  然后我们需要来编译最大个的 EMIPLIB 库了,在 EMIPLIB 的源代码目录有 README 文件,上面有在 windows 下编译此库的参考。比较麻烦的问题是对于视频,我们可能需要添加 QT 支持(这可能需要我们在 windows 下先安装好 QT ,并自己手动完成一些文件)。对于最基本的编译我们先不去管它。上面的 README 文件中也说明了,在源代码目录的 src/core/ 目录下面有一个配置文件 mipconfig_win.h ,我们可以在编译前进行一些选择,来得到更多功能支持的库。不过现在我们只使用默认的,只有 speex 支持被添加了。
  用 vc8 打开 sln 文件吧,要正确的进行编译,我们最好先把上面需要的两个库,以及一些头文件放在一个合适的地方,让 IDE 可以找到它们。这需要你设置 vc 的目录(在工具 -- 选项里面)添加 include 目录及 lib 目录。然后也在项目设置中设定多线程调试( /Mtd ),现在应该可以编译 EMIPLIB 了。( PS :我们可能需要安装 Dshow ,新的版本 MS 已经把它从 DxSDK 中踢出来鸟,放到了 PlatFormSDK 中)。
  最基本的编译应该不会花去我们太多时间。让我们先尝尝鲜,看看怎么用这个库。
  第二步: hello world
  在 EMIPLIB 源代码目录里面有一个 examples 目录,里面给了几个例子。我们找一个功能比较全的叫做 feedbackexample.cpp ,来看看怎么使用这个库:
我们省略了其中一些代码,只贴出来比较重要的。
 /* 这个 demo 它打开一个叫做 soundfile.wav 的文件,并对其进行采样、 uLaw 编码、 RTP 编码然后设定好 RTP 的目的地(这里它发送给了自己),再经过 RTP 解码、 uLAW 解码、采样编码,发给声卡让它播放出来。 */
 
 MIPTime interval(0.020);                                        // 设定间隔为 20ms
 MIPAverageTimer timer(interval);                             //
设定计时器          
 MIPWAVInput sndFileInput;                                    //
声音文件输入
 MIPSamplingRateConverter sampConv, sampConv2;    //
采样转换
 MIPSampleEncoder sampEnc, sampEnc2, sampEnc3;   //
采样编码
 MIPULawEncoder uLawEnc;                                    //uLaw
编码
 MIPRTPULawEncoder rtpEnc;                                  //rtp
编码
 MIPRTPComponent rtpComp;                                  //rtp
组建   
 MIPRTPDecoder rtpDec;                                        //rtp
解码
 MIPRTPULawDecoder rtpULawDec;                          //rtp ulaw
解码
 MIPULawDecoder uLawDec;                                   //uLaw
解码                                   
 MIPAudioMixer mixer;                                            //
混音
 MIPWinMMOutput sndCardOutput;                           //
声卡输出
 MyChain chain("Sound file player");                         //
链:用来把上面组建串起来的对象。  
 RTPSession rtpSession;                                         //RTP
会话,来自 jrtplib 
 bool returnValue;                                                 //
返回值   
  int samplingRate = 8000;                                      // 采样率默认为 8kHz 
 int numChannels = 1;                                            //
声道设置默认为单声道
 
 // 打开一个 wav 文件。
 returnValue = sndFileInput.open("soundfile.wav", interval);
// 初始化采样转换,设置了采样率以及声道             
 returnValue = sampConv.init(samplingRate, numChannels);
// 初始化采样编码,参数用于设定音频数据在计算机中的保存形式
 returnValue = sampEnc.init(MIPRAWAUDIOMESSAGE_TYPE_S16);
// 初始化 ulaw 编码
 returnValue = uLawEnc.init();
// 初始化 rtp 编码,这个组建可以创建发送到 RTP 组件的 RTP 消息。 
returnValue = rtpEnc.init();
// 初始化 RTPSession ,需要设置包括端口采样率等等与传输有关的参数
 RTPUDPv4TransmissionParams transmissionParams;
 RTPSessionParams sessionParams;
 int portBase = 60000;
 int status;
 transmissionParams.SetPortbase(portBase);
 sessionParams.SetOwnTimestampUnit(1.0/((double)samplingRate));
 sessionParams.SetMaximumPacketSize(64000);
 sessionParams.SetAcceptOwnPackets(true);
 //
建立一个 RTPSession
 status = rtpSession.Create(sessionParams,&transmissionParams);
 //  添加一个目的地, RTPSession 将往此目的发送 RTP 数据。这里我们发送给自己。
 status = rtpSession.AddDestination(RTPIPv4Address(ntohl(inet_addr("127.0.0.1")),portBase));
 // 初始化 RTP 组件,使用我们刚才定义的 RTPSession 为参数
 returnValue = rtpComp.init(&rtpSession);
 //
初始化 RTP 解码器
 returnValue = rtpDec.init(true, 0, &rtpSession);
 //
设置 RTP 解码器使用 ulaw 规则
 returnValue = rtpDec.setPacketDecoder(0,&rtpULawDec);
 // 
初始化 ulaw 解码,转换 被 U-law 解码的采样数据为线性解码采样
 returnValue = uLawDec.init();
 //  初始化采样编码,转换接受到的音频数据为浮点数形式存储
 returnValue = sampEnc2.init(MIPRAWAUDIOMESSAGE_TYPE_FLOAT);
 // 初始化采样转换 , 设置参数采样率及声道
 returnValue = sampConv2.init(samplingRate, numChannels);
//
初始化混音
 returnValue = mixer.init(samplingRate, numChannels, interval);
//
初始化声卡输出
 returnValue = sndCardOutput.open(samplingRate, numChannels, interval);
//
声卡输出使用的数据形式
 returnValue = sampEnc3.init(MIPRAWAUDIOMESSAGE_TYPE_S16LE);
 //  建立整个链:看看这个顺序,这是整个程序工作的逻辑
 returnValue = chain.setChainStart(&timer);
 returnValue = chain.addConnection(&timer, &sndFileInput);
 returnValue = chain.addConnection(&sndFileInput, &sampConv);
 returnValue = chain.addConnection(&sampConv, &sampEnc);
 returnValue = chain.addConnection(&sampEnc, &uLawEnc);
 returnValue = chain.addConnection(&uLawEnc, &rtpEnc);
 returnValue = chain.addConnection(&rtpEnc, &rtpComp);
 returnValue = chain.addConnection(&rtpComp, &rtpDec);
 returnValue = chain.addConnection(&rtpDec, &uLawDec, true);
 returnValue = chain.addConnection(&uLawDec, &sampEnc2, true);
 returnValue = chain.addConnection(&sampEnc2, &sampConv2, true);
returnValue = chain.addConnection(&sampConv2, &mixer, true);
 returnValue = chain.addConnection(&mixer, &sampEnc3);
 returnValue = chain.addConnection(&sampEnc3, &sndCardOutput);
 
 //
启动这个链
 returnValue = chain.start();
 // 这里添加等待停止的代码
 // 停止 
 returnValue = chain.stop();
 rtpSession.Destroy();
 
要想运行这个程序,需要我们的编译器可以找到 jrtplib.lib,jrtplib.lib,emiplib.lib  以及  这些 lib 导出符号需要的一些 .H 文件。比较好的方法是,把它们分别放到相应目录中,在 vc 目录中设置。另外,还需要在 lib 中添加 ws2_32.lib, winmm.lib 。运行时库选项统一为 "/MTd" 。其它的问题,可能还需要你在忽略库列表中把一些冲突的库加上 , 比如 libc.lib 、 libcmt.lib 、 msvcrt.lib 、 libcd.lib 、 msvcrtd.lib ...
  源代码中没有给你提供上面所说的那个 wav 文件,你需要自己找一个。
  能听到那个 XXX.wav 的声音了,大功告成。 
  第三步:一些介绍
  我们来大体了解一下 EMIPLIB ,以及怎么使用它。
为了提供一个灵活性比较好的框架,此库德目的是建立一些列相关的小组件,每个组件提供一些特定的工作,如音频取样,写音频到文件或者传输音频包等等。这些组件可以放置到一个 chain( 链 ) 中,在这个链上,这些组件可以相互通信。这样,(按照需求)通过连接这些组件到一条链上,可以建立复杂的引用程序。
  另外, EMIPLIB 为了大家使用方便也提供了一些更高级的类,它们包装好了一些常用的功能,给我们更好的 interface 。比如上面 hello world 中的那一串的定义,初始化,貌似都差不多的 chain , MIPAudioSession 类都给我们包装好了。如果这些功能已经提供了足够的功能,使用它们就好了,如果你有特殊的要求,你也可以像上面例子一样,自己写那一堆组件,按照你的思路让他们工作。
  大部分可以放到 MIPComponentChain 上的组件都派生自 MIPComponent 类。我们需要作的工作就是从这些派生类里面选择合适的组件,把它们放在一个 chain 上面,它就可以开始工作了。即使不使用 EMIPLIB 提供给我们的包装类,这些工作也不会很繁琐。比较详细的描述,大家可以参考 EMIPLIB 主页上的 Library core 部分。
  第四步:一个语音会议的 demo
  最后我们来做一个局域网的语音会议的 demo ,也算做个入门结业。
  我们的语音会议的 demo 设计为这样:没有服务器,会议中每一方都可以 listen 来自局域网的声音,也可以往自己的列表中添加目标位置,向它 ( 们 ) 发送你的语音。
这样要完成一个三人的对话,我们需要三方都打开 listen ,并且添加另外两个人的地址,发送自己的声音。
我们开两个独立的线程,一个负责在端口 12000 接受来自局域网的声音,一个负责往发送列表中的目的地发送本地语音。
之前我们的例子中只是在本地做了一个 wav 文件的播放,我们需要解决另外几个问题:得到声卡输入、如何向目的地发送 RTP 、如何接收 RTP 。
第一个问题比较好解决,我们仿照例子中声卡播放使用的对象,找到了这个类: MIPWAVInput ,把它放在某个 chain 的最开始处,我们就可以得到声音的输入了。
代码类似于下面:
 
 MIPWinMMInput sndCardInput;
 bool returnValue;
 int samplingRate = 8000;
 int numChannels = 1;
 returnValue=sndCardInput.open(samplingRate,numChannels,interval,buffertime,false);
 
在初始化 chain 时候:
 
chain.setChainStart(&sndCardInput); 
 
就可以了。
 
RTP 的发送和接收主要是对于 RTPsession 的参数设置。接收端代码我们设置端口为监听端口,发送端 SetPortbase(portBase) 为发送端口,而在 RTPSession::AddDestination 函数中端口使用目的地的监听端口 ;
 
我们的发送语音的线程大致是这样的:
 
DWORD WINAPI WorkerThread(LPVOID lpParameter)
{
 IpAddrList *ipl=(IpAddrList*)lpParameter; //
把目的列表传过来鸟
 WSADATA dat;
 WSAStartup(MAKEWORD(2,2),&dat);
 MIPTime interval(0.020); // We'll use 20 millisecond intervals.
 MIPTime buffertime(10);
 MIPAverageTimer timer(interval);
 MIPWAVInput sndFileInput;
 MIPSamplingRateConverter sampConv;
 MIPSampleEncoder sampEnc;
 MIPULawEncoder uLawEnc;
 MIPRTPULawEncoder rtpEnc;
 MIPRTPComponent rtpComp;
 
 MIPWinMMInput sndCardInput;
 MIPWinMMOutput sndCardOutput;
 MyChain chain("MPVC");
 RTPSession rtpSession;
 bool returnValue;
 int samplingRate = 8000;
 int numChannels = 1;
 //We'll start microphone
 returnValue=sndCardInput.open(samplingRate,numChannels,interval,buffertime,false);
 returnValue = sampEnc.init(MIPRAWAUDIOMESSAGE_TYPE_S16);
 returnValue = uLawEnc.init();
 returnValue = rtpEnc.init();
 RTPUDPv4TransmissionParams transmissionParams;
 RTPSessionParams sessionParams;
 int portBase = BASEPORT_SEND;
 int status;
 
 transmissionParams.SetPortbase(portBase);
 sessionParams.SetOwnTimestampUnit(1.0/((double)samplingRate));
 sessionParams.SetMaximumPacketSize(64000);
 status = rtpSession.Create(sessionParams,&transmissionParams);
 for(int i=0;i<ipl->count;i++) // 这个 for 是从一个列表中读目的地址,大家可以自己按自己的要求实现,几个目的地就调用几个 AddDestination 。
 {
  status = rtpSession.AddDestination(RTPIPv4Address(ntohl(inet_addr(ipl->ipaddr[i])),BASEPORT_LISTEN));
 }
 
 returnValue = rtpComp.init(&rtpSession);
 returnValue = chain.setChainStart(&sndCardInput);
 returnValue = chain.addConnection(&sndCardInput, &sampEnc);
 returnValue = chain.addConnection(&sampEnc, &uLawEnc);
 returnValue = chain.addConnection(&uLawEnc, &rtpEnc);
 returnValue = chain.addConnection(&rtpEnc, &rtpComp);
 returnValue = chain.start();
 while(stop_f)
 {
  Sleep(SLEEP_TIME);
 }
 rtpSession.BYEDestroy(RTPTime(10,0),0,0);
 returnValue = chain.stop();
 rtpSession.Destroy();
 WSACleanup();
 return 0;
}
 
listen 端的代码类似下面:
DWORD WINAPI WorkerThread_Listen(LPVOID lpParameter)
{
 WSADATA dat;
 WSAStartup(MAKEWORD(2,2),&dat);
 MIPTime interval(0.020); // We'll use 20 millisecond intervals.
 MIPTime buffertime(10);
 MIPAverageTimer timer(interval);
 MIPWAVInput sndFileInput;
 MIPSamplingRateConverter sampConv, sampConv2;
 MIPSampleEncoder sampEnc, sampEnc2, sampEnc3;
 MIPULawEncoder uLawEnc;
 MIPRTPULawEncoder rtpEnc;
 MIPRTPComponent rtpComp;
 MIPRTPDecoder rtpDec;
 MIPRTPULawDecoder rtpULawDec;
 MIPULawDecoder uLawDec;
 MIPAudioMixer mixer;
 
 MIPWinMMOutput sndCardOutput;
 MyChain chain("MPVClisten");
 RTPSession rtpSession;
 bool returnValue;
 int samplingRate = 8000;
 int numChannels = 1;
 
 RTPUDPv4TransmissionParams transmissionParams;
 RTPSessionParams sessionParams;
 int portBase = BASEPORT_LISTEN;
 int status;
 transmissionParams.SetPortbase(portBase);
 sessionParams.SetOwnTimestampUnit(1.0/((double)samplingRate));
 sessionParams.SetMaximumPacketSize(64000);
 status = rtpSession.Create(sessionParams,&transmissionParams);
 
 returnValue = rtpComp.init(&rtpSession);
 returnValue = rtpDec.init(true, 0, &rtpSession);
 returnValue = rtpDec.setPacketDecoder(0,&rtpULawDec);
 returnValue = uLawDec.init();
 returnValue = sampEnc2.init(MIPRAWAUDIOMESSAGE_TYPE_FLOAT);
 returnValue = sampConv2.init(samplingRate, numChannels);
 returnValue = mixer.init(samplingRate, numChannels, interval);
 returnValue = sndCardOutput.open(samplingRate, numChannels, interval);
 returnValue = sampEnc3.init(MIPRAWAUDIOMESSAGE_TYPE_S16LE);
 returnValue = chain.setChainStart(&timer);
 returnValue = chain.addConnection(&timer, &rtpComp);
 returnValue = chain.addConnection(&rtpComp, &rtpDec);
 returnValue = chain.addConnection(&rtpDec, &uLawDec, true);
 returnValue = chain.addConnection(&uLawDec, &sampEnc2, true);
 returnValue = chain.addConnection(&sampEnc2, &sampConv2, true);
 returnValue = chain.addConnection(&sampConv2, &mixer, true);
 returnValue = chain.addConnection(&mixer, &sampEnc3);
 returnValue = chain.addConnection(&sampEnc3, &sndCardOutput);
 // Start the chain
 returnValue = chain.start();
 while(lstop_f)
 {
  Sleep(SLEEP_TIME);
 }
  
 rtpSession.BYEDestroy(RTPTime(10,0),0,0);
 returnValue = chain.stop();
 rtpSession.Destroy();
 WSACleanup();
 return 0;
} 
 
其他的一些 UI 方面的事情大家随意吧 ...
你要是在你的局域网里面已经已经成功实现了一个语音会议 demo... 呵呵,恭喜你。我的文章就先写到这里。更高级的 ... 等我会了就写。
大家如果在上面这章有什么问题,可以看看  源代码 src/sessions 目录下的 mipaudiosession.cpp ,里面有 MIPAudioSession 类的实现,它对我们理解这个 chain 很有帮助。
 
EMIPLIB-1.0.0的使用(二) 2011.03.31  By Pafone 这次来编译soundfileplayer,新建一个工程。像EMIPLIB-1.0.0的使用(一)那样在工程属性加入include的目录、库目录和库,还要额外加一个库winmm.lib,这个库不用指定路径。 编译: 1.编译时,说出找不到unistd.h,注释掉即可,原因在上篇文章已经说过。 2.  链接错 1>正在链接... 1>emiplib-1.0.0.lib(mipwinmmoutput.obj) : error LNK2001: 无法解析的外 阅读详情

相关推荐

emiplib chm文档

方便查阅的emiplib 1.1.1 chm文档,由dot+htmpworkshop+doxygen完成。

EMIPLIB使用入门

                                                                       mwg_arden 的草稿,转载需注明。这个库遵守LGPS,所以文档也遵守。  EMIPLIB(http://research.edm.uhasselt.be/emiplib)的全称是EDM Media over IP libray 。EDM是Has

4212

dataviz_energy:用于数据可视化的过程(UHasselt&KULeuven)。 在数据中可视化来自“我们的世界”的能源数据

dataviz_energy 用于数据可视化的过程(UHasselt&KULeuven)。 可视化来自“数据世界”的能源数据。

EMIPLIB库分析二

前一篇中详细分析了MIPComponentChain类。

Neohan的专栏 6957

Scratch离线版部署指南:解决资源缺失与页面显示异常问题

本文提供了一份详尽的Scratch离线版部署指南,旨在解决网络依赖导致的资源缺失与页面显示异常问题。通过从基础文件获取、自动化资源抓取到生产环境部署的完整流程,帮助教育工作者和开发者在无网络环境下搭建功能完整的本地Scratch编辑器,确保编程教学的顺利进行。

wine的专栏 1260

手把手教你用mitmproxy抓包抖音数据流(附Python脚本模板)

本文详细介绍了如何使用mitmproxy抓包抖音数据流,包括环境搭建、证书安装和Python脚本模板。从mitmproxy配置到抖音API解析,提供完整的移动端数据流分析方案,帮助开发者快速掌握数据抓取技术,适用于应用优化、竞品分析和安全审计等场景。

weixin_33670786的博客 307

EMIPLIB库分析一

通过分析feedbackexample例程来了解

Neohan的专栏 7040

卡方检验的隐藏逻辑:为什么正态分布的平方和如此重要?

本文深入探讨了卡方检验的核心逻辑,揭示了正态分布平方和在统计检验中的重要性。通过分析卡方分布与伽马分布的关系,以及实际应用案例,帮助读者理解卡方检验的原理、局限及高级应用场景,为数据分析提供有力工具。

3a9bq4r8t2y的博客 206

EMIPLIB的使用及扩展(二)

2.EMIPLIB的消息机制 EMIPLIB组件对象间,采用消息(Message)驱动机制实现数据的交流与互通。换句话说,组件间数据的交互,只能依靠消息的传递实现。 依据本节第一部分描述的“EMIPLIB的功能模块划分”,将组件分为不同功能类别,对应的,也将消息划分为不同种类,只有相同或者相近功能的组件间才共享同一定义的消息。具体的系统消息结构见下图所示: ...

weixin_34296641的博客 252

华为ENSP虚拟网络与本地物理网卡高效桥接实战指南

本文提供了一份详细的华为ENSP虚拟网络与本地物理网卡桥接实战指南。通过清晰的四步操作,帮助用户打破虚拟实验环境的“孤岛”限制,实现ENSP设备与真实局域网及互联网的互通,从而进行更真实的协议测试、软件升级和混合网络环境搭建。

qsc90123456的博客 536

自定义载板RK3588HDMI输入配置完整解决方案

✅ HDMI输入信号检测✅ 自动时序识别(支持1080p@60Hz等标准格式)✅ V4L2视频设备接口✅ 实时视频流捕获✅ H.264编码录制✅ HDCP内容保护支持问题根因识别:发现了hdmim1模块资源冲突的本质问题硬件设计理解:明确了Orange Pi 5 Plus的真实硬件设计意图功能实现:成功启用HDMI输入功能,替代了无法使用的HDMI1输出完整验证:建立了从硬件检测到视频录制的完整测试流程。

梁俊星的博客 1271

EMIPLIB的使用及扩展(一)

1.1.3 EMIPLIB简介 EMIPLIB全称为“EDM Media over IP Library”,是比利时哈瑟尔大学下属研究机构Expertise Centre for Digital Media (EDM)研发的开源代码,此库用于串联流媒体系统所必须的各个功能模块:音视频数据采集(Input)与播放(Output)、编码(Encode)与解码(Decode)、网...

weixin_34115824的博客 198

YOLO26涨点改进 | 全网独家首发 主干改进篇 | TGRS 2025 | RepViT-TD,告别庞大骨干!YOLO26 + RepViT-TD轻量又强大,实现更快更准的小目标检测!

本文提出将RepViT-TD轻量级主干网络应用于YOLO26目标检测框架,以提升小目标检测性能。RepViT-TD通过优化计算资源分配,强化前两层高分辨率特征提取能力,在保持轻量化的同时(仅4.85M参数)显著提升微小目标的检测精度(AI-TODv2数据集AP50达54.6%)。文章详细介绍了三种主干改进方案(RepVit_ldy1/2/3)的代码实现,并提供了完整的YAML配置文件修改指南,使模型能高效部署于边缘设备。实验表明,该方法在计算复杂度(38.19G FLOPs)和检测精度间取得了良好平衡。

Ai缝合怪、助力小伙伴高效发论文 326

EMIPLIB 简介

EMIPLIB()http://research.edm.uhasselt.be/emiplib的全称是EDM Media over IP libray 。EDM是Hasselt University大学的Expertise Centre for Digital Media  ,这个库就是这里开发的。 这个库能做什么呢?官方是这么描述的(版本0.14.0):·       Soundc

GZFStudy的专栏 3543

windows中通过docker部署LocateAnything-3B模型

windows中通过docker部署LocateAnything-3B模型

yilvyangguang520的博客 483

数据分享】中国12.5m数字高程模型(DEM)数据(分省)

数据名称:ALOS 12.5m DEM 数据。数据名称:ALOS 12.5m DEM 数据。数据大小:61.5GB。空间分辨率:12.5m。数据大小:61.5GB。空间分辨率:12.5m。

JData_Engineer的博客 5387

EMIPLIB1.0.0的编译

EMIPLIB是一个用RTP传输音视频的开源库,totally free。 目前最新版是1.0.0  在这里下载http://research.edm.uhasselt.be/emiplib/emiplib.html emiplib-1.0.0.tar.gz 依赖项:基本的支持声音的用前三个便可以了 1.jrtplib http://research.edm.uhasselt.be/~jori/page/index.php?n=CS.Jrtplib 2.jthread http://researc

pafone的专栏 1816

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

EMIPLIB库分析三 MIPWAVInput

dfd

Neohan的专栏 811

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

EMIPLIB1.0.0的使用(一)

上次已经编译通过了EMIPLIB-1.0.0,下面来学习怎么使用EMIPLIB。先从里面的例子开始。 先编译下最简单的例子。 example文件夹里的simplechain.cpp 新建一个VC2008工程,源文件里添加 simplechain.cpp,在项目属性里设置包含头文件目录,库文件目录,库文件名 这个例子有用到的头文件:jthread-1.2.1, jrtplib-3.7.1, emiplib-1.0.0  用到的三个库也是对应的。 暂时没有用到speex。 编译时提示找不到unistd.

pafone的专栏 2077

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

学习小结-关于emiplib

EMIPLIB的全称是“EDM Media over IP Iibray”,是Hasselt University 大学开发的。这个库的目的是使各种多媒体能在网络上方便传输, 此库提供了从底层的采集,编码解码,传输等功能。加上jrtplib和jthread ,还有如在windows 下开发时的对音频要有winmm.lib库的支持, 对视频的有dshow 以及qt for windous 之内的软件

2227

emiplib调用声卡失败

<br />应用程序使用emiplib的API编写,但打开设备(指声卡)失败。/dev/dsp与/dev/audio也不存在。<br />使用padsp命令运行程序即可,具体内容看padsp手册。<br />例: padsp ./soundfileplayer

湘江鸿的技术专栏 732

RTP和语音

LIBRTP、JRTPLIB 等  Jori在RTP方面做了不少事情.JRTPLIB: http://research.edm.uhasselt.be/~jori/page/index.php?n=CS.JrtplibEMIPLIB: http://research.edm.uhasselt.be/emiplib/emiplib.html RakNet 是网络游戏的一个引擎

技术为业务服务 909
上一篇: 动态链接库几个要点
下一篇: EMIPLIB 简介
GZFStudy
博客等级 码龄20年 42粉丝 62原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值