使用pjsip传输已经编码的视频,源码在github

pjsip功能很强,做sip rtp语音通话库首选。在2.0之后,也支持视频。不过,它的视频功能缺省是从视频设备采集,然后进行编译,再发送出去的。假设,我们已经有了视频源,比如IP摄像机,不需要采集和编码这个过程,怎么处理呢?假设我们采用pjsip附带的pjsua为例。

通常的方法:
1 把视频源当然文件来处理,sample有。不过这种方法用的不多。
2 修改vid_stream.c,在put_frame和get_frame里,换上我们自己的视频源。这种方法使用的最多,很多人在1.x版本里支持视频,就用这种方法。
3 本文采用的:重新构造sdp,自己创建rtp通道。

前两个方法思路直接,代码量都不小,尤其是第二种,需要修改pj底层代码。
如果基于pjsua做一个简单的视频通信,可以采用本文中的方法。其实代码量也不小,不过sample提供了参考,实现起来也比较容易。下面简单说明:

1 关键点在sdp上,pjsua_call_make_call这个函数非常方便,直接呼叫对方。不过它在底层做了太多工作,比如启动了声卡。而不用这个函数,直接用比较底层的pjsip_inv_send_msg,自己处理的工作相对比较多(但不难,不过这样就不需要pjsua这个现成的程序了,所以我们继续用pjsua_call_make_call)。
不过还好,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等。

这是发起呼叫时的,接收方收到后的回应之后,也会触发这个回调,自己设定RTP端口,payload type就可以了。


