使用Librtmp进行的简单推流
一、整体流程
1、建立Rtmp连接
2、发送Audio Header 和Video Header
3、发送Audio和Video数据包
二、时间戳处理
需要注意的是,无论是发送视频数据包还是音频数据包,时间戳一定要是递增的,否则会出现音频卡顿,视频闪烁一类的异常情况。
下面是packet时间戳的伪代码:
double m_TimeStamp = 0;
void Send_Audio()
{if(m_TimeStamp == 0) m_TimeStamp = GetTickCount64();double TimeStamp = GetTickCount64() - m_TimeStamp;SendAudioPacket(TimeStamp);
}
void Send_Video()
{if(m_TimeStamp == 0) m_TimeStamp = GetTickCount64();double TimeStamp = GetTickCount64() - m_TimeStamp;SendVideoPacket(TimeStamp);
}
下面是构造数据包的代码示例:
if(nPacketType == RTMP_PACKET_TYPE_AUDIO){packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;packet.m_packetType = RTMP_PACKET_TYPE_AUDIO;packet.m_hasAbsTimestamp = 0;packet.m_nChannel = STREAM_CHANNEL_AUDIO;packet.m_nTimeStamp = nTimestamp;packet.m_nInfoField2 = m_pRtmp->m_stream_id;packet.m_nBodySize = size;}else if(nPacketType == RTMP_PACKET_TYPE_VIDEO){packet.m_headerType = RTMP_PACKET_SIZE_LARGE;packet.m_packetType = nPacketType;packet.m_hasAbsTimestamp = 0;packet.m_nChannel = STREAM_CHANNEL_VIDEO;packet.m_nTimeStamp = nTimestamp;packet.m_nInfoField2 = m_pRtmp->m_stream_id;packet.m_nBodySize = size;}
下面是Audio Header部分的代码示例及解析
int RtmpStream::rtmp_audio_header(RtmpMetadata &pMetaData)
{RTMPPacket packet;RTMPPacket_Reset(&packet);RTMPPacket_Alloc(&packet, 4);//前4位 |1010| 代表音频数据编码类型为 AAC//接下来 2 位 |11| 表示采样率为 44kHz//接下来 1 位 |1| 表示采样点位数 16bit//最低 1 位 |1| 表示双声道。//(10101111)B = (AF)Hpacket.m_body[0] = 0xAF;//0x00表示传输的音频数据为Audio Sequence Header//如果是0x01表示发送的数据为音频data数据。packet.m_body[1] = 0x00;//AudioSpecificType 5bit AAC-LC=2 00010//samplingFrequencyIndex 4bit 48000=3 0011 44100=4 0100//channelConfiguration 4bit 单声道=1 0001 双声道=2 0010//frameL.engthFlag 1bit 标志位, 用于表明IMDCT窗口长度, 0//dependsOnCoreCoder 1bit 标志位, 表明是否依赖于corecoder, 0//extensionFlag 1bit 选择了AAC - LC, 这里必须为0//(00010 0011 0010 000)B = (1190)H/*//48000packet.m_body[2] = 0x11;packet.m_body[3] = 0x90;//44100packet.m_body[2] = 0x12;packet.m_body[3] = 0x10;*/packet.m_body[2] |= (1 << 4);//自适应单通道或双通道if (pMetaData.nAudioChannels == 1)packet.m_body[3] |= (1 << 3);else if (pMetaData.nAudioChannels == 2)packet.m_body[3] |= (1 << 4);//自适应采样频率32000、44100、48000if (pMetaData.nAudioSampleSize == 48000){packet.m_body[2] |= (1);packet.m_body[3] |= (1 << 7);}else if (pMetaData.nAudioSampleSize == 44100){packet.m_body[2] |= (1 << 1);}else if (pMetaData.nAudioSampleSize == 32000){packet.m_body[2] |= (1 << 1);packet.m_body[3] |= (1 << 7);}packet.m_headerType = RTMP_PACKET_SIZE_LARGE;packet.m_packetType = RTMP_PACKET_TYPE_AUDIO;packet.m_hasAbsTimestamp = 0;packet.m_nChannel = STREAM_CHANNEL_AUDIO;packet.m_nTimeStamp = 0;packet.m_nInfoField2 = m_pRtmp->m_stream_id;packet.m_nBodySize = 4;//调用发送接口int nRet;{std::lock_guard<std::mutex> lck(m_mtxRtmp);nRet = RTMP_SendPacket(m_pRtmp, &packet, TRUE);}RTMPPacket_Free(&packet);//释放内存 return nRet;
}
https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf
使用Librtmp进行的简单推流相关推荐
- java jni librtmp_编译Android平台libRTMP库
操作系统: Mac OSX NDK: android-ndk-r10e-darwin-x86_64 编译目标: librtmp.a librtmp.so 简介 Android 官方提供了三种编译方式, ...
- 雷霄骅开源视音频项目汇总
from: http://blog.csdn.net/leixiaohua1020/article/details/42658139# 作者:雷霄骅, 一个值得怀念的人 本文汇总一下自己视音频编解码学 ...
- [总结]RTMP流媒体技术零基础学习方法
本文主要总结一些我在学习RTMP流媒体技术过程中积累的经验.也为后来学习RTMP流媒体技术的人们一个参考.本文力图从简到难,循序渐进的介绍RTMP流媒体技术的方方面面,先从应用说起,逐步深化剖析相关工 ...
- FFMPEG开源音视频项目学习汇总
~非常感谢雷霄骅老师的无私帮助,本文转载自:http://blog.csdn.net/leixiaohua1020/article/details/42658139~ 本文汇总一下自己视音 ...
- 我的开源视音频项目汇总
本文汇总一下自己视音频编解码学习方面的开源项目.这些开源项目大体上可以分成专业领域程序,FFmpeg示例程序,FFmpeg移植程序,多媒体项目示例程序,视音频编解码原理学习工程几个类别.这些类别的详细 ...
- 3个平台下的ffmpeg——ffmpeg编译
3个平台下的ffmpeg--ffmpeg编译 ffmpeg编译 需要在3个平台(win\linux\arm)下使用ffmpeg的库,所以进行了ffmpeg的编译. 其中ffmpeg的编译也有许多依赖, ...
- “小程序+直播”怎样搅动音视频技术生态?
责编 / 王宇豪 策划 / LiveVideoStack 12月26日晚间,微信小程序开放了直播能力,并首先向社交.教育.医疗.政务民生.金融等五大应用场景开放.与原生App应用和基于浏览器的H5 ...
- nginx-rtmp多房间和授权实现
nginx-rtmp多房间和授权实现 本篇为nginx-rtmp的进阶篇,实现多房间直播和观看直播并且添加推流的授权验证(用java实现的授权验证).在阅读时您需要去看简单推流实现,传送门, 如果您已 ...
- 1小时学会:最简单的iOS直播推流(十)librtmp使用介绍
最简单的iOS 推流代码,视频捕获,软编码(faac,x264),硬编码(aac,h264),美颜,flv编码,rtmp协议,陆续更新代码解析,你想学的知识这里都有,愿意懂直播技术的同学快来看!! 源 ...
最新文章
- java对象的参数传递,对象类型的参数传递是什么意思
- mysql 速度优化
- 【翻译】QEMU内部机制:顶层概览
- Clonezilla制作镜像时报错:extfsclone.c:bitmap free count err解决办法
- Py之xlutils:xlutils的简介、安装、使用方法之详细攻略
- 我的大学到研究生自学 Java 之路,过程艰辛,不放弃,保持热情,最终发现我是这样拿到大厂 offer 的!...
- 编写一个弹出式菜单的shell程序_分享一个有趣的shell脚本--实现抓阄程序
- 关于 SAP Spartacus feature library 里的 _index.scss 文件,和神奇的下划线省略行为
- mongodb哪些情况适用内嵌,哪些情况适用引用
- 如果还不懂如何使用 Consumer 接口,就来看这篇!
- 马蜂窝等多家旅游平台针对肺炎疫情推出旅客保障措施
- 项目兼容ie8技术要点
- 【大数据课堂000】今天开课了每天更新一集
- python mvc框架django搭建项目_Django笔记1:基础:创建虚拟主机和新项目
- 中英文国家名及手机号码前缀
- CentOS 下编译安装AliSQL
- 利用java制作桌面应用程序_Java桌面应用
- GoogleVoice群发WhatsApp翻译谷歌语音消息自动群发
- 线上英语教学APP开源平台(定制制作)
- 快速实现抖音的分享登录(android)