前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IOS 下实现一对一直播平台系统 libRtmp 推拉流

IOS 下实现一对一直播平台系统 libRtmp 推拉流

原创
作者头像
布谷鸟网络科技
修改2019-03-18 11:06:24
2.5K0
修改2019-03-18 11:06:24
举报

前言

今天向大家介绍一下如何使用 librtmp 库推拉音视频直播流。虽然Adobe已经宣布不在维护 flash 了,但 flash使用的 rtmp 协议目前仍然是直播系统中最常用的传输协议。

目前实现 rtmp 协议的有很多库,但在众多 rtmp 协议的实现中,librtmp 无疑是最好的一个。

今天我们就向大家介绍一下,如何在 iOS 中使用 librtmp。

交叉编译 librtmp

在开发移动端程序时,我们都会用到交叉编译。那么什么是交叉编译呢?交叉编译就是指在一种 CPU类型/操作系统 的机子上编译出另一种 CPU类型/操作系统 的机子上可以运行的程序就称为交叉编译。

以 iOS 为例,我们在 Mac 环境上(CPU类型为 Intel)编译出 iPhone 手机(CPU类型为 ARM)可执行的程序。这个工作我们几乎每天都在做,只是大家没有观注而已。

同样,我们想在 iOS 程序中使用 librtmp 库,就必须先将 librtmp 编译成 ARM 架构 的可执行的程序(也就是 iPhone 手机可执行的程序),这样才能在 iOS 程序中使用它。

Xcode 为我们提供了交叉编译的工具。可以通过 xcode-select --print-path 可获取交叉编译工具目录,在该目录的 user/bin 下就可以找到交叉编译的工具。最主要的两个工具是 gcc 编译器和 ld 链接器。

下面我们来详细介绍一下 gcc 及 ld 参数的含义:

  • isysroot: 指定目标机SDK位置,也就是iPhone手机开发SDK的位置。
  • arch: 指定目标机 CPU 架构。
  • miphoneos-version-min: 指定可用的操作系统最小版本。
  • fembed-bitcode: 苹果自带的参数。从 iOS7.0 开始支持。有兴趣的同学在线上查一上资料吧。

下面是编译 librtmp 的部分关键脚本:

DEVELOPER=$(xcode-select --print-path)

SDK_VERSION=$(xcrun -sdk iphoneos --show-sdk-version)
echo $SDK_VERSION
SDK_VERSION_MIN=7.0

DEVICE_PLATFORM="${DEVELOPER}/Platforms/iPhoneOS.platform"
SIMULATOR_PLATFORM="${DEVELOPER}/Platforms/iPhoneSimulator.platform"
DEVICE_SDK="${DEVICE_PLATFORM}/Developer/SDKs/iPhoneOS${SDK_VERSION}.sdk"
SIMULATOR_SDK="${SIMULATOR_PLATFORM}/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk"

...

CROSS_COMPILE="${DEVELOPER}/usr/bin/" \
XCFLAGS="-g -O2 -isysroot ${SDK} -I${IOS_OPENSSL}/include -arch $ARCH -miphoneos-version-min=${SDK_VERSION_MIN} -fembed-bitcode" \
XLDFLAGS="-isysroot ${SDK} -arch $ARCH -L${IOS_OPENSSL}/lib -lssl" \
make SYS=darwin

make SYS=darwin prefix="/tmp/librtmp-$ARCH" install &> "/tmp/librtmp-$ARCH.log"

执行该脚本后,它就指定好了做交叉编译的编译器及链接器。并指定好了编译参数和链接参数。最后,Makefile 会使用指定的编译器对代码进行编译,生成可以在iPhone上运行的程序。

使用 librtmp 拉流

使用 librtmp 接流的基本步骤:

  1. 分配 RTMP 对象,并初始化 RTMP *rtmp=RTMP_Alloc(); RTMP_Init(rtmp);
  2. 设置 rtmp URL RTMP_SetupURL(rtmp,"rtmp://live.hkstv.hk.lxdns.com/live/hks")
  3. 设置缓冲区大小 //1hour RTMP_SetBufferMS(rtmp, 3600*1000);
  4. 连接流媒体服务器 ... RTMP_Connect(rtmp,NULL) ... RTMP_ConnectStream(rtmp,0) ...
  5. 拉流 while((nRead=RTMP_Read(rtmp,buf,bufsize)) > 0 { ... }
  6. 关闭连接 RTMP_Close(rtmp); RTMP_Free(rtmp);

librtmp 推流

使用 librtmp 推流与拉流的流程差不多。刚开始时也是分配并初始化 RTMP, 只是在连接流媒体服务器时需要打开写开关。代码如下:

//if unable,the AMF command would be 'play' instead of 'publish'
RTMP_EnableWrite(rtmp);

if (!RTMP_Connect(rtmp,NULL)){
    ...
}

if (!RTMP_ConnectStream(rtmp,0)){
    ...
}

连接到流媒体服务器后,设置并初始化 RTMPPacket,RTMPPacket 里边存放要发送的数据包。代码如下:

packet=(RTMPPacket*)malloc(sizeof(RTMPPacket));
RTMPPacket_Alloc(packet,1024*64);
RTMPPacket_Reset(packet);

packet->m_hasAbsTimestamp = 0;
packet->m_nChannel = 0x04;
packet->m_nInfoField2 = rtmp->m_stream_id;

下面开始将 FLV 文件推到流媒体服务器上。首先,跳过 FLV 头。

//jump over FLV Header
fseek(fp,9,SEEK_SET);

FLV 文件格式是由 FLV Header + FLV Body组成的。其中 FLV Header一共 9 个字节。FLV Body 由 Tag Header + Tag Body 组成。

然后,在一个 while 循环中不停的分析Tag,从 Tag Header 和 Tag Body中取出数据,构造好 RTMPPacket 后 push 到流媒体服务器。

...

if(fread(packet->m_body,1,datalength,fp)!=datalength)
    break;

packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
packet->m_nTimeStamp = timestamp;
packet->m_packetType = type;
packet->m_nBodySize  = datalength;
pre_frame_time=timestamp;

if (!RTMP_IsConnected(rtmp)){
  ...
}
if (!RTMP_SendPacket(rtmp,packet,0)){
  ...
}

...

最后,将 flv 文件全部推送到媒体服务器后,关闭 rtmp 连接。

小结

本文首先介绍了如何在 Mac 上编译出可以在 iOS 上可运行的 librtmp 库,然后介绍了如何从流媒体服务器上拉流,最后介绍了如何使用 librtmp 将 flv 文件推送到流媒体服务器上。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 交叉编译 librtmp
  • 使用 librtmp 拉流
  • librtmp 推流
  • 小结
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档