当前位置: 首页 > news >正文

做网投网站南京网站流量优化

做网投网站,南京网站流量优化,如何做好公司网站建设,中国企业网站开发前言 MP4#xff0c;是最常见的国际通用格式#xff0c;在常见的播放软件中都可以使用和播放#xff0c;磁盘空间占地小#xff0c;画质一般清晰#xff0c;它本身是支持h264、AAC的编码格式#xff0c;对于其他编码的话#xff0c;需要进行额外处理。本文提供了ffmpeg录…前言 MP4是最常见的国际通用格式在常见的播放软件中都可以使用和播放磁盘空间占地小画质一般清晰它本身是支持h264、AAC的编码格式对于其他编码的话需要进行额外处理。本文提供了ffmpeg录制mp4的封装代码经测试视频上它支持h264、h265编码音频支持了AAC、G711的aLaw、muLaw编码。对于以上编码的支持部分是需要修改ffmpeg的源码本文也有提供已编译好的ffmpeg以及说明源码上需要修改的地方。 一、时间戳处理 在mp4录制中有碰到一个问题即在录制实时流后用播放器进行播放播放时间没有从0秒开始。windows自带的media play播放时一开始都是静止的画面从第n秒后才开始正式播放用VLC可以直接跳到n秒进行播放。这个问题的原因是时间戳没有处理好需要记录下首帧指定首帧时间戳为0然后后续视频帧的时间戳等于当前帧的时间戳减去首帧时间戳。代码如下 二、添加h264、h265、AAC解码头信息 解码头信息是保存在解码器上下文AVCodecContext的extradata中这些信息包含h264的SPS、PPS头信息AAC的adts头信息h265的VPS、SPS、PPS我们需要使用比特流过滤器AVBitStreamFilter来为每一种格式添加相应的头部信息这样才能在解码器中正常进行解码。以下为添加解码头信息的相关代码     初始化时视频     循环读帧中视频     初始化时音频     循环读帧中音频 三、ffmpeg支持g711 aLaw muLaw 在ffmpeg源码movenc.c文件中找到mov_write_audio_tag函数修改以下 和在该文件中增加以下 muLaw修改类似它的MKTAG为 ‘u’,‘l’, ‘a’,‘w’。 四、代码分享 mp4recorder.h #ifndef MP4RECORDER_H #define MP4RECORDER_Hextern C {#include libavcodec/avcodec.h#include libavformat/avformat.h#include libavfilter/avfilter.h#include libswscale/swscale.h#include libavutil/frame.h#include libavutil/imgutils.h#include libavcodec/bsf.h }#include QObject #include QMutexclass mp4Recorder : public QObject {Q_OBJECT public:explicit mp4Recorder(QObject *parent nullptr);virtual ~mp4Recorder();bool Init(AVFormatContext *pIfmtCtx, int nCodecType, int nAudioCodecType, QString sFile);bool DeInit();bool isInit() {return m_bInit;}bool saveOneFrame(AVPacket pkt, int nCodecType, int nAudioCodecType);private:uint64_t m_nCounts;bool m_bFirstGoP;bool m_bInit;QString m_sRecordFile;AVFormatContext *m_pIfmtCtx;AVFormatContext *m_pOfmtCtx; // output stream format. copy from instream format.const AVOutputFormat *m_pOfmt; // save file format.QMutex m_lock;int64_t m_nVideoTimeStamp;int m_nVideoDuration;int m_nVideoIndex -1;int m_nAudioIndex -1;int m_nSpsPpsSize 0;AVBSFContext *m_pBsfc nullptr;AVBSFContext *m_pBsfcAAC nullptr;AVPacket *m_pktFilter nullptr;AVPacket *m_pktFilterAudio nullptr;int64_t m_nFirstVideoPts 0;int64_t m_nFirstAudioPts 0;bool m_bTransCode false;// stream map.int *m_pStreamMapping;int m_nMappingSize;};#endif // MP4RECORDER_Hmp4recorder.cpp #include mp4recorder.h #include commondef.h #include cteasyaacencoder.h#define TRANSCODE 0mp4Recorder::mp4Recorder(QObject *parent) : QObject(parent) {QMutexLocker guard(m_lock);m_sRecordFile.clear();m_pIfmtCtx nullptr;m_pOfmtCtx nullptr;m_pOfmt nullptr;m_pStreamMapping nullptr;m_nMappingSize 0;m_nCounts 0;m_bFirstGoP false;m_bInit false; }mp4Recorder::~mp4Recorder() {DeInit(); }bool mp4Recorder::Init(AVFormatContext *pIfmtCtx, int nCodecType, int nAudioCodecType, QString sFile) {QMutexLocker guard(m_lock);if(!pIfmtCtx || sFile.isEmpty()){MY_DEBUG sFile.isEmpty().;return false;}m_sRecordFile sFile;m_pIfmtCtx pIfmtCtx;QByteArray ba m_sRecordFile.toLatin1();const char* pOutFile ba.data();qDebug() pOutFile: pOutFile;unsigned i 0;int ret 0;int stream_index 0;// 1. create output contextavformat_alloc_output_context2(m_pOfmtCtx, nullptr, nullptr, pOutFile);if (!m_pOfmtCtx){MY_DEBUG Could not create output context.;ret AVERROR_UNKNOWN;goto end;}// 2. get memory.m_nMappingSize pIfmtCtx-nb_streams;m_pStreamMapping (int*)av_mallocz_array(m_nMappingSize, sizeof(*m_pStreamMapping));if (!m_pStreamMapping){MY_DEBUG av_mallocz_array fail.;ret AVERROR(ENOMEM);goto end;}// 3. copy steam information.m_pOfmt m_pOfmtCtx-oformat;for (i 0; i pIfmtCtx-nb_streams; i){AVStream *pOutStream;AVStream *pInStream pIfmtCtx-streams[i];AVCodecParameters *pInCodecpar pInStream-codecpar;if (pInCodecpar-codec_type ! AVMEDIA_TYPE_AUDIO pInCodecpar-codec_type ! AVMEDIA_TYPE_VIDEO pInCodecpar-codec_type ! AVMEDIA_TYPE_SUBTITLE){m_pStreamMapping[i] -1;continue;}if(pInCodecpar-codec_type AVMEDIA_TYPE_VIDEO){m_nVideoIndex i;//1.找到相应解码器的过滤器if(nCodecType AV_CODEC_ID_HEVC){const AVBitStreamFilter *bsf av_bsf_get_by_name(hevc_mp4toannexb);if (!bsf){MY_DEBUG av_bsf_get_by_name() video failed;return false;}//2.过滤器分配内存av_bsf_alloc(bsf, m_pBsfc);}else{const AVBitStreamFilter *bsf av_bsf_get_by_name(h264_mp4toannexb);if (!bsf){MY_DEBUG av_bsf_get_by_name() video failed;return false;}//2.过滤器分配内存av_bsf_alloc(bsf, m_pBsfc);}//3.添加解码器属性avcodec_parameters_copy(m_pBsfc-par_in, pInCodecpar);//4. 初始化过滤器上下文av_bsf_init(m_pBsfc);}else if(pInCodecpar-codec_type AVMEDIA_TYPE_AUDIO){m_nAudioIndex i;#if TRANSCODEif(nAudioCodecType AV_CODEC_ID_PCM_ALAW || nAudioCodecType AV_CODEC_ID_PCM_MULAW){MY_DEBUG ctEasyAACEncoder Init;if(nAudioCodecType AV_CODEC_ID_PCM_ALAW)ctEasyAACEncoder::getInstance().Init(Law_ALaw);elsectEasyAACEncoder::getInstance().Init(Law_ULaw);m_bTransCode true;}elsem_bTransCode false;#endifif(m_bTransCode || nAudioCodecType AV_CODEC_ID_AAC){//1. 找到相应解码器的过滤器const AVBitStreamFilter *bsf av_bsf_get_by_name(aac_adtstoasc);if (!bsf){MY_DEBUG av_bsf_get_by_name() audio failed;return false;}//2.过滤器分配内存av_bsf_alloc(bsf, m_pBsfcAAC);//3.添加解码器属性avcodec_parameters_copy(m_pBsfcAAC-par_in, pInCodecpar);//4. 初始化过滤器上下文av_bsf_init(m_pBsfcAAC);}#if TRANSCODEif(m_bTransCode)m_pBsfcAAC-par_in-codec_id AV_CODEC_ID_AAC; #endif}// fill the stream index.m_pStreamMapping[i] stream_index;// copy the new codec prameters.pOutStream avformat_new_stream(m_pOfmtCtx, nullptr);if (!pOutStream){MY_DEBUG Failed allocating output stream;ret AVERROR_UNKNOWN;goto end;}ret avcodec_parameters_copy(pOutStream-codecpar, pInCodecpar);if (ret 0){MY_DEBUG Failed to copy codec parameters;goto end;} #if TRANSCODEif(m_bTransCode pInCodecpar-codec_type AVMEDIA_TYPE_AUDIO)pOutStream-codecpar-codec_id AV_CODEC_ID_AAC; #endif//pOutStream-codecpar-bit_rate 2000000;//pOutStream-codecpar-codec_tag 0;}// 4. create MP4 header.if (!(m_pOfmt-flags AVFMT_NOFILE)) // network stream{ret avio_open(m_pOfmtCtx-pb, pOutFile, AVIO_FLAG_WRITE);if (ret 0){MY_DEBUG Could not open output file m_sRecordFile;goto end;}}// 5. write file header.ret avformat_write_header(m_pOfmtCtx, nullptr);if (ret 0){MY_DEBUG Error occurred when opening output file ret: ret;goto end;}m_pktFilter new AVPacket;av_init_packet(m_pktFilter);m_pktFilter-data NULL;m_pktFilter-size 0;m_pktFilterAudio new AVPacket;av_init_packet(m_pktFilterAudio);m_pktFilterAudio-data NULL;m_pktFilterAudio-size 0;m_nFirstVideoPts 0;m_nFirstAudioPts 0;m_bFirstGoP false;m_bInit true;m_nCounts 0;return true;end:DeInit();if (ret 0 ret ! AVERROR_EOF){MY_DEBUG Error occurred.;}return false; }bool mp4Recorder::DeInit() {// 1. save tail.if(m_bInit m_pOfmtCtx){av_write_trailer(m_pOfmtCtx);}m_bInit false;// 2. close outputif (m_pOfmtCtx !(m_pOfmt-flags AVFMT_NOFILE)){avio_closep(m_pOfmtCtx-pb);}// 3. free contex.if(m_pOfmtCtx){avformat_free_context(m_pOfmtCtx);m_pOfmtCtx nullptr;}av_freep(m_pStreamMapping);if(m_pBsfc){av_bsf_free(m_pBsfc);m_pBsfc nullptr;}if(m_pBsfcAAC){av_bsf_free(m_pBsfcAAC);m_pBsfcAAC nullptr;}#if TRANSCODEif(m_bTransCode){ctEasyAACEncoder::getInstance().DeInit();m_bTransCode false;} #endifreturn true; }bool mp4Recorder::saveOneFrame(AVPacket pkt, int nCodecType, int nAudioCodecType) {int ret 0;if(!m_bInit){return false;}AVStream *pInStream, *pOutStream;if(nCodecType AV_CODEC_ID_H264){if(m_bFirstGoP false){if(pkt.flags ! AV_PKT_FLAG_KEY){av_packet_unref(pkt);return false; // first frame must be Iframe.}else{m_bFirstGoP true;}}}pInStream m_pIfmtCtx-streams[pkt.stream_index];if (pkt.stream_index m_nMappingSize ||m_pStreamMapping[pkt.stream_index] 0){av_packet_unref(pkt);return true;}pkt.stream_index m_pStreamMapping[pkt.stream_index];pOutStream m_pOfmtCtx-streams[pkt.stream_index];if(pInStream-codecpar-codec_type ! AVMEDIA_TYPE_VIDEO pInStream-codecpar-codec_type ! AVMEDIA_TYPE_AUDIO){av_packet_unref(pkt);return false;}if(pInStream-codecpar-codec_type AVMEDIA_TYPE_VIDEO){av_bsf_send_packet(m_pBsfc, pkt);av_bsf_receive_packet(m_pBsfc, m_pktFilter);m_pktFilter-pts av_rescale_q_rnd(m_pktFilter-pts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilter-dts av_rescale_q_rnd(m_pktFilter-dts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilter-duration av_rescale_q_rnd(m_pktFilter-duration, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilter-stream_index pOutStream-index;//时间戳处理if(m_nFirstVideoPts 0){m_nFirstVideoPts m_pktFilter-pts;m_pktFilter-pts 0;m_pktFilter-dts 0;}else{m_pktFilter-pts m_pktFilter-pts - m_nFirstVideoPts;m_pktFilter-dts m_pktFilter-dts - m_nFirstVideoPts;}//av_packet_rescale_ts(pkt, pInStream-time_base, pOutStream-time_base);m_pktFilter-pos -1;m_pktFilter-flags | AV_PKT_FLAG_KEY;ret av_interleaved_write_frame(m_pOfmtCtx, m_pktFilter);av_packet_unref(pkt);if (ret 0){qDebug() Video Error muxing packet;}}else{ #if TRANSCODEif(m_bTransCode){AVPacket* pAACPkt av_packet_clone(pkt);if(ctEasyAACEncoder::getInstance().G711ToAAC(pkt.data, pkt.size, pAACPkt-data, pAACPkt-size) false){av_packet_unref(pkt);return false;}av_bsf_send_packet(m_pBsfcAAC, pAACPkt);av_bsf_receive_packet(m_pBsfcAAC, m_pktFilterAudio);}else #endifif(m_bTransCode || nAudioCodecType AV_CODEC_ID_AAC){av_bsf_send_packet(m_pBsfcAAC, pkt);av_bsf_receive_packet(m_pBsfcAAC, m_pktFilterAudio);m_pktFilterAudio-pts av_rescale_q_rnd(m_pktFilterAudio-pts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio-dts av_rescale_q_rnd(m_pktFilterAudio-dts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio-duration av_rescale_q_rnd(m_pktFilterAudio-duration, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio-stream_index pOutStream-index;//用差值作时间戳if(m_nFirstAudioPts 0){m_nFirstAudioPts m_pktFilterAudio-pts;m_pktFilterAudio-pts 0;m_pktFilterAudio-dts 0;}else{m_pktFilterAudio-pts m_pktFilterAudio-pts - m_nFirstAudioPts;m_pktFilterAudio-dts m_pktFilterAudio-dts - m_nFirstAudioPts;}m_pktFilterAudio-pos -1;m_pktFilterAudio-flags | AV_PKT_FLAG_KEY;ret av_interleaved_write_frame(m_pOfmtCtx, m_pktFilterAudio);}else{pkt.pts av_rescale_q_rnd(pkt.pts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);pkt.dts av_rescale_q_rnd(pkt.dts, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);pkt.duration av_rescale_q_rnd(pkt.duration, pInStream-time_base, pOutStream-time_base, AV_ROUND_NEAR_INF);pkt.stream_index pOutStream-index;//用差值作时间戳if(m_nFirstAudioPts 0){m_nFirstAudioPts pkt.pts;pkt.pts 0;pkt.dts 0;}else{pkt.pts pkt.pts - m_nFirstAudioPts;pkt.dts pkt.dts - m_nFirstAudioPts;}pkt.pos -1;pkt.flags | AV_PKT_FLAG_KEY;ret av_interleaved_write_frame(m_pOfmtCtx, pkt);}av_packet_unref(pkt);if (ret 0){qDebug() Audio Error muxing packet;}}return (ret 0); }四、ffmpeg库下载 链接地址https://download.csdn.net/download/linyibin_123/87542123
http://www.w-s-a.com/news/264906/

