上一篇对摄像头预览,拍照做了大概的介绍,现在已经可以拿到视频帧了,在加上 RTSP 实现,就是直播的雏形,当然还要加上一些 WEB 管理和手机平台的支援,就是一整套直播软件。

介绍一些基础概念:RTP RTSP RTMP

RTP 实时传输协议,RTMP 以前  flash 用的视频协议,RTSP 目前比较流行的 直播协议

H264 基础概念:SPS 、PSS 、NAl 、NALU、 I帧 P 帧B 帧、fps 、pts 、dts

SPS Sequence Parameter Set 序列参数设置  PPS Picture Parameter Set 图片参数设置

SPS PSS 在容器 mkv 文件中保存时仅存在于开头时不是每一帧都会附加,但是在 RTSP 实时直播时,需要填充到 sdp 传输。

用到的软件和第三方库:ffmpeg live555 VLC

VLC 全平台播放器,win ubuntu mac os android 各个平台都有,功能强大,UI美观,还没有广告。

live555 开源 RTP RTSP 项目

ffmpeg 开源编解码器,多种格式转换,加水印,ffplay 更是全能播放器(就是控制做的不行),解码器需要自行编译加入。

ffplay 在 win 上使用时,需要加一个环境变量,否则没声音 set SDL_AUDIODRIVER=directsound

1,在本机发布一个 ts 流,用 VLC 和 手机浏览器, 进行播放。

ffmpeg -i -.rm -profile:v baseline -level 3.0 -s 640x360 -start_number  -hls_time  -hls_list_size  -f hls -.m3u8

把 ffmpeg 拆分好的文件,复制到 webroot 目录里面,然后使用 VLC 播放,也可以通过 html5 的 video 在手机上播放,手机上浏览器支持 ts 流比较好

2,RTSP 流 使用 live555 发布

http://live555.com/liveMedia/public/ 下载源码,编译安装,不得不说有的时候在 ubuntu 上开发的确比 win 上简单。

下载解压后,执行 ./genMakefiles linux 在 make 会生成 mediaServer/live555MediaServer 运行它,在它的目录放一些文件,这里放的是 mkv 的文件,这里还写了支持的其它类型的文件。

然后使用 ffplay 进行播放。

使用 wireshark 抓包查看数据包

RTSP 文档 https://www.rfc-editor.org/rfc/rfc2326.html 自己对照着看吧,如果完全自己从0开发,这些是需要知道的。

3,H264 ACC 编码

要先找一些原始数据,才能开始编码。直接从 DirectShow 中,的确是可以拿到数据,每次启动什么的还是有点麻烦,所以先生成一些数据,使用 ffmpeg 提取视频为图片

ffmpeg -i .mp4 -r  -q:v  -f image2 image-%5d.jpg

从 1.mp4 中提取了图片,帧率是 25 。

win 平台下载编译好的 lib 比较省心 libffmpeg libjpeg

https://ffmpeg.zeranoe.com/builds/  下载 dev 、shared 2个,为啥要下载2个,因为这个运行的时候,需要 dll,(注意,里面没有包含 x264)

linux 可以自行编译,需要下载很多库 x264 x265 啥的。

参考例子 ffmpeg-4.1/doc/examples$

编译

gcc encode_video.c -lavcodec -lavutil  -o encode_video

gcc muxing.c -lavcodec -lavutil -lswscale -lswresample -lavformat -lm -o muxing

执行 ./encode_video 1.mp4 libx264  ./muxing 2.mp4

使用 ffplay 播放器打开

实际上这个是动的,不过 GIF 录的不好。

H264 中要求是 YUV420P 格式,JPG 默认解码 RGB  也可以解码为 JCS_YCbCr 。YCbCr 和 YUV 几种格式的区别,ffmpeg 中有以下几种:

AV_PIX_FMT_YUV444P

AV_PIX_FMT_YUV422P

AV_PIX_FMT_YUV420P

 //rgb24 to yun420p
sws_ctx = sws_getContext(frame->width, frame->height, AV_PIX_FMT_RGB24,
frame->width, frame->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC,
NULL,NULL,NULL); struct dirent **namelist;
int n; n = scandir(dir_path, &namelist, NULL, alphasort);
for(i = ; i < n; i++)
{
if( != strcmp(".", namelist[i]->d_name) && != strcmp("..", namelist[i]->d_name))
{
snprintf(file_image, sizeof(file_image), "%s/%s", dir_path, namelist[i]->d_name); printf("file_image:%s\n", file_image);
read_jpeg(file_image, &video_width, &video_height, &image_buff); uint8_t *indata[AV_NUM_DATA_POINTERS] = { };
indata[] = image_buff;
int inlinesize[AV_NUM_DATA_POINTERS] = { };
inlinesize[] = frame->width * ; ret = sws_scale(sws_ctx, indata, inlinesize, , frame->height, frame->data, frame->linesize); /* make sure the frame data is writable */
ret = av_frame_make_writable(frame);
if (ret < ) exit(); frame->pts = i; /* encode the image */
encode(c, frame, pkt, f); free(image_buff);
}
free(namelist[i]);
}
free(namelist);
sws_freeContext(sws_ctx); closedir(dir);

