1.

LiveVideoCoreSDK

AudioUnitRender ==> MicSource::inputCallback ==> GenericAudioMixer::pushBuffer

GenericAudioMixer::mixThread() ==> AACEncode::pushBuffer ==> Split::pushBuffer ==> AACPacketizer::pushBuffer ==> LibRtmpSessionMgr::pushBuffer

http://www.jianshu.com/p/5b1341e97757

服务器 http://www.cnblogs.com/damiao/p/5231221.html

brew install ffmpeg --with-ffplay 

http://blog.csdn.net/charleslei/article/details/72462791

- (void)didProcessFrame:(CMSampleBufferRef)sampleBuffer
{
if(mVideoFilterView){
dispatch_async(dispatch_get_main_queue(), ^{
// if (self.cameraState == VCCameraStateFront) {
// mVideoFilterView.mirror = YES;
// } else {
// mVideoFilterView.mirror = NO;
// }
[mVideoFilterView renderFrame:sampleBuffer];
});
CVPixelBufferRef pixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer);
m_cameraSource->bufferCaptured(pixelBufferRef);
}
if(self.rtmpSessionState == kVCSessionStateNone) {
self.rtmpSessionState = kVCSessionStatePreviewStarted;
}
}

==> m_cameraSource->setOutput(m_videoSplit)

==> m_videoSplit->setOutput(m_h264Encoder);

==> m_h264Encoder->setOutput(m_h264Split);

==> m_h264Split->setOutput(m_h264Packetizer);

==> m_h264Packetizer->setOutput(m_outputSession);

void IOSRTMPSession::pushBuffer(const uint8_t* const data, size_t size, IMetadata& metadata){

        dispatch_semaphore_wait(m_lock, DISPATCH_TIME_FOREVER);
if (!m_iConnectedFlag) {
dispatch_semaphore_signal(m_lock);
return ;
}
dispatch_semaphore_signal(m_lock); const IOSRTMPMetadata_t inMetadata = static_cast<const IOSRTMPMetadata_t&>(metadata);
unsigned int uiMsgTypeId = inMetadata.getData<kIOSRTMPMetadataMsgTypeId>();
if((RTMP_PT_AUDIO != uiMsgTypeId) && (RTMP_PT_VIDEO != uiMsgTypeId)){
return;
} char* pSendBuff = (char*)malloc(size);
if (pSendBuff == NULL) {
printf("malloc pSendBuff failed\n");
return;
}
memcpy(pSendBuff, data, size);
int dts = inMetadata.getData<kIOSRTMPMetadataTimestamp>();
int pts = inMetadata.pts; int iret = ;
if(RTMP_PT_AUDIO == uiMsgTypeId){
iret = Librtmp_PutAudioBuffer(pSendBuff, (int)size, dts);
}else if (RTMP_PT_VIDEO == uiMsgTypeId){
iret = Librtmp_PutVideoBuffer(pSendBuff, (int)size , pts, pts);
} if (iret != ) {
printf("\n put buffer error.\n");
} free(pSendBuff); }

2.

推流流程

使用rtmp协议(其他协议也类似)推流的大体流程如下:

  1. 通过系统相机捕获视频及声音,该美颜的美颜,该滤镜的滤镜。
  2. 捕获的视频帧为yuv格式,音频帧为pcm格式。
  3. 将捕获的音视频数据,传入一个串行队列(编码队列),在队列中进行编码操作。
  4. 将yuv格式视频数据,转成h264格式视频帧;将pcm格式音频数据,转成aac格式音频帧。
  5. 将转好的h264及aac格式数据,转成flv视频帧。放入编码缓冲区,待发送。继续获取视频帧并编码。
  6. 建立rtmp连接到服务器,成功后,创建另一个串行队列(发送队列)。
  7. rtmp协议,需要在首帧发送 sps/pps和AudioSpecificConfig这2种特别的帧数据。
  8. 发送了首帧之后,发送队列不停从编码队列中获取flv视频帧,发送至rtmp服务端。
  9. 结束直播,关闭推流,释放资源。

https://www.jianshu.com/p/77fea6e0eccb

 3.yuv
 
a.
 
https://www.jianshu.com/p/e09b14616d99
b.
做到这里,基本的问题都解决了,视频可以正常渲染了;不过还有一个稍令人不悦的小问题,即app被切到后台再切回来时,由于这个时候AVSampleBufferDisplayLayer已经失效,所以这个时候渲染的view会是黑屏,这会有一到两秒的时间,直到layer重新建立好并开始渲染。那怎么让这个时候不出现黑屏呢?就需要前面提到的UIImageView
 
    @synchronized(self) {
if (self.previousPixelBuffer){
CFRelease(self.previousPixelBuffer);
self.previousPixelBuffer = nil;
}
self.previousPixelBuffer = CFRetain(pixelBuffer);
}
- (void)didResignActive{
NSLog(@"resign active");
[self setupPlayerBackgroundImage];
} - (void) setupPlayerBackgroundImage{
if (self.isVideoHWDecoderEnable){
@synchronized(self) {
if (self.previousPixelBuffer){
self.image = [self getUIImageFromPixelBuffer:self.previousPixelBuffer];
CFRelease(self.previousPixelBuffer);
self.previousPixelBuffer = nil;
}
}
}
} - (UIImage*)getUIImageFromPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
UIImage *uiImage = nil;
if (pixelBuffer){
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
uiImage = [UIImage imageWithCIImage:ciImage];
UIGraphicsBeginImageContext(self.bounds.size);
[uiImage drawInRect:self.bounds];
uiImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return uiImage;
}
 
