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

2023-05-16

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,只是演示怎么使用,细节还有很多问题需要修改。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Asterisk修改res_pjsip以支持IMS VoLTE tel URI Scheme

    一 概述 nbsp nbsp Asterisk 13 0 0到Asterisk 16 15 0这些官方版本都是不支持IMS VoLTE tel URI scheme RFC3966 假如将Asterisk部署在这几个版本环境中不可避免地会遇
  • Asterisk修改res_pjsip以支持IMS VoLTE tel URI Scheme

    一 概述 nbsp nbsp Asterisk 13 0 0到Asterisk 16 15 0这些官方版本都是不支持IMS VoLTE tel URI scheme RFC3966 假如将Asterisk部署在这几个版本环境中不可避免地会遇
  • 使用pjsip传输已经编码的视频

    pjsip功能很强 xff0c 做sip rtp语音通话库首选 在2 0之后 xff0c 也支持视频 不过 xff0c 它的视频功能缺省是从视频设备采集 xff0c 然后进行编译 xff0c 再发送出去的 假设 xff0c 我们已经有了视频
  • Window下编译PJSIP,不编译Media模块

    Windows系统下使用VS2017进行编译PJSIP 下载地址 PJSIP的地址 https github com pjsip pjproject 在线clone太慢的话 可以直接在这里下载比clone会快很多 https github
  • Cocoapods:目标具有传递依赖项,在安装“VialerSIPLib”时包括静态二进制文件

    我正在尝试为 Jsip VialerSIPLib 安装 Objective C 包装器 并在我的 swift 项目中使用它 这是我的 pod platform ios 10 0 use frameworks target EMedicalA
  • 如何在设备的前台应用程序中显示双高绿色状态栏(通话中)?

    这里有很多问题要求在后台显示红色录音栏 很明显我应该使用AVAudioSession类别AVAudioSessionCategoryPlayAndRecord为了那个原因 我的问题是 当我的应用程序中有活动的 VOIP 通话时 如何在前台应
  • C - 使用 pjsip 时如何解决此错误?

    我在使用 pjsip 时遇到此错误 如何解决这个问题 我的系统中有麦克风 扬声器 但无法获取设备 http paste ubuntu com 6504337 Create audio device parameter to open the
  • ios pjsip - 在 sip 通话期间播放声音

    当我进行 sip 呼叫时 有时我想发送 dtmf 数字 为此 我创建了一个自定义拨号盘 当按下某个键时 该拨号盘应播放该键的声音 但在 sip 呼叫期间不会播放该声音 当没有呼叫时 会播放声音 这些声音是通过以下函数播放的AudioTool
  • 在 Android 上使用 pjsip

    我成功安装并构建了pjsip图书馆和pjsua对于Android 我跑了pjsua在我的设备上并且它有效 但是我仍然不知道如何使用这个库的方法 我已经看过了CSipSimple应用程序 我注意到jni这两个项目的文件夹非常不同 我是否必须将
  • ios10 iphone5s voip siphon pjsip2.5.5 打开声音设备时出错

    有人可以告诉我为什么会发生这种情况吗 iOS10 iPhone5s VOIP虹吸pjsip2 5 5 这些问题并不是每次都会出现 有时当你想拨打电话或接听电话时就会出现 添加于 20161226 打开声音设备时出错 14 06 03 137
  • 为所有架构编译 PJSIP 2.5 库

    要为 iPhone 设备编译 PJSIP 库 我使用此代码 make distclean make clean ARCH arch arm64 configure iphone enable opus codec make dep make
  • PJSIP 库中的 TLSv1_2 (TLS1.2) 支持

    我正在使用最新的PJSIP http www pjsip org 我的 Android iOS 应用程序中的库 我想在我的项目中使用 TLSv1 2 连接 PJSIP 支持哪个 TLS 版本 从源代码来看它似乎支持TLSv1 0 有没有办法
  • pjsip接收短信

    任何人都知道有关如何设置 pjsip 客户端来接收消息的任何好例子 我可以使用以下方式从客户端发送消息 pjsua im send sip acc id to NULL msgbody NULL NULL 到任何数字 但我不知道如何才能将消
  • pjsip 2.5.5 构建错误

    我正在尝试为 android 构建 pjsipNDK r13b 标准构建就像 configure android with opus home user pjsip pjproject opus dev lib工作完美 但我需要几个TARG
  • Android 使用 openssl 构建 PJSIP

    我正在尝试在 Android 上构建具有 SSL TLS 支持的 PJSIP 我成功构建了 OpenSSL 以下这个答案 https stackoverflow com a 11170629 1274789 没有 fips 作为共享 so
  • Android SIP 堆栈 - 使用什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要在 Android 上创建使用 SIP 堆栈 它将与 asterix 一起使用 并使用户能够更改
  • 当 pjmedia_conf_connect_port 在 pjsip 中执行 SIGABRT 时,录音呼叫崩溃

    早些时候 当我使用 pjsip 2 7 1 时 它工作正常 通话录音很完美 但现在我已经安装了pjsip 2 9 它在 pjmedia conf connect port 上崩溃 SIGABRT 因为 pjsua var mconf 我不知
  • pjsip 库中的 UnsatisfiedLinkError

    我构建 Pjsip 库并在 android studio 中使用它的示例 question 当我运行时出现此错误 我该如何解决它 提前致谢 例外 jsip pjsua2 app E AndroidRuntime 致命异常 main 进程 o
  • Pjsip iOS 如何将声音传输到接收端并录制?

    func startSipRecording caller String callid pjsua call id gt started Bool startDate NSDate var status pj init if status
  • 如何使用 PJSIP 为 iOS 客户端应用程序捕获并翻译其他语言的传入音频流?

    我想在基于 VoIP 的 iOS 客户端应用程序中集成语言转换器 该应用程序将根据用户选择将实时传入音频流翻译为其他选定的语言 我正在使用 PjSip 开源库来支持 VoIP 呼叫 对于语言翻译 我想使用语音到文本和文本到语音开源库 现在我