这个是 修改自  encode_video.c 把 上面拆分的 jpg 图片合成 264 编码,编译方式:gcc encode_video_h264.c -lavcodec -lavutil -lswscale -lswresample -lavformat -ljpeg

这里使用读取文件夹内的所有 jpg ,read_jpeg() 是一个用 libjpeg 实现的,得到 jpeg 解码 RGB 数据的方法,但是 编码器需要 YUV420P 所以使用 sws_scale 进行转换。

将转换好的 xin.264 文件复制到  mediaServer 下面,启动 live555MediaServer 用 VLC 播放。

vs2010 编译 live555 下载并解压 live.2020.03.06.tar.gz

方法1,编辑 win32config

TOOLS32 = c:\Program Files\DevStudio\Vc 修改为 vs 的路径 C:\Program Files\Microsoft Visual Studio 10.0\VC

LINK_OPTS_0 = $(linkdebug) msvcrt.lib

执行 genWindowsMakefiles

新建一个 vs_build.bat

call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
cd liveMedia
nmake /B -f liveMedia.mak
cd ../groupsock
nmake /B -f groupsock.mak
cd ../UsageEnvironment
nmake /B -f UsageEnvironment.mak
cd ../BasicUsageEnvironment
nmake /B -f BasicUsageEnvironment.mak
cd ../testProgs
nmake /B -f testProgs.mak
cd ../mediaServer
nmake /B -f mediaServer.mak

运行这个批处理,完成以后,就会生成 库文件和exe

新建一个空白的 vc++ 工程,复制,生成的头文件和库 和 testOnDemandRTSPServer.cpp 配置好工程,编译生成 exe 放个测试  test.264 运行,能正常播放。

方法2,直接使用 vs2010 新建一个 win32 项目 ,选择 静态库 ,无编译头

添加一些头文件。这里4个 lib 项目,合在一起了,添加一个 NO_OPENSSL 宏 禁用 openssl 。

编译出来了,比那个 方法1强多了,修改调试都方便。

编译 jpegsr6.zip  解压 jconfig.vc  改名为 jconfig.h  新建  vs_build.bat

 call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
nmake /f makefile.vc nodebug=

libjpeg.lib 和一些头文件

重新编序 ffmpeg 并加入 https://www.videolan.org/developers/x264.html

windows 下编译的问题:

1,找不到 dirent.h  解决方法,https://github.com/jacksoja/dirent 添加头文件

2,error C1083: 无法打开包括文件:“inttypes.h”: No such file or directory 解决方法, https://github.com/chemeris/msinttypes 添加头文件 删除 stdint.h

live555 源码添加 live 直播支持,以 h264 为例 H264VideoFileServerMediaSubsession

createNewStreamSource() 这里是生成 source 数据源的,里面使用一个 ByteStreamFileSource 进行构造。

Medium => MediaSource => FramedSource => FramedFileSource => ByteStreamFileSource => File

Medium => MediaSource => FramedSource => FramedFilter => MPEGVideoStreamFramer => H264or5VideoStreamFramer => H264VideoStreamFramer => ByteStreamFileSource

添加为 H264VideoStreamFramer 从 实时流中读取数据的方法。

添加类  class LiveStreamH264Source: public FramedSource 用来提供数据 ,提供数据录入,数据读出,数据缓存。

添加类  H264VideoLiveFramer: public MPEGVideoStreamFramer 用来处理 source 获取 sps pps ,sdp

添加类  class H264VideoLiveMediaSubsession: public OnDemandServerMediaSubsession 用来管理会话

重新 编译运行

新添加的 live h264 已经出来了 ,重新实现 LiveStreamH264Source 中提供,读流,写流的操作方法即可。

视频帧 RGB 转为 H264 在填充流,参考上面的 RGB 编码 h264。

总结:

ffmpeg 实现 RGB 的 h264编码 和 PCM aac 编码

DirectShow 实现 windows 平台下,视频帧图像采集,音频 PCM 录制

送到 live555 通过 RTSP RTP 传输,在理想点就是实现 P2P 以减少服务器压力。

最终成果 gif 动画:

VLC 播放的有点色块,ffplay 的没事。

后记:

为啥图像是倒的?