https://blog.csdn.net/fernandowei/article/details/52179631
https://blog.csdn.net/fernandowei/article/details/52180840
http://blog.easemob.com/?p=277
https://www.jianshu.com/p/d5489a8fe2a9
 

4.std:thread

    void
GLESVideoMixer::start() {
m_mixThread = std::thread([this](){ this->mixThread(); });
}

https://www.github.com/runner365/LiveVideoCoreSDK/

3.ijkplayer

http://www.jianshu.com/p/a7d9ed02cf40











第11月第3天 直播 rtmp yuv的更多相关文章

  1. 11月30日《奥威Power-BI智能分析报表制作方法》腾讯课堂开课啦

    这么快一周就过去了,奥威公开课又要与大家见面咯,上节课老师教的三种报表集成方法你们都掌握了吗?大家都知道,学习的结果在于实际应用,想要熟练掌握新内容的要点就在于去应用它.正是基于这一要点,每一期的课程 ...

  2. 11月23日《奥威Power-BI报表集成到其他系统》腾讯课堂开课啦

    听说明天全国各地区都要冷到爆了,要是天气冷到可以放假就好了.想象一下大冷天的一定要在被窝里度过才对嘛,索性明天晚上来个相约吧,相约在被窝里看奥威Power-BI公开课如何?        上周奥威公开 ...

  3. 11月16日《奥威Power-BI基于SQL的存储过程及自定义SQL脚本制作报表》腾讯课堂开课啦

           上周的课程<奥威Power-BI vs微软Power BI>带同学们全面认识了两个Power-BI的使用情况,同学们已经迫不及待想知道这周的学习内容了吧!这周的课程关键词—— ...

  4. 11月09日《奥威Power-BI vs微软Power BI》腾讯课堂开课啦

    上过奥威公开课的同学可能有一个疑问:奥威Power-BI和微软Power BI是同一个吗,为什么叫同样的名字?正如这个世界上有很多个John.Jack.Marry…一样,奥威Power-BI和微软Po ...

  5. Android 如何直播RTMP流

    在android上,视频/音频流直播是极少有人关注的一部分.每当我们讨论流媒体,RTMP(Real Time Messaging Protocol)是不可或缺的.RTMP是一个基本的视频/音频直播流协 ...

  6. 【阿里聚安全·安全周刊】阿里双11技术十二讲直播预约|AWS S3配置错误曝光NSA陆军机密文件

    关键词:阿里双11技术十二讲直播丨雪人计划丨亚马逊AWS S3配置错误丨2018威胁预测丨MacOS漏洞丨智能风控平台MTEE3丨黑客窃取<权利的游戏>剧本|Android 8.1   本 ...

  7. Azure 11 月新公布

    Azure 11 月新发布:Apple FairPlay Streaming, 应用服务(App Service), 虚拟机规模集(VMSS) Azure 媒体服务的 Apple FairPlay S ...

  8. 「P4996」「洛谷11月月赛」 咕咕咕(数论

    题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...

  9. 11月1号开学! 《jmeter性能测试实战》崭新亮相!

    课程介绍 第10期<jmeter性能测试实战>课程,11月2号开学!全新改版,和之前的课程框架完全不同 主讲老师:飞天小子 上课方式:每周六周日晚8点到10点,QQ群视频在线直播教学 本期 ...

随机推荐

  1. 微软职位内部推荐-Senior Software Development Engineer_Commerce

    微软近期Open的职位: Are you looking for a high impact project that involves processing of billions of dolla ...

  2. PAT甲题题解-1031. Hello World for U (20)-字符串处理,水

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  3. PAT甲题题解-1044. Shopping in Mars (25)-水题

    n,m然后给出n个数让你求所有存在的区间[l,r],使得a[l]~a[r]的和为m并且按l的大小顺序输出对应区间.如果不存在和为m的区间段,则输出a[l]~a[r]-m最小的区间段方案. 如果两层fo ...

  4. Daily Scrum NO.6

    会议概况 这两日又是由于编译deadline和数据库课程设计使得我们的进度进行缓慢.但是项目的进程仍然在可掌控的范围之内,时间虽然紧,但是应该最终能够实现Beta版本. 这次会议我们总结了之前5个正常 ...

  5. Day Six

    站立式会议 站立式会议内容总结 442 今天:实现计划界面的逻辑 遇到的问题:模态框问题 明天:解决上面问题,开始使用动态数据 331 今天:点击添加找到文件 遇到问题:找到文件在app的引入实现 明 ...

  6. 第三个Sprint ------第一天

    Github账户: 账户名称:kangqu Github地址: https://github.com/kangqu/country.git Github网站全英文,表示鸭梨山大...

  7. (改进)Python语言实现词频统计

    需求: 1.设计一个词频统计的程序. 2.英语文章中包含的英语标点符号不计入统计. 3.将统计结果按照单词的出现频率由大到小进行排序. 设计: 1.基本功能和用法会在程序中进行提示. 2.原理是利用分 ...

  8. Jquery 获取屏幕及滑块及元素的高度及距离

    alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(document).height()); //浏览器时下窗口文档的高度 alert($(docum ...

  9. 一本通1669S-Nim

    1669:S-Nim [输入样例] 2 2 5 3 2 5 12 3 2 4 7 4 2 3 7 12 5 1 2 3 4 5 3 2 5 12 3 2 4 7 4 2 3 7 12 0 [输出样例] ...

  10. Java学习之静态代码块

    一.static(在方法区有一块固定的存储区域,由于优先于对象存在,所以可以被所有对象共享) 在定义方法的时候你写main方法的类加static, 写普通类的写方法的时候就不要加static 1.st ...