1.sipåè®®å¦ä½ç¨Cè¯è¨å®ç°
2.pjsip 本地视频预览怎么改变内容源的编译大小 iOS
3.webrtc linphone å°åºåªä¸ª
4.PJSIP源码探究 pjmedia-videodev模块
5.å¦ä½å¨ android 设å¤ä¸ä½¿ç¨ pjsip G.729 ç¼è§£ç çåè½
sipåè®®å¦ä½ç¨Cè¯è¨å®ç°
1ãå¼æºçsipæå¡å¨ç«¯ï¼æ¯è¾å¥½ç¨çæ¯Asteriskï¼æ åCç¨åºå®ç°ï¼ä»£ç æ¸ æ°ã
2ãsipçclientç¸å¯¹æ¯è¾å¤ï¼ä¸»è¦æexosip,pjsipåopalãexosipç®åæç¨ï¼å¨PCä¸ç¨æ¯è¾æ¹ä¾¿ãä½æ¯æ¶åçç¸å ³èµæºå¤ªå¤ï¼ç¨äºosip,srtp,ms2çä¼å¤çå¼æºåºï¼ms2ä¸é¢è¿ç¨å°äºffmpegï¼å«çä¸è¯´ï¼å ç¼è¯å°±æ¯å©æ¢¦ãopalåè½æ强ï¼è½ç¶ä¹ç¨å°äºffmpeg ï¼ä½æ¯èªå·±å°è£ çé常好ï¼éç¨æ件æ¹å¼ï¼è°ç¨çµæ´»ãopaléç¨classæ¹å¼æä¾å°è£ ï¼æ¥å£é常å好ãæè§å¯ä¸ä¸ç½çå°æ¹ï¼å°±æ¯ä½å±ä½¿ç¨äºptlibï¼è½ç¶å¤å¹³å°ä¸é½å¾å¥½ç¨ï¼ä½æ¾å¨åµå ¥å¼ä¸æè§ç¨åºå¤§äºä¸äºãpjsip精巧ï¼æ¹ä¾¿ç§»æ¤ï¼åµå ¥å¼ä¸åºè¯¥æ¯é¦éãä¸è¿è§é¢é¢æ¯ææ¹é¢æ©å±èµ·æ¥æ¯opal麻ç¦ã个人æè§ï¼å¯¹äºwindowså¼åè æ¥è¯´ï¼pjsipæ大ç好å¤å°±æ¯ä»£ç è°è¯æ¹ä¾¿ãæ´ä¸ªå·¥ç¨ä¸æ¬¡ç¼è¯éè¿ï¼å¦å¤ä¸¤ä¸ªåºè¿è¦æ¾å¾å¤ç¸å ³çèµæº
ã
3ãå ¶ä»çä¸äºåè®®æ ä¹è°è¯è¿ï¼æ¯å¦reSipphoneï¼å¥½è±¡æ¯è¿ä¸ªååï¼è¿æYateï¼ä¸è¿ä»å¿«éå¼åè§åº¦çï¼é½ä¸å¤ªåéãç°å¨æsipå¼åçï¼ä¸å¼å§å°±æ¯å æ¾å¥½åè®®æ ãlinphone,ekigaä»ä¹çï¼ä½åºå¤§ã对äºåå¼å§åçï¼æ好æ¯ä¸ä¸ªç²¾ç®çdemoãåæ¥æ¾å°pjsipä¸é¢çå 个ä¾åï¼æ ¢æ ¢å°äºè§£äºsipçå·¥ä½æµç¨ï¼å½ç¶å°ä¸äºæå å·¥å ·åtcpdumpã
ä¸è¿ï¼å ¶å®ï¼sip没ææ³è±¡ä¸çé£ä¹éº»ç¦ãç°å¨å头çï¼åå¼å§å项ç®ï¼ä½¿ç¨åè®®æ ç»å¯¹ä¸æ¯å¥½æ³æ³ãå¦ææ¢ä¸ªæ¹åï¼å çæSIPåºæ¬åè®®ï¼ç¶åèªå·±æ¹é ä¸ä¸ªï¼æå®å ¨åä¸ä¸ªï¼å¯è½æææ´å¥½ã
pjsip 本地视频预览怎么改变内容源的大小 iOS
1 把视频源当然文件来处理,sample有。源译不过这种方法用的码源码编不多。
2 修改vid_stream.c,编译在put_frame和get_frame里,源译换上我们自己的码源码编小程序源码修改流量主视频源。这种方法使用的编译最多,很多人在1.x版本里支持视频,源译就用这种方法。码源码编
3 重新构造sdp,编译自己创建rtp通道。源译
在sdp上,码源码编pjsua_call_make_call这个函数非常方便,编译直接呼叫对方。源译不过它在底层做了太多工作,码源码编比如启动了声卡。而不用这个函数,直接用比较底层的pjsip_inv_send_msg,自己处理的工作相对比较多(但不难,不过这样就不需要pjsua这个现成的程序了,所以我们继续用pjsua_call_make_call)。Vscode源码改造
不过还好,pj库提供了大量的回调,其中一个:on_call_sdp_created,就是在创建sdp后回调上来,由我们自己再修改。比如我们自己定义rtp的端口g_local_port。
void on_call_sdp_created(pjsua_call_id call_id,
pjmedia_sdp_session *sdp,
pj_pool_t *pool,
const pjmedia_sdp_session *rem_sdp)
{
int nPort;
if (sdp != NULL)
{
pjmedia_sdp_media *m = sdp->media[sdp->media_count-1];
m->desc.port = g_local_port;
pjmedia_sdp_conn *c = sdp->conn;
char* addr;
if (c)
addr= c->addr.ptr;
else
{
const pj_str_t *hostname;
pj_sockaddr_in tmp_addr;
char *addr;
hostname = pj_gethostname();
pj_sockaddr_in_init(&tmp_addr, hostname, 0);
addr = pj_inet_ntoa(tmp_addr.sin_addr);
sdp->conn = (pjmedia_sdp_conn *)pj_pool_zalloc (pool, sizeof(pjmedia_sdp_conn));
sdp->conn->net_type = pj_str("IN");
sdp->conn->addr_type = pj_str("IP4");
sdp->conn->addr = pj_str(addr);
}
sdp->origin.addr = *pj_gethostname();
}
}
同样,这里还可以修改payload type等。
这是发起呼叫时的,接收方收到后的trx生态源码回应之后,也会触发这个回调,自己设定RTP端口,payload type就可以了。
2
呼叫成功后,双方建立起连接关系,这时需要传rtp数据了。pjsua把这些工作都放在底层了,不做任何修改,只需要在发送和接收时,自己做一些处理就行。源码大食神
先说接收方(参考siprtp.c源码):
pj_status_t init_local_rtp()
{
if (m_bInitMedia)
{
destroy_media();
}
//g_local_port = local_port;
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pool = pj_pool_create(&(cp.factory), "test", , , NULL);
int status;
//status = pjmedia_endpt_create(&cp.factory, pjsip_endpt_get_ioqueue(pjsua_get_pjsip_endpt()), 0, &med_endpt);
status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
status = pjmedia_rtp_session_init(&video.out_sess, , pj_rand());
status = pjmedia_rtp_session_init(&video.in_sess, , 0);
status = pjmedia_transport_udp_create(med_endpt, NULL, g_local_port, 0, &video.transport);
m_bInitMedia = true;
video.active = true;
return 0;
}
这段代码是本地启动rtp一个端口用来接收视频数据。
然后,从sdp得到对方发送的ip和端口,调用pjmedia_transport_attach,建立关联就可以了。
webrtc linphone å°åºåªä¸ª
æ¯è¾æ¨èwebrtcãwebrtcåºæ¬ææ¯å·²ç»æäºï¼å æ¬p2pä¼ è¾ï¼é³è§é¢codec,é³é¢å¤çææ¯çããç¹å»å è´¹è¯ç¨ï¼0ææ¬å¯å¨ã
Linphoneæ¯èççsipï¼æ¯æå¹³å°å¹¿æ³ windows, mac,ios,android,linuxï¼ææ¯ä¼æ¯è¾æçãä½æ¯linphoneå¨Androidä¸çbugæç¹å¤ãimsdroid,csipsimple,linphoneé½æ³æ³è®¾æ³è°ç¨webrtcçé³é¢ææ¯ï¼æµè¯è¿Android端çwebrtcå ç½è§é¢éè¯æææ¯è¾æ»¡æãä½æ¯è¦æwebrtcåæä¸ä¸ªç§»å¨ç«¯çIM软件çè¯è¿æä¸äºè·¯è¦èµ°ï¼ä¸è¿webrtcåºæ¬ææ¯é½å·²ç»æäºï¼å æ¬p2pä¼ è¾ï¼é³è§é¢codec,é³é¢å¤çææ¯ãä¸è¿å ¶å 为ç®åä» æ¯æVP8çè§é¢ç¼ç æ ¼å¼ï¼QQä¹æ¯ï¼æ³åé«æ¸ è§é¢éè¯çè¦æ³¨æäºãVP8å¨ç§»å¨ç«¯ç硬件ç¼è§£ç æ¯æçå¹³å°æ²¡å 个ï¼RKå¯ä»¥æ¯æVP8硬件ç¼è§£ç ï¼ãä¸è¿webrtc代ç éçå°å¯ä»¥ä½¿ç¨å¤é¨codec,è¿ä¸ªè¿æ¯æå¸æè°å°Hçã
æ³è¦äºè§£æ´å¤å ³äºwebrtcçç¸å ³ä¿¡æ¯ï¼æ¨èå¨è¯¢ZEGOå³æç§æãZEGOå³æç§æèªä¸»ç åçé«é³è´¨è¯é³è§é¢å¼æï¼è½å¤æä¾å®æ¶æ¸ æ°çå¤äººè¯é³è§é¢éè¯ãæ¯æå¤è·¯è§é¢ç»é¢ï¼ä¿éæ¯ä¸è·¯è¯é³è§é¢é½æ¸ æ°æµç æä¾ç«¯å°ç«¯çSDKãåå¸å¼è½¬ç ãæ¥å ¥é´æäºæå¡æ¥å ¥ãæè±è¿ç»´ãè½»æ¾æ¯ææµ·éç¨æ·è¿è¥ã
PJSIP源码探究 pjmedia-videodev模块
PJSIP源码探索:pjmedia-videodev模块详解
在上一章节中,我们已经了解了PJSIP在Android平台的编译和使用基础。接下来,我们将深入探究pjmedia-videodev模块,这一核心组件负责实现PJSIP的蚂蚁平台源码视频捕获功能。掌握这部分内容,你将能够为PJSIP添加自定义视频输入设备。
源码解析:视频捕获入口
在pjsua2的Endpoint.java中,主要通过Endpoint对象的libCreate、libInit、libStart和libDestroy方法来调用底层的c++代码。其中,pjsua_init函数在pjsua_core.c的行中起关键作用,通过media_cfg参数,我们可以看出它与媒体相关。在pjsua_media_subsys_init中,初始化了音频和视频子系统,其中pjmedia_vid_subsys_init在pjsua_vid.c的行,负责初始化视频捕获设备。
在pjmedia-videodev模块中,寻找视频捕获的源头,pjmedia_vid_dev_subsys_init在pjmedia-videodev/videodev.c中负责视频设备的注册。在Android编译环境下,pjmedia_and_factory被注册,负责打开摄像头并获取画面。
源码分析:pjmedia-vid-dev-factory
Android摄像头捕获器工厂的实现位于pjmedia-videodev/android_dev.c,其中工厂实例的创建、设备信息的获取与管理,以及与Java类的交互都十分重要。工厂中的and_factory和factory_op结构体定义了工厂操作的接口,包括设备初始化、信息查询和流创建等。
视频设备流的操作在stream_op中定义,包括获取参数、设置视频功能、启动和停止相机,以及释放资源等。这些操作允许我们动态调整视频流,实现自定义画面捕获。
总结:pjmedia-videodev模块功能概览
pjmedia-videodev的核心是pjmedia_vid_dev_factory,它通过实现一系列操作函数,如创建VideoStream和管理设备流,来捕获和处理视频数据。通过自定义VideoStream和其操作,开发者能够添加时间水印、滤镜效果,甚至捕获屏幕内容,为视频通话增添更多可能性。
至此,关于pjmedia-videodev模块的源码探究已告一段落,希望你对视频捕获的实现有了深入理解,期待你在PJSIP应用中发挥创意。
å¦ä½å¨ android 设å¤ä¸ä½¿ç¨ pjsip G. ç¼è§£ç çåè½
ã第ä¸æ¥æ¯çæ pjsip 为 Android ï¼æ¥éª¤ä¸º Ubuntu Linuxï¼ çæºä»£ç ï¼
ãã1.设置 ANDROID_NDK_ROOT ç¯å¢åéè®¾ç½®ä¸ºæ¨ NDK æ ¹æ件夹ã
ãã2.è½¬å° pjsip 2.x æ件夹并å建 pjlib/include/pj/config_site.h å æ¬ config_site_sample.h ( #include <pj/config_site_sample.h> )
ãã3.è¿è¡./configure-android
ãã4.è¿è¡make clean && make depend && make
ããä¹åè¿äºæ¥éª¤ï¼ä½ å°æå 个éæåºä¸çå 个æ件夹ãæ建议å°å®ä»¬åç»ç¸åçæ件夹 ï¼æ好å¨æ¨ç项ç®ä¸ï¼ ä¸çï¼
ããmkdir <your_project_path>/pjsip_libs
ããfind . -name *.a | xargs -I % cp % <your_project_path>/pjsip_libs/
ããä¸æ¦ä½ çææåºï¼æ¨éè¦å°è¿äºåºæ·»å å°æ¨çé¡¹ç® Android.mk æ件ï¼è¿æ¯ç±å æ¬ä¸ä¸ªæ°ç模åèæ¯ä¸ªå¾ä¹¦é¦ãæ¤æ¨¡åé¨ååºè¯¥æ¯ä¸æ ·çä¸è¥¿ï¼
ããinclude $(CLEAR_VARS)
ããLOCAL_MODULE := pjsua-arm-unknown-linux-androideabi
ããLOCAL_SRC_FILES := $(MY_PJLIB_PATH)/libpjsua-arm-unknown-linux-androideabi.a
ããinclude $(PREBUILT_STATIC_LIBRARY)
ããï¼ä½ å ¶å®æ¯ä¸èä¸æ建æ¨ç JNI 项ç®çæºä»£ç ï¼ææ模åé½æ·»å å°æ¨çéæåºçå¼ç¨ï¼
ããLOCAL_STATIC_LIBRARIES := pjsua-arm-unknown-linux-androideabi ...
ããè¿å°å æ¬ pjsip çå¼ç¨å å ¥æ¨ç JNI åºãç°å¨ï¼æ¨éè¦é ç½® pjsip UA å®ä¾ã
ããä½ æä¸ä¸ªå ³äº init åå¼å§ç解é pjsip ç UA (pjsua) å¨ pjsip/include/pjsua-lib/pjsua.h ä½è¦éµå¾ªç主è¦æ¥éª¤æ¯ï¼
ãã1.å建ä¸ä¸ªå ·æ UA å®ä¾pjsua_create
ãã2.å建ä¸ä¸ªå·¥ä½çº¿ç¨ä¸pj_thread_create
ãã3.UA å®ä¾ç设置çé»è®¤é ç½®ï¼
ããpjsua_config cfg æ¡© ï¼pjsua_logging_config log_cfg ï¼pjsua_media_config media_cfg ï¼
ããpj_cli_cfg_default(&app_config.cli_cfg.cfg) ï¼pjsua_logging_config_default(&log_cfg) ï¼pjsua_media_config_default(&media_cfg) ï¼
ãã4.åå§åå æ ä¸pjsua_init
ãã5.å¯å¨ä¸å æ pjsua_start
ããä»è¿éï¼ä½ æå 足çé ç½®é项 ï¼æ¥å¿ã åªä½ã 交éå·¥å ·çï¼
ããæ¨å¯ä»¥æ¾å°åºæ¬ PJSIP æç¨å¨è¿éï¼åéé¢ pjsip çæºçæ ¹è·¯å¾ï¼ä½ æä¸ä¸ªåºæ¬ ï¼ä½ä¸å¤å®æ´ï¼åºæ¬ç SIP 使ç¨æ åµï¼ å¨ï¼pjsip-apps/src/samples/simple_pjsua.c
ããç¼è¾ï¼å¨çææ¶å¨ pjsip åºç¨ç¨åºç android 项ç®ï¼ä½ å¯ä»¥é¢ä¸´ä¸ä¸ªé®é¢ï¼å 为 pjsua app ä¸çæé»è®¤æ åµä¸ï¼å¯¹ä¸è¬çæ ï¼æ´å ·ä½å°è¯´ï¼pjsuaï¼ ç®æ ä¸å æ¬ææä¸ï¼ å¨ pjsip-åºç¨ç¨åº/çæ/çææ件çç®æ )ãè¥è¦ä¿®å¤è¿åªæ¯è½¬å° pjsip-åºç¨ç¨åº/å建åè¿è¡ï¼
ãã使 pjsua
ããè¿å°å建å¨æ£ç¡®ç对象æ件: pjsip-apps/build/output/pjsua-arm-unknown-linux-androideabi/ (éè¦æ建 android æ ·æ¬æ¶)ã
ããä¸æ¦ä½ ææç¸åºç对象æ件ï¼æ¨å¯ä»¥å¨ pjsip-åºç¨ç¨åº/src/pjsua/android ç³»ç»å次è¿è¡ ndk çæ