这说明真的是用 DirectShow 做的,SampleGrabberCallback::BufferCB 采集到的数据对 BMP 亲合力比较强, 而 BMP 是比左下角开始扫的,而且每行做了4整数对齐。

解决方法是吗? 多简单,把摄像头反着装就行了,哈哈。

副产品,基于 SDL2 的查看器,调节正常了

开发RTSP 直播软件 H264 AAC 编码的更多相关文章

  1. 直播软件开发关于Android、iOS中的视频采集步骤

    很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...

  2. 公布一个软件,轻新视频录播程序,H264/AAC录制视音频,保存FLV,支持RTMP直播

    已经上传到CSDN,下载地址:http://download.csdn.net/detail/avsuper/7421647,不要钱滴,嘿嘿... 本程序能够把摄像头视频和麦克风音频,录制为FLV文件 ...

  3. C++实现RTMP协议发送H.264编码及AAC编码的直播软件开发音视频

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...

  4. 【视频开发】【Live555】通过live555实现H264 RTSP直播

    前面的文章中介绍了<H264视频通过RTMP流直播>,下面将介绍一下如何将H264实时视频通过RTSP直播. 实现思路是将视频流发送给live555, 由live555来实现H264数据流 ...

  5. 采集音频和摄像头视频并实时H264编码及AAC编码[转]

    0. 前言 我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法.那种方法有一些局限性,不适合实时性质的应用,如:视频会议.视频聊天.视频监控等.本文所使用的技术, ...

  6. RTMP协议发送H.264编码及AAC编码的音视频,实现摄像头直播

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...

  7. 采集音频和摄像头视频并实时H264编码及AAC编码

    转自:http://www.cnblogs.com/haibindev/archive/2011/11/10/2244442.html 0. 前言 我在前两篇文章中写了DirectShow捕获音视频然 ...

  8. 【Android 直播软件开发:音视频硬解码篇】

    开篇 炙手可热,望而生畏的音视频开发 时至今日,短视频App可谓是如日中天,一片兴兴向荣.随着短视频的兴起,音视频开发也越来越受到重视,但是由于音视频开发涉及知识面比较广,入门门槛相对较高,让许许多多 ...

  9. send/receive h264/aac file/data by rtp/rtsp over udp/tcp

    一.安装一些必要的调试工具 1.vlc安装sudo apt-get install vlcsudo apt-get install vlc-nox 2.ffmpeg安装,带ffplay,ffplay依 ...

随机推荐

  1. es 查询分词字段为空的数据

    { "query": { "bool" : { "filter" : { "script" : { "scri ...

  2. 对Java8新的日期时间类的学习(二)

    示例11 在Java中如何判断某个日期是在另一个日期的前面还是后面 这也是实际项目中常见的一个任务.你怎么判断某个日期是在另一个日期的前面还是后面,或者正好相等呢?在Java 8中,LocalDate ...

  3. deeplearning.ai 改善深层神经网络 week1 深度学习的实用层面

    1. 应用机器学习是高度依赖迭代尝试的,不要指望一蹴而就,必须不断调参数看结果,根据结果再继续调参数. 2. 数据集分成训练集(training set).验证集(validation/develop ...

  4. 渗透利器-BadUSB 控制外网主机详解 Teensy2.0++

    准备工作 一块 Teensy2.0++ 的板子(淘宝一搜就有) Arduino编译器 1.8.7版本下载连接:arduino下载地址 Teensy插件 下载连接:Teensy下载地址 [外链图片转存失 ...

  5. leetcode第24题:两两交换链表中的节点

    通过分析,这属于数据结构类型题目,但涉及到多次交换,也需要算法知识. 首先,我想的是,将链表中节点相互交换. class Solution: def swapPairs(self, head: Lis ...

  6. MyBatis学习笔记二:MyBatis生产中使用环境搭建

    这里是在上一个环境的基础上修改的,这里就不在给出所有的配置,只给出哪里修改的配置 1.修改POJO对象为注解方式 2.创建Dao层接口 package com.orange.dao; import c ...

  7. Nginx笔记总结一:基本安装和配置

    1. Nginx安装 下载地址和安装依赖包 http://nginx.org/download/nginx-1.9.14.tar.gz yum -y install pcre pcre-devel z ...

  8. 我的第一个Quartz代码

    创建Maven项目   打开Eclipse->File->Project->Maven ->Maven Project直接下一步输入Group Id和Artifact Id , ...

  9. 吴裕雄--天生自然 R语言开发学习:时间序列(续三)

    #-----------------------------------------# # R in Action (2nd ed): Chapter 15 # # Time series # # r ...

  10. Java Timer和TimerTask

    Timer是JDK中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的任务,可以指定一次或多次. TimerTask是一个实现了Runnable接口的抽象类,代表一个可被执行的任 ...