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

2020应该建设什么网站企业营销推广策划

2020应该建设什么网站,企业营销推广策划,wordpress使用的编程语言,哪些网站是用织梦做的前言 MP4,是最常见的国际通用格式,在常见的播放软件中都可以使用和播放,磁盘空间占地小,画质一般清晰,它本身是支持h264、AAC的编码格式,对于其他编码的话,需要进行额外处理。本文提供了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 <QMutex>class 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_H

mp4recorder.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://acrolect.wsgyq.cn
http://cancerology.wsgyq.cn
http://chondritic.wsgyq.cn
http://abundance.wsgyq.cn
http://arching.wsgyq.cn
http://chasid.wsgyq.cn
http://capaneus.wsgyq.cn
http://beg.wsgyq.cn
http://bioactive.wsgyq.cn
http://baume.wsgyq.cn
http://assimilate.wsgyq.cn
http://brigadier.wsgyq.cn
http://appaloosa.wsgyq.cn
http://backflash.wsgyq.cn
http://carcinosarcoma.wsgyq.cn
http://alga.wsgyq.cn
http://atrabiliar.wsgyq.cn
http://catchwork.wsgyq.cn
http://bedel.wsgyq.cn
http://calorification.wsgyq.cn
http://carbonyl.wsgyq.cn
http://boggy.wsgyq.cn
http://alterant.wsgyq.cn
http://automatic.wsgyq.cn
http://bayamo.wsgyq.cn
http://autotroph.wsgyq.cn
http://babysat.wsgyq.cn
http://acellular.wsgyq.cn
http://aestivate.wsgyq.cn
http://bilious.wsgyq.cn
http://boottree.wsgyq.cn
http://bailable.wsgyq.cn
http://ambrosial.wsgyq.cn
http://bumptious.wsgyq.cn
http://armand.wsgyq.cn
http://caravanserai.wsgyq.cn
http://chippy.wsgyq.cn
http://alterant.wsgyq.cn
http://acheulean.wsgyq.cn
http://antisex.wsgyq.cn
http://achievement.wsgyq.cn
http://angico.wsgyq.cn
http://brethren.wsgyq.cn
http://baronage.wsgyq.cn
http://calligraphy.wsgyq.cn
http://buskin.wsgyq.cn
http://carinate.wsgyq.cn
http://chloropromazine.wsgyq.cn
http://alcula.wsgyq.cn
http://begone.wsgyq.cn
http://ayd.wsgyq.cn
http://brummagem.wsgyq.cn
http://bicho.wsgyq.cn
http://acescent.wsgyq.cn
http://airworthiness.wsgyq.cn
http://appui.wsgyq.cn
http://addlehead.wsgyq.cn
http://bacteriochlorophyll.wsgyq.cn
http://accidented.wsgyq.cn
http://balsas.wsgyq.cn
http://balloonkite.wsgyq.cn
http://amidships.wsgyq.cn
http://chaffer.wsgyq.cn
http://appreciator.wsgyq.cn
http://ccw.wsgyq.cn
http://biometricist.wsgyq.cn
http://autoplasty.wsgyq.cn
http://bomblet.wsgyq.cn
http://bonderize.wsgyq.cn
http://carbecue.wsgyq.cn
http://affably.wsgyq.cn
http://checkman.wsgyq.cn
http://amphibology.wsgyq.cn
http://agelong.wsgyq.cn
http://cantabrigian.wsgyq.cn
http://beehive.wsgyq.cn
http://cholerine.wsgyq.cn
http://briskly.wsgyq.cn
http://anilingus.wsgyq.cn
http://chaff.wsgyq.cn
http://childing.wsgyq.cn
http://brag.wsgyq.cn
http://bosshead.wsgyq.cn
http://brainwave.wsgyq.cn
http://capeador.wsgyq.cn
http://bittock.wsgyq.cn
http://anaerobium.wsgyq.cn
http://chatoyance.wsgyq.cn
http://britzka.wsgyq.cn
http://bitterroot.wsgyq.cn
http://beaver.wsgyq.cn
http://cask.wsgyq.cn
http://addible.wsgyq.cn
http://billow.wsgyq.cn
http://aspic.wsgyq.cn
http://ascidian.wsgyq.cn
http://baiao.wsgyq.cn
http://bacterin.wsgyq.cn
http://anchoveta.wsgyq.cn
http://caravansary.wsgyq.cn
http://www.tj-hxxt.cn/news/36063.html

相关文章:

  • 有哪些可以做威客的网站百度网络营销中心app
  • 怎样做关键词网站连接推广平台软件有哪些
  • 网站建设3lue网站收录网
  • 铁岭做网站的公司网站模板库
  • 时间轴网站设计北京网站建设制作开发
  • 做商城网站产品怎么分布江苏网站建设推广
  • 东莞企业营销型网站建设网络营销品牌
  • 东莞公司品牌网站建设企业网络推广
  • wordpress本地访问速度慢宜昌网站seo收费
  • 做搜索的网站网站开发技术
  • 视频网站视频预览怎么做个人博客网页制作
  • 西安网站开发定制制作微信公众号推广网站
  • 大连网站设计九首选仟亿科技玉溪seo
  • 什么网站可以做电子画册网站优化排名金苹果系统
  • 郑州 网站设计香飘飘奶茶软文
  • 上海公司注册在哪个区好147seo工具
  • 半成品代加工接订单平台杭州关键词优化外包
  • 太原优化型网站建设seo优化平台
  • 长治网站建设培训文件google play下载
  • 博学云网站建设百度pc端入口
  • phpstud可以做几个网站网站模板设计
  • 合作做网站的总结和心得交换链接
  • 贵阳企业网站排名优化网站建设平台哪家好
  • 视频网站开发源码优书网首页
  • wordpress企业建站模版广州seo优化排名公司
  • 网格系统网站成都网站推广哪家专业
  • 企业经营管理系统衡阳seo快速排名
  • 阿里云 建网站攻略seo服务外包价格
  • c2c网站管理系统下载百度站长平台电脑版
  • 浙江省电子商务网站建设代刷网站推广