随机推荐

  • 在ros环境下的amcl配置笔记

    这段时间导师让研究一下amcl xff0c 在这之前只有一点ros基础 xff0c 根本不知道amcl是什么东东 xff0c 于是开始查资料找教程 xff0c 但是真心没有找到面向小白的配置教程 xff0c 在这几天的摸索中 xff0c 终
  • ROS 发布和订阅自定义消息数组

    今天学习使用ros发布和订阅自定义的消息以及消息数组 xff0c 记录 xff0c 备忘 xff01 说明 xff1a 以ubuntu14 04 xff0c indigo版本为例 ros工作空间位置 xff1a workspace catk
  • Ubuntu USB串口数据 读取及显示

    显示串口接受的数据命令 1 1 在终端输入 lsusb 显示所有连接的usb设备 1 2 在终端输入 ls dev ttyA 显示所有连接的虚拟USB设备端口号 1 3 在终端输入 ls dev ttyU 显示所有连接的USB设备端口号 1
  • 单片机学习(四)——ESP8266(最全教程和说明)

    文章目录 前言一 ESP8266可以干什么 xff1f 二 ESP8266作为传输数据的开发 1 电路连接图2 ESP8266直接烧录3 通过Arduino对ESP8266进行烧录三 ESP8266作为开发板的开发四 可能会存在的问题总结
  • VScode怎么修改主题色

    VScode底部点击 设置 按钮 xff0c 点击colorTheme 出来的弹框选项中 xff0c 点击选择合适的主题色即可
  • 初学者PID进阶——在线调整参数

    原文地址 xff1a http brettbeauregard com blog 2011 04 improving the beginner e2 80 99s pid tuning changes 问题The Problem 在系统运行
  • 路由器WiFi天线拆机详解-路由器天线原理

    xff08 本文已经同步到公众号 原创文章 xff0c 转载请与作者联系 xff09 1 前言 xff1a 随着无线通信的发展 xff0c WiFi对我们日常生活工作越来越重要 作为WiFi的载体 路由器 xff0c 也是经常出现在生活的各
  • 以机器人为中心的视觉惯性里程计--RVIO

    有没有大佬能用这个代码发布一个 39 nav msgs Odometry 39 message的 34 odom 34 话题 xff0c 下面是代码的github地址 xff0c 和作者的意见 代码地址 https github com r
  • ubuntu的gazebo无法加载模型的解决办法

    最近在CMU exploration的平台上做仿真实验时 xff0c 出现了无法加载模型的错误 ERROR 1657256347 244258655 3 370000000 Updating ModelState model camera
  • 开发板(ubuntu系统)通过串口接收数据,并将数据通过网口转发出去

    测试软件windows下串口助手和cmd下的telnet xff0c ubuntu下的minicom 设置好相应的串口号和端口号 此程序可以正常接收数据 include lt termios h gt include lt unistd h
  • 嵌入式操作系统的内存,你了解多少?

    linux 内存是后台开发人员 xff0c 需要深入了解的计算机资源 合理的使用内存 xff0c 有助于提升机器的性能和稳定性 本文主要介绍 linux 内存组织结构和页面布局 xff0c 内存碎片产生原因和优化算法 xff0c linux
  • RK查看gpu占用率方法

    查看gpu占用率 cat sys devices platform ff9a0000 gpu devfreq ff9a0000 gpu load 0 64 200000000Hz 64 前面的数值表示gpu占用率 xff0c 如果一直为0
  • 对视频50p,50i 还有25p,25i区别的粗劣解释

    对视频50p 50i 还有25p 25i区别的粗劣解释 首先跟你解释p和i的概念 xff0c p是逐行扫描模式 xff0c i是隔行扫描模式 帧速率有以下几种 xff1a 60帧 秒 xff08 实际为59 94帧 秒 xff0c 为方便起
  • 对 makefile 中 .c.o 的理解

    LIBS 61 gao o all LIBS 64 echo 34 final 34 c o gcc o 64 lt echo 34 in c o rule 34 执行 结果 xff1a gcc o gao o gao c in c o r
  • 使用arecord、aplay 实现录音和播放

    Linux应用开发 第八章 ALSA应用开发 腾讯云开发者社区 腾讯云 tencent com period size 指定 period size buffer size 指定 buffer size 259条消息 使用arecord a
  • git 查看某个文件的修改记录

    1 git log filename 可以看到fileName相关的commit记录 2 git log p filename 可以显示每次提交的diff 3 查看某次提交中的某个文件变化 xff0c 可以直接加上fileName git
  • C语言wav格式详解,代码实践

    393条消息 C语言wav格式详解 xff0c 代码实践 c语言写wav文件 白屿林的博客 CSDN博客
  • RT-Thread 命令自启动详解

    408条消息 RT Thread 自动初始化详解 init app export Nameless Y的博客 CSDN博客 在msh c增加如下代码 xff0c 即可实现自启动 static int exec audio sample vo
  • (无人机方向)ros小白学习之路(一)ROS创建节点与编译

    文章目录 前言ROS创建节点与编译创建工作空间 1 创建和初始化 2 编译 3 为新建的工作空间配置系统环境ros功能包的创建1 xff1a 自定义功能包的创建2 xff1a 在github上下载功能包源码 ROS功能包常用指令1 xff1
  • 使用pjsip传输已经编码的视频

    pjsip功能很强 xff0c 做sip rtp语音通话库首选 在2 0之后 xff0c 也支持视频 不过 xff0c 它的视频功能缺省是从视频设备采集 xff0c 然后进行编译 xff0c 再发送出去的 假设 xff0c 我们已经有了视频