Live555 C++ arm linux64 RTSP推流开发

这篇具有很好参考价值的文章主要介绍了Live555 C++ arm linux64 RTSP推流开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、首先安装Live555

1、下载源码

由于不能apt-get install,所以先官网下载源码。http://www.live555.com/liveMedia/
live555,c++,arm开发,开发语言,1024程序员节
live555,c++,arm开发,开发语言,1024程序员节
解压 tar -zxvf live.2023.07.24.tar.gz

安装可以看这篇博文前部
live555server环境搭建
OpenSSL必须安装

2、生成makefile

安装时如果直接在arm板子上装,生成makefile时就直接写

~/live$ ./genMakefiles linux

# 查看Makefile
~/live$ cat Makefile
##### Change the following for your environment:
COMPILE_OPTS =		$(INCLUDES) -I/usr/local/include -I. -O2 -DSOCKLEN_T=socklen_t -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
C =			c
C_COMPILER =		cc
...

不能写成armlinux

~/live$ ./genMakefiles armlinux

# 查看Makefile
~/live$ cat Makefile
##### Change the following for your environment:
CROSS_COMPILE?=		arm-elf-
COMPILE_OPTS =		$(INCLUDES) -I/usr/local/include -I. -O2 -DSOCKLEN_T=socklen_t -DNO_SSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
C =			c
...

如果选成了armlinux,这样make的时候用的就是交叉编译工具链,仅适用于从x86机器上给arm机器编译。

3、make

make时基本都会遇到test问题
编辑一下这个文件 /live/BasicUsageEnvironment/BasicTaskScheduler.cpp(190行左右)

if (fTriggersAwaitingHandling[i].test()) {
# 将上面这行改为
if (fTriggersAwaitingHandling[i].test_and_set()) {

4、sudo make install

编好了再运行sudo make install之后,就会把头文件放到 /usr/local/include 中,库文件放到 /usr/local/lib 中,不需要添加环境变量。

5、编译

编译demo的时候,在makefile中增加-I和-L就行。

文件名:
test_live555.cpp
编译指令:
g++ -I/usr/local/include -I/usr/local/include/groupsock -I/usr/local/include/UsageEnvironment -L/usr/local/lib test_live555.cpp -o test_live555 -lliveMedia -lBasicUsageEnvironment -lgroupsock -lUsageEnvironment -lssl -lcrypto

-lliveMedia -lBasicUsageEnvironment -lgroupsock -lUsageEnvironment 是live555的
-lssl -lcrypto 是OpenSSL的

二、运行demo

我们既然是要做rtsp推流,demo在 live/testProgs/testOnDemandRTSPServer.cpp 中,这个demo功能就是读取本地视频,然后启动RTSP推流服务器。

make的时候已经编译好了,我们可以直接运行。
不过我删减了一些,得自己编译了。拷到test_live555.cpp中,写一个makefile:

#include <liveMedia/liveMedia.hh>
#include <BasicUsageEnvironment/BasicUsageEnvironment.hh>
#include <UsageEnvironment/UsageEnvironment.hh>
#include <GroupsockHelper.hh>


void announceURL(RTSPServer* rtspServer, ServerMediaSession* sms) {
  if (rtspServer == NULL || sms == NULL) return; // sanity check

  UsageEnvironment& env = rtspServer->envir();

  env << "Play this stream using the URL ";
  if (weHaveAnIPv4Address(env)) {
    char* url = rtspServer->ipv4rtspURL(sms);
    env << "\"" << url << "\"";
    delete[] url;
    if (weHaveAnIPv6Address(env)) env << " or ";
  }
  if (weHaveAnIPv6Address(env)) {
    char* url = rtspServer->ipv6rtspURL(sms);
    env << "\"" << url << "\"";
    delete[] url;
  }
  env << "\n";
}
static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
			   char const* streamName, char const* inputFileName) {
  UsageEnvironment& env = rtspServer->envir();

  env << "\n\"" << streamName << "\" stream, from the file \""
      << inputFileName << "\"\n";
  announceURL(rtspServer, sms);
}

UsageEnvironment* env;

// To make the second and subsequent client for each stream reuse the same
// input stream as the first client (rather than playing the file from the
// start for each client), change the following "False" to "True":
Boolean reuseFirstSource = False;

int main(int argc, char** argv) {
  // Begin by setting up our usage environment:
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  env = BasicUsageEnvironment::createNew(*scheduler);

  UserAuthenticationDatabase* authDB = NULL;
#ifdef ACCESS_CONTROL
  authDB = new UserAuthenticationDatabase;
  authDB->addUserRecord("admin", "a12345678");
#endif

  // Create the RTSP server:
#ifdef SERVER_USE_TLS
  // Serve RTSPS: RTSP over a TLS connection:
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 322, authDB);
#else
  // Serve regular RTSP (over a TCP connection):
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
#endif
  if (rtspServer == NULL) {
    *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
    exit(1);
  }

  char const* descriptionString
    = "Session streamed by \"testOnDemandRTSPServer\"";

  // A H.264 video elementary stream:
  {
    char const* streamName = "h264ESVideoTest";
    char const* inputFileName = "test.264";
    ServerMediaSession* sms
      = ServerMediaSession::createNew(*env, streamName, streamName,
				      descriptionString);
    sms->addSubsession(H264VideoFileServerMediaSubsession
		       ::createNew(*env, inputFileName, reuseFirstSource));
    rtspServer->addServerMediaSession(sms);

    announceStream(rtspServer, sms, streamName, inputFileName);
  }

#ifdef SERVER_USE_TLS
  // (Attempt to) use the default HTTPS port (443) instead:
  char const* httpProtocolStr = "HTTPS";
  if (rtspServer->setUpTunnelingOverHTTP(443)) {
#else
  char const* httpProtocolStr = "HTTP";
  if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
#endif
    *env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-" << httpProtocolStr << " tunneling.)\n";
  } else {
    *env << "\n(RTSP-over-" << httpProtocolStr << " tunneling is not available.)\n";
  }

  env->taskScheduler().doEventLoop(); // does not return

  return 0; // only to prevent compiler warning
}


