请描述网站开发的一般流程图,做影视网站需要多大硬盘,南通网站排名公司,做湲网站文章目录 流程api核心代码muxer.hmuxer.cpp aac 和 h264 封装为视频流#xff0c;封装为c的Muxter类 流程 分配视频文件上下文 int Init(const char *url); 创建流#xff0c;赋值给视频的音频流和视频流 int AddStream(AVCodecContext *codec_ctx); 写视频流的head int Se… 文章目录 流程api核心代码muxer.hmuxer.cpp aac 和 h264 封装为视频流封装为c的Muxter类 流程 分配视频文件上下文 int Init(const char *url); 创建流赋值给视频的音频流和视频流 int AddStream(AVCodecContext *codec_ctx); 写视频流的head int SendHeader(); 写视频流的packet需要转换packet的pts和dts , 值为 原有pts * 编码时间基/ 视频流的时间基 int SendPacket(AVPacket *packet) 写视频流的trail int SendTrailer(); 释放资源 void DeInit();
api
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const // 时间基转换函数 , 计算结果为 a * bq / cq
核心代码
muxer.h
#ifndef MUXER_H
#define MUXER_H
#include iostream
extern C
{
#include libavformat/avformat.h
#include libavcodec/avcodec.h
}class Muxer
{
public:Muxer();~Muxer();// 输出文件 返回0值异常// 初始化int Init(const char *url);// 资源释放void DeInit();// 创建流int AddStream(AVCodecContext *codec_ctx);// 写流int SendHeader();int SendPacket(AVPacket *packet);int SendTrailer();int Open(); // avio open
private:AVFormatContext *fmt_ctx_ NULL;std::string url_ ;// 编码器上下文AVCodecContext *aud_codec_ctx_ NULL;AVStream *aud_stream_ NULL;AVCodecContext *vid_codec_ctx_ NULL;AVStream *vid_stream_ NULL;int audio_index_ -1;int video_index_ -1;
};#endif // MUXER_H
muxer.cpp #include muxer.hMuxer::Muxer()
{}Muxer::~Muxer()
{}int Muxer::Init(const char *url)
{int ret avformat_alloc_output_context2(fmt_ctx_, NULL, NULL,url);if(ret ! 0) {char errbuf[1024] {0};av_strerror(ret, errbuf, sizeof(errbuf) - 1);printf(avformat_alloc_output_context2 failed:%s\n, ret);return -1;}url_ url;return 0;
}void Muxer::DeInit()
{if(fmt_ctx_) {avformat_close_input(fmt_ctx_);}url_ ;aud_codec_ctx_ NULL;aud_stream_ NULL;audio_index_ -1;vid_codec_ctx_ NULL;vid_stream_ NULL;video_index_ -1;
}int Muxer::AddStream(AVCodecContext *codec_ctx)
{if(!fmt_ctx_) {printf(fmt ctx is NULL\n);return -1;}if(!codec_ctx) {printf(codec ctx is NULL\n);return -1;}AVStream *st avformat_new_stream(fmt_ctx_, NULL);if(!st) {printf(avformat_new_stream failed\n);return -1;}// st-codecpar-codec_tag 0;// 从编码器上下文复制, 根据提供的编解码器的值填充参数结构avcodec_parameters_from_context(st-codecpar, codec_ctx);av_dump_format(fmt_ctx_, 0, url_.c_str(), 1);// 判断当前的是视频流还是音频流if(codec_ctx-codec_type AVMEDIA_TYPE_AUDIO) {aud_codec_ctx_ codec_ctx;aud_stream_ st;audio_index_ st-index;} else if(codec_ctx-codec_type AVMEDIA_TYPE_VIDEO) {vid_codec_ctx_ codec_ctx;vid_stream_ st;video_index_ st-index;}return 0;
}int Muxer::SendHeader()
{if(!fmt_ctx_) {printf(fmt ctx is NULL\n);return -1;}int ret avformat_write_header(fmt_ctx_, NULL);if(ret ! 0) {char errbuf[1024] {0};av_strerror(ret, errbuf, sizeof(errbuf) - 1);printf(avformat_write_header failed:%s\n, ret);return -1;}return 0;
}int Muxer::SendPacket(AVPacket *packet)
{int stream_index packet-stream_index;if(!packet || packet-size 0 || !packet-data) {printf(packet is null\n);if(packet)av_packet_free(packet);return -1;}AVRational src_time_base; // 编码后的包AVRational dst_time_base; // mp4输出文件对应流的time_baseif(vid_stream_ vid_codec_ctx_ stream_index video_index_) {src_time_base vid_codec_ctx_-time_base;dst_time_base vid_stream_-time_base;} else if(aud_stream_ aud_codec_ctx_ stream_index audio_index_) {src_time_base aud_codec_ctx_-time_base;dst_time_base aud_stream_-time_base;}// 时间基转换// int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;// 时间基转换函数 a * bq / cqpacket-pts av_rescale_q(packet-pts, src_time_base, dst_time_base);packet-dts av_rescale_q(packet-dts, src_time_base, dst_time_base);packet-duration av_rescale_q(packet-duration, src_time_base, dst_time_base);int ret 0;//写packetret av_interleaved_write_frame(fmt_ctx_, packet); // 不是立即写入文件内部缓存主要是对pts进行排序// ret av_write_frame(fmt_ctx_, packet);av_packet_free(packet);if(ret 0) {return 0;}else {char errbuf[1024] {0};av_strerror(ret, errbuf, sizeof(errbuf) - 1);printf(avformat_write_header failed:%s\n, ret);return -1;}
}int Muxer::SendTrailer()
{if(!fmt_ctx_) {printf(fmt ctx is NULL\n);return -1;}int ret av_write_trailer(fmt_ctx_);if(ret ! 0) {char errbuf[1024] {0};av_strerror(ret, errbuf, sizeof(errbuf) - 1);printf(av_write_trailer failed:%s\n, ret);return -1;}return 0;
}