相关文章:

  • 做外贸的几个网站查询网域名解析
  • 酒泉如何做百度的网站seo研究中心好客站
  • 网站设计建设平台户县做网站
  • 一元云购网站开发wordpress博客空间
  • 深圳高端网站建设公司排名如何搭建局域网服务器
  • 照片管理网站模板高端网站开发哪家好
  • 黄冈网站制作wordpress为什么不能显示域名
  • 做网站设计怎么进企业电子商务网站建设与管理教材
  • 设计广告公司网站建设网站开发技术选择
  • 个人网站教程个人网站有必要备案吗
  • 网站建设推广好做吗黄浦企业网站制作
  • 怎样做28网站代理中山网站建设方案外包
  • vs2010做网站前台搭建小网站
  • 做视频必须知道的一些网站wordpress 标签鼠标滑过_弹出的title 代码美化
  • 怎么做室内设计公司网站电商运营培训视频课程
  • 昆明网站策划天津市建筑信息平台
  • 三亚放心游app官方网站wordpress 个人主题
  • 做简单的网站备案平台新增网站
  • 中国建设网站银行网络营销推广方案整合
  • 网站域名列表dede网站白屏
  • 站长工具一区品牌建设卓有成效
  • 电子商务网站建设案例wordpress批量编辑
  • 想代理个网站建设平台100个最佳市场营销案例
  • 钟表东莞网站建设石家庄做网站时光
  • 织梦 图片网站源码成都建设工程安监局网站
  • 做兼职的网站策划书湖北省建设工程造价信息网
  • 企业网站网址长期做网站应该购买稳定的空间
  • 网站静态化设计html5手机网站制作
  • 深圳最简单的网站建设家居网站建设全网营销
  • 如何取消网站备案佛山网站优化公司