CC = g++
CFLAGS = -I/usr/local/include -I/usr/local/include/groupsock -I/usr/local/include/UsageEnvironment
LDFLAGS = -L/usr/local/lib
LIBS = -lliveMedia -lBasicUsageEnvironment -lgroupsock -lUsageEnvironment -lssl -lcrypto

TARGET = test_live555

all: $(TARGET)

$(TARGET): test_live555.cpp
	$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ $(LIBS)

clean:
	rm -f $(TARGET)

(删干净了其他格式,只留了.264的,不然太乱)随便拷了一个.264文件过来,运行后打印如下:

$ ./test_live555 

"h264ESVideoTest" stream, from the file "test.264"
Play this stream using the URL "rtsp://192.168.1.149:8554/h264ESVideoTest"

(We use port 8000 for optional RTSP-over-HTTP tunneling.)

这时就代表,已经开始推流了,用vlc输入这个url就可以拉了
live555,c++,arm开发,开发语言,1024程序员节
拉流时可以看到程序打印

MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (60972).  55319 bytes of trailing data was dropped!  Correct this by increasing "OutPacketBuffer::maxSize" to at least 115319, *before* creating this 'RTPSink'.  (Current value is 60000.)
MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (60972).  55319 bytes of trailing data was dropped!  Correct this by increasing "OutPacketBuffer::maxSize" to at least 115319, *before* creating this 'RTPSink'.  (Current value is 60000.)
MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (60972).  9383 bytes of trailing data was dropped!  Correct this by increasing "OutPacketBuffer::maxSize" to at least 69383, *before* creating this 'RTPSink'.  (Current value is 60000.)

同时也可以抓包看到RTSP相关网络包
live555,c++,arm开发,开发语言,1024程序员节

三、问题

