建站公司 商城,工程合同范本通用版,河北建设工程信息网换成什么网址了,做效果图需要提供什么一、前言 目前市面上有很多开源的流媒体服务器解决方案#xff0c;常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca。这几种的对比如下#xff1a; #xff08;本图来源#xff1a;https://www.ngui.cc/zz/1781086.html?actiononClick#xff09;
二、SRS的介绍 SRS常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca。这几种的对比如下 本图来源https://www.ngui.cc/zz/1781086.html?actiononClick
二、SRS的介绍 SRSSimple Real-time Server是一个开源的流媒体服务器它支持RTMP、HLS、HTTP-FLV等多种流媒体协议。SRS提供了丰富的功能包括推流、拉流、转码、录制、转发等并且具有高性能、低延迟的特点。使用SRS可以搭建自己的流媒体服务器实现音视频的实时传输和播放。你可以通过SRS推送音视频流到服务器也可以从SRS服务器拉取音视频流进行播放或者转发给其他客户端。SRS支持多线程推拉流可以利用多核处理器的优势提高处理能力和并发性能。在使用多线程推拉流时需要注意线程同步和数据共享的问题。
三、SRS的搭建
3.1 下载
虚拟机环境CentOS 7 64位
SRS下载地址https://gitcode.net/mirrors/ossrs SRS 4.0以上版本,4.0版本以下不支持GB/28181协议
3.2 配置、编译、运行
下载后解压到CentOS 7目录下注意不要在共享目录下操作不然会出现ln软链接错误问题。
1执行配置命令
cd srs/trunk
./configure2执行编译命令
make3执行运行命令
./etc/init.d/srs start配置文件位置在conf/srs.conf可修改配置文件内容
4检查srs服务启动是否正常
ps -ef | grep srs3.3 网页登录
默认端口8080 红框中的为推流地址
四、QT下推流客户端 本客户端基于我的博客https://blog.csdn.net/linyibin_123/article/details/132107948 开发的播放器下新增RTMP推流。 播放器可以支持软硬解码截图、录像等功能详细功能看该博客。本客户端支持读取文件解码后推流也支持拉取网络流解码后进行推流。推流地址为前面搭建的RTMP流媒体服务器推流成功后通过VLC播放器从RTMP服务器上拉流下来播放。
4.1 读取本地文件解码后推流 4.2 拉取网络流解码后推流 4.3 相关代码
初始化推流
bool ctFFmpeg::initPushStream()
{if(m_bEnablePush){int nRet avformat_alloc_output_context2(m_pOfmtCtx, nullptr, flv, m_sRtmpServerAddr.toUtf8().data());if(!m_pOfmtCtx || nRet 0){MY_DEBUG avformat_alloc_output_context2 failed;return false;}m_pOvCodec avcodec_find_encoder(AV_CODEC_ID_H264);if(!m_pOvCodec){MY_DEBUG avcodec_find_encoder failed;return false;}m_pOvCodecCtx avcodec_alloc_context3(m_pOvCodec);if(!m_pOvCodecCtx){MY_DEBUG avcodec_alloc_context3 failed;return false;}m_pOvCodecCtx-pix_fmt AV_PIX_FMT_YUV420P;m_pOvCodecCtx-width m_nVideoW;m_pOvCodecCtx-height m_nVideoH;m_pOvCodecCtx-time_base.num 1;m_pOvCodecCtx-time_base.den 25;m_pOvCodecCtx-bit_rate 300000;m_pOvCodecCtx-gop_size 250;//Some formats want stream headers to be separate.if (m_pOfmtCtx-oformat-flags AVFMT_GLOBALHEADER)m_pOvCodecCtx-flags | AV_CODEC_FLAG_GLOBAL_HEADER;m_pOvCodecCtx-qmin 10;m_pOvCodecCtx-qmax 51;m_pOvCodecCtx-max_b_frames 0;AVDictionary *param 0;av_dict_set(param, preset, fast, 0);av_dict_set(param, tune, zerolatency, 0);if (avcodec_open2(m_pOvCodecCtx, m_pOvCodec, param) 0){MY_DEBUG avcodec_open2 failed.;return false;}m_pVideoSt avformat_new_stream(m_pOfmtCtx, m_pOvCodec);if (nullptr m_pVideoSt){MY_DEBUG avformat_new_stream failed.;return false;}m_pVideoSt-time_base.num 1;m_pVideoSt-time_base.den 30;avcodec_parameters_from_context(m_pVideoSt-codecpar, m_pOvCodecCtx);av_dump_format(m_pOfmtCtx, 0, m_sRtmpServerAddr.toLatin1().data(), 1);//Open output URLif (!(m_pOfmtCtx-oformat-flags AVFMT_NOFILE)){nRet avio_open(m_pOfmtCtx-pb, m_sRtmpServerAddr.toLatin1().data(), AVIO_FLAG_READ_WRITE);if (nRet 0){MY_DEBUG avio_open failed. url: m_sRtmpServerAddr;return false;}}m_pOfmtCtx-video_codec_id m_pOfmtCtx-oformat-video_codec;nRet avformat_write_header(m_pOfmtCtx, NULL);if (nRet 0){MY_DEBUG avformat_write_header failed. nRet nRet;return false;}m_pOutFrameYUV av_frame_alloc();int nBufferSize av_image_get_buffer_size(AV_PIX_FMT_YUV420P, m_nVideoW, m_nVideoH, 1);m_pOutDstBuffer (unsigned char*)av_malloc(nBufferSize);if (!m_pOutDstBuffer){return false;}MY_DEBUG storeAvFrame 111;nRet av_image_fill_arrays(m_pOutFrameYUV-data, m_pOutFrameYUV-linesize,m_pOutDstBuffer, AV_PIX_FMT_YUV420P, m_nVideoW, m_nVideoH, 1);if(nRet 0){return false;}m_pImgConvertCtx sws_getContext(m_pVideoCodecCxt-width, m_pVideoCodecCxt-height,m_pVideoCodecCxt-pix_fmt, m_pVideoCodecCxt-width,m_pVideoCodecCxt-height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);m_nStartTime av_gettime();m_nFramecnt 0;return true;}return false;
}推流过程
void ctFFmpeg::pushStream()
{if(m_bEnablePush m_bSupportPush m_pYuvFrame){sws_scale(m_pImgConvertCtx, (const uint8_t* const*)m_pYuvFrame-data, m_pYuvFrame-linesize, 0,m_pVideoCodecCxt-height, m_pOutFrameYUV-data, m_pOutFrameYUV-linesize);m_pOutFrameYUV-width m_pYuvFrame-width;m_pOutFrameYUV-height m_pYuvFrame-height;m_pOutFrameYUV-format AV_PIX_FMT_YUV420P;m_encPkt.data NULL;m_encPkt.size 0;av_init_packet(m_encPkt);int nRet avcodec_send_frame(m_pOvCodecCtx, m_pOutFrameYUV);while(nRet 0){nRet avcodec_receive_packet(m_pOvCodecCtx, m_encPkt);if (nRet AVERROR(EAGAIN) || nRet AVERROR_EOF || nRet 0){//MY_DEBUG avcodec_receive_packet nRet AVERROR(EAGAIN) || nRet AVERROR_EOF;break;}m_nFramecnt;m_encPkt.stream_index m_pVideoSt-index;//av_packet_rescale_ts(pkt, m_pOvCodecCtx-time_base, m_pVideoSt-time_base);AVRational time_base m_pOfmtCtx-streams[0]-time_base;//{ 1, 1000 };AVRational time_base_q {1, AV_TIME_BASE};AVRational rFramerate1 m_pAVFmtCxt-streams[0]-r_frame_rate;int64_t nCalcDuration (double)(AV_TIME_BASE)*(1 / av_q2d(rFramerate1)); //内部时间戳//Parametersm_encPkt.pts av_rescale_q(m_nFramecnt*nCalcDuration, time_base_q, time_base);m_encPkt.dts m_encPkt.pts;m_encPkt.duration av_rescale_q(nCalcDuration, time_base_q, time_base);m_encPkt.pos -1;//MY_DEBUG m_encPkt.pts: m_encPkt.pts;int64_t pts_time av_rescale_q(m_encPkt.pts, time_base, time_base_q);int64_t now_time av_gettime() - m_nStartTime;if ((pts_time now_time))av_usleep(pts_time - now_time);nRet av_interleaved_write_frame(m_pOfmtCtx, m_encPkt);if(nRet 0){MY_DEBUG av_interleaved_write_frame fail nRet: nRet;}av_packet_unref(m_encPkt);}}
}结束推流
void ctFFmpeg::endPushStream()
{if(m_bEnablePush m_bSupportPush){av_write_trailer(m_pOfmtCtx);if (m_pOfmtCtx !(m_pOfmtCtx-oformat-flags AVFMT_NOFILE))avio_close(m_pOfmtCtx-pb);avformat_free_context(m_pOfmtCtx);if(nullptr ! m_pOvCodecCtx){avcodec_free_context(m_pOvCodecCtx);m_pOvCodecCtx nullptr;}if(m_pOutDstBuffer)av_free(m_pOutDstBuffer);}
}五、客户端下载
https://download.csdn.net/download/linyibin_123/88237527