呼叫成功后,双方建立起连接关系,这时需要传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", 1000, 512, 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, 97, pj_rand());
status = pjmedia_rtp_session_init(&video.in_sess, 97, 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,建立关联就可以了。

发送方同样调用上面函数,初始化本地端口,但不需要pjmedia_transport_attach。(假定视频传输是单方向的)
发送动作就比较简单了,先把要发的数据分包,大小不超过1400,然后pjmedia_rtp_encode_rtp,再pjmedia_transport_send_rtp。

上面还没有讲接收方是怎么接数据的,这里也用到了pj提供的回调机制:
status = pjmedia_transport_attach(video.transport, &video, 
//&info.rem_addr, 
&remote_addr,
NULL, 
sizeof(pj_sockaddr_in),
&on_rx_rtp,
NULL);

这里面的on_rx_rtp就是接收RTP的回调。

video.transport等定义:

struct media_stream
{
    /* Static: */
    unsigned call_index;    /* Call owner. */
    unsigned media_index;    /* Media index in call. */
    pjmedia_transport   *transport;    /* To send/recv RTP/RTCP */

/* Active? */
    pj_bool_t active;    /* Non-zero if is in call. */

/* Current stream info: */
    pjmedia_stream_info si;    /* Current stream info. */

/* More info: */
    unsigned clock_rate;    /* clock rate */
    unsigned samples_per_frame; /* samples per frame */
    unsigned bytes_per_frame;   /* frame size. */

/* RTP session: */
    pjmedia_rtp_session out_sess;    /* outgoing RTP session */
    pjmedia_rtp_session in_sess;    /* incoming RTP session */

/* RTCP stats: */
    pjmedia_rtcp_session rtcp;    /* incoming RTCP session. */

/* Thread: */
    pj_bool_t thread_quit_flag;  /* Stop media thread. */
    pj_thread_t *thread;    /* Media thread. */
};

struct media_stream video;

源码在:https://github.com/sxcong/pjsipvideo_demo
视频源RTSP,可以直接使用IPCAM,比如海康摄像机。
SIP SERVER是开源的resiprocate,编译出来可直接使用。
DEMO程序是vc2008写的,包括SIP的登录,发送请求,发送和接收视频并解码播放。可在同一台机器上运行两个实例测试。
不过毕竟是DEMO,只是演示怎么使用,细节还有很多问题需要修改。

from:http://blog.chinaunix.net/uid-15063109-id-4445165.html

时间: 2024-11-07 11:26:08

使用pjsip传输已经编码的视频,源码在github的相关文章

使用pjsip传输已经编码的视频

http://blog.chinaunix.net/uid-15063109-id-4445165.html ———————————————————————————————————————————————————————————— pjsip功能很强,做sip rtp语音通话库首选.在2.0之后,也支持视频.不过,它的视频功能缺省是从视频设备采集,然后进行编译,再发送出去的.假设,我们已经有了视频源,比 如IP摄像机,不需要采集和编码这个过程,怎么处理呢?假设我们采用pjsip附带的pjsua为

短视频源码:足不出户看世界

作者/布谷惠泽 来源/山东布谷鸟网络 伴随着互联网的发展,以抖音,快手为主的短视频源码迅速火热起来,预计2020年短视频市场规模将超过350亿元.一方面,随着智能终端的发展和普及,我国使用手机设备上网的网民已经达到了96.3%,远远超过其他上网设备,课件用户的移动触网习惯已经养成:另一方面,中国移动互联网络环境不断优化,为消费者的移动端上网体验提供了技术的支持和保障.移动互联网用户的普及和流量的增长,使得碎片化时代的触网体验难以保障,可以打破时间和空间限制观看浏览视频,因此短视频成为移动互联网时

短视频源码为什么会如此受人关注呢?

作者/布谷惠泽 来源/山东布谷鸟网络   随着信息技术的发展,文字图片作为广泛信息载体的日子已成为过去,抖音的火爆盛行和直播行业的火爆态势证明了视频这一信息载体的魅力,随着短视频APP开发的需求日益增多,一套优异的短视频源码更是能让开发工作事半功倍.那么短视频源码为什么如此受人关注呢?   首先就源码自身层面来讲,一套完整的短视频源码本身的优势就格外引人注意.客户可以通过短视频源码在较短的时间内完成搭建部署,无需×××商进行定制开发,也算省去了一笔不小的费用支出.此外,开源的意义在于,技术客户有

直播风潮淡去,短视频源码成为娱乐行业新宠

作者/布谷惠泽 来源/山东布谷鸟网络  互联网时代,娱乐产品的更新速度非常快,直播风潮已经过去啦,短视频app慢慢成为娱乐行业的新宠!近几年,短视频平台捧红了一大批的网红,人人都想成为流量主吸金,短视频APP平台吸引了越来越多的流量加入,成为了红利风口,许多投资者纷纷开始涉足短视频行业,短视频迅速崛起.  随着中国移动互联网时代的来临,以快手,抖音为主的短视频平台迅速火热起来,移动互联网用户的普及以及流量的增长,是的碎片化时代的触网体验得到了保障,用户可以打破时间和空间限制观看浏览视频,因此短视

为什么小视频源码中要内置那么多的分类模块?

倘若我们将市面上的所有短视频都下载下来进行对比,我们就会发现,大概所有的短视频软件都会有"视频分类"这个模块,这个在短视频源码中,各种视频分类是必不可少的一项. 那么,第一个问题来了:为什么小视频源码中要内置那么多的分类模块?因为分类模块越多,用户类型就越多,越精准,也越利于后期变现. 小视频可以涉足的领域有很多,比如音乐.舞蹈.母婴.科普.种草.购物.搞笑--多领域的精彩内容令人目不暇接,也吸引了更多类型的客户,每种类型的客户凭借其需求可以自主选择他们想看的视频,再辅以大数据算法的支

2017年传智毕业设计视频+源码下载地址

[毕设项目]美食美刻网站制作 视频http://yun.itheima.com/course/253.html 资料链接:http://pan.baidu.com/s/1dFkYBXv 密码:m47l [毕设项目]mui框架之乐淘移动端实战应用01 http://pan.baidu.com/s/1jISpJTG 链接:http://pan.baidu.com/s/1nuPlEQl 密码:rhw0 [毕设项目]mui框架之乐淘移动端实战应用02 http://pan.baidu.com/s/1cv

2019教你用react全家桶+node.js全栈开发大型电商后台管理系统(视频+源码+课件)

主要内容:1. 业务功能模块: 用户登陆.商品分类管理.商品管理.角色管理.用户管理.菜单权限控制.订单管理等2. 前端技术: React + React Router4 + Redux + Antd + Axios + ES6/ES8 + webpack + ECharts/Bizcharts 等 3. 后端技术: NodeJS + Express + MongoDB + Mongoose + Multer 等 4. 项目开发模式: 模块化.组件化.工程化的开发模式 5. 深入源码: 自定义R

基于python语言的tensorflow的‘端到端’的字符型验证码识别源码整理(github源码分享)

基于python语言的tensorflow的‘端到端’的字符型验证码识别 1   Abstract 验证码(CAPTCHA)的诞生本身是为了自动区分 自然人 和 机器人 的一套公开方法, 但是近几年的人工智能技术的发展,传统的字符验证已经形同虚设. 所以,大家一方面研究和学习此代码时,另外一方面也要警惕自己的互联网系统的web安全问题. Keywords: 人工智能,Python,字符验证码,CAPTCHA,识别,tensorflow,CNN,深度学习 2   Introduction 全自动区

Spring 源码从github导入源码到idea2016

步骤 安装git或者github客户端 java环境JDK安装(必须是1.8) gradle下载安装(选择的最新版3.1) git clone github上spring源码 import导入project