live555似乎无法对RTSP推理地址进行定制。除非改源码。
live555,c++,arm开发,开发语言,1024程序员节

源码GroupsockHelper.cpp可见

ipv4AddressBits ourIPv4Address(UsageEnvironment& env) {
  if (ReceivingInterfaceAddr != INADDR_ANY) {
    // Hack: If we were told to receive on a specific interface address, then 
    // define this to be our ip address:
    _ourIPv4Address = ReceivingInterfaceAddr;
  }

  if (!_weHaveAnIPv4Address) {
    getOurIPAddresses(env);
  }

  return _ourIPv4Address;
}

...

void getOurIPAddresses(UsageEnvironment& env) {
  // We use two methods to (try to) get our IP addresses.
  // First, we use "getifaddrs()".  But if that doesn't work
  // (or if "getifaddrs()" is not defined), then we use an alternative (more old-fashioned)
  // mechanism: First get our host name, then try resolving this host name.
  struct sockaddr_storage foundIPv4Address = nullAddress(AF_INET);
  struct sockaddr_storage foundIPv6Address = nullAddress(AF_INET6);

  Boolean getifaddrsWorks = False; // until we learn otherwise
#ifndef NO_GETIFADDRS
  struct ifaddrs* ifap;

  if (getifaddrs(&ifap) == 0) {
    // Look through all interfaces:
    for (struct ifaddrs* p = ifap; p != NULL; p = p->ifa_next) {
      // Ignore an interface if it's not up, or is a loopback interface:
      if ((p->ifa_flags&IFF_UP) == 0 || (p->ifa_flags&IFF_LOOPBACK) != 0) continue;

      // Also ignore the interface if the address is considered 'bad' for us:
      if (p->ifa_addr == NULL || isBadAddressForUs(*p->ifa_addr)) continue;

      // We take the first IPv4 and first IPv6 addresses:
      if (p->ifa_addr->sa_family == AF_INET && addressIsNull(foundIPv4Address)) {
        copyAddress(foundIPv4Address, p->ifa_addr);
        getifaddrsWorks = True;
      } else if (p->ifa_addr->sa_family == AF_INET6 && addressIsNull(foundIPv6Address)) {
        copyAddress(foundIPv6Address, p->ifa_addr);
        getifaddrsWorks = True;
      }
    }
    freeifaddrs(ifap);
  }
  
  ...

在获取IP时

for (struct ifaddrs* p = ifap; p != NULL; p = p->ifa_next) {

ifap中有所有网卡的信息,但是

if (p->ifa_addr->sa_family == AF_INET && addressIsNull(foundIPv4Address)) {

这句只拿了第一个符合要求的ip。只要变量foundIPv4Address中有结果,就不会再要了。所以只能获取到一个ip,返回到上层的_ourIPv4Address中,拼接到RTSP服务器url前面。文章来源地址https://www.toymoban.com/news/detail-778602.html

到了这里,关于Live555 C++ arm linux64 RTSP推流开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • live555server环境搭建

    openssl可选安不安 安装(选择好版本) 使用头文件是否可用时编译测试时记得链接(不可调换顺序) 不安 ./genMakefiles linux 这里可能会报一个编译错误 这里修改自己解压后这个文件中的/live/BasicUsageEnvironment/BasicTaskScheduler.cpp(190行左右) 这样就可以继续编译了 这两个文件夹下

    2024年02月12日
    浏览(39)
  • live555推送实时视频流

    1,linux 环境: 官网上下载,下载地址:http://www.live555.com/liveMedia/public/ live555 版本:“2018.12.14” 参考:http://www.live555.com/liveMedia/faq.html 这个FAQ要仔细阅读。 2,编译 根据不同的平台来配置,并生成对应的Makefile 2.1 ARM平台: 修改交叉编译工具 cp config.armlinux config.arm vi config.arm

    2023年04月08日
    浏览(79)
  • 实时流媒体传输开源库——Live555

    Live555(LiveMedia Libraries)是一个开源的多媒体流处理库,主要用于实现基于标准网络协议的实时流媒体传输。Live555提供了一套 C++ 类库,可以用于开发支持 RTP/RTCP、RTSP、SIP 等协议的流媒体服务器和客户端应用程序。它广泛用于视频监控、视频会议、音视频直播等流媒体传输领

    2024年01月22日
    浏览(47)
  • 基于Live555实现数据流的推送

    Live555是使用c++编写的RTSP开源库,以文件为载体进行推流,其中实现了多种类型的音频以及视频的流化。 RTSP是一种媒体传输协议,基于TCP协议,主要功能为媒体播放的控制以及开始连接时的握手操作。时间流传输走的时RTP协议,流传输控制协议走的是RTCP,RTP和RTCP具体使用

    2024年02月12日
    浏览(43)
  • 探讨下live555用的编程设计模式

    这个应该放到这里 7.live555mediaserver-第1阶段小结(完整对象图和思维导图) https://blog.csdn.net/yhb1206/article/details/127330771 但是想想,还是拿出来吧。 从这第1阶段就能发现,它实质用到了reactor网络编程模式,具体点是 单Reactor服务器模型 。 该文章说的很不错。Reactor模式介绍ht

    2024年02月09日
    浏览(34)
  • ubuntu-22.04.3-live-server-amd64安装详细过程

    一、ubuntu-22.04.3官方下载地址 1.打开网址地址:https://cn.ubuntu.com/download/alternative-downloads​​​​​​ 2.拖到网页下方,点击”Ubuntu 22.04.3 LTS 服务器版“ 3.先安装迅雷,然后点开点开下载的BT文件即可下载 二、使用VMware Workstation Pro创建虚拟机 1.VMware Workstation Pro实验演示的版本

    2024年02月04日
    浏览(43)
  • ubuntu-20.04.6-live-server-amd64安装教程-完整版

    Ubuntu 20.04.6 Live Server AMD64 安装教程 - 完整版\\\" 提供了详细的指南,旨在帮助用户在使用 AMD64 架构的服务器上安装 Ubuntu 20.04.6 Live Server 版本。该教程包含全面的步骤和详细说明,使用户能够顺利完成整个安装过程,建立一个基于 Ubuntu 20.04.6 的服务器环境。     选择语言 选择跳

    2024年01月21日
    浏览(79)
  • Ubuntu 中 desktop-amd64 和 live-server-amd64 的区别、ubantu安装

    目录 一、Ubuntu的操作系统镜像 1. Desktop-amd64: 2. Live-server-amd64: 二、ubantu 安装 1、安装前的准备工作 2、VMware虚拟机安装Ubuntu操作系统 2.1新建虚拟机 2.2选择类型配置 2.3选择安装客户机操作系统 2.4命名虚拟机 2.5指定磁盘容量 2.6设置 自定义硬件 1.点击“自定义硬件”,根据需要

    2024年04月16日
    浏览(54)
  • 在Fedora-Workstation-Live-x86_64-36-1.5中使用佳能喷墨打印机ip2780

    在Fedora-Workstation-Live-x86_64-36-1.5中使用佳能喷墨打印机ip2780 操作系统是64位的Fedora-Workstation-Live-x86_64-36-1.5.iso,实物打印机是佳能ip2780,USB接口 应用程序——其它——设置——打印机——解锁——输入root密码——将打印机USB插入电脑主机并按下电源键,大约1分钟后跳出提示打

    2024年02月05日
    浏览(54)
  • 使用uni-live-pusher 和 uni-live-player 组件开发小程序直播功能

    Uniapp开发文档中没有直接提供小程序直播功能的API,需要自己通过调用第三方SDK或者封装相关API实现。下面介绍一些可能实用的组件和工具: uni-live-pusher 和 uni-live-player 组件:这两个组件可以实现小程序直播推流和播放器功能,可在H5、App、微信小程序等多端使用。 腾讯云直

    2024年02月12日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包