最新要闻
- 联发科MT6825芯片组获上海MWC 2023亚洲突破性设备创新大奖!手机卫星可双向通信_焦点资讯
- 支持Type-C充电:英菲克F1无线鼠标24.9元抄底
- 天天热消息:做错N多年!央视科普:鸡蛋别再放到冰箱门上了
- 要求罚金30亿美元!Chatgpt涉嫌信息盗窃被起诉 全球视讯
- 官方辟谣激情誓师女生考508分:女生考了600多分 考得特别好 环球焦点
- 全球低水足迹倡议(LWFi)联盟扩容,伊利“双足迹”开启全链减碳新篇章_世界视点
- 新款2024MGCyberster泄露 当前热讯
- 天天快讯:暴露年龄!时隔16年 Office“大眼夹”回归Windows 11:功能焕然一新
- 16.5亿打造!《封神》妲己首次亮相引热议 网友称妆造诡异在拍画皮吗
- 苹果之后 三星被指侵犯加州理工Wi-Fi专利:索赔可达数十亿美元-世界新消息
- “快乐水”不快乐了!阿斯巴甜将被定为可能致癌物质|天天热资讯
- 华为发布F5.5G智简全光联接四大创新:万兆时代来了
- 讯息:大宗交易:蓝色光标成交6967.8万元,折价1.96%(06-29)
- 天天速读:高铁踹老头底被曝
- 如何使用 iOS 17 将照片变成 iMessage 贴纸
- 多家高校下月起停用微信支付 微信团队致歉:即刻修正
手机
光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯
搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注
- 光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯
- 搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注
- 视点!美国首位女总统即将诞生?拜登恐怕要提前下岗,美政坛迎来变局?
- 当前速递!用理想仪器实现更好的颗粒 德国新帕泰克亮相CPHI & PMEC China获好评
- 微粒贷怎么申请开通 开通方法如下
- 焦点简讯:心疼!这位40岁的云南缉毒警,已是满头白发
家电
如何将视频文件.h264和音频文件.mp3复用为输出文件output.mp4?
一.初始化复用器
(相关资料图)
在这个部分我们可以分三步进行:(1)打开输入视频文件上下文句柄 (2)打开输入音频文件上下文句柄 (3)打开输出文件上下文句柄
1.打开输入视频文件上下文句柄
在这一步,我们主要用到两个重要的函数:av_find_input_format()和avformat_open_input()。我们先调用av_find_input_format函数得到输入视频文件的格式,然后将该格式和视频文件的路径传入avformat_open_input()函数,就可以打开输入视频文件的上下文句柄。下面给出代码:
#define STREAM_FRAME_RATE 25static AVFormatContext *video_fmt_ctx= nullptr,*audio_fmt_ctx= nullptr,*output_fmt_ctx= nullptr;static AVPacket *pkt;static int32_t in_video_st_idx=-1,in_audio_st_idx=-1;static int32_t out_video_st_idx=-1,out_audio_st_idx=-1;static int32_t init_input_video(const char *video_input_file,const char *video_format){ int32_t result=0; const AVInputFormat *video_input_format= av_find_input_format(video_format); if(!video_input_format){ cerr<<"Error:av_find_input_format failed."<2.打开输入音频文件上下文句柄
打开输入音频文件上下文句柄的方法和上面的输入视频文件类似,直接上代码:
static int32_t init_input_audio(const char *audio_input_file,const char *audio_format){ int32_t result=0; const AVInputFormat *audio_input_format= av_find_input_format(audio_format); if(!audio_input_format){ cerr<<"Error:av_find_input_format failed."<3.打开输出文件上下文句柄
打开输出文件上下文句柄需要调用函数avformat_alloc_output_context2(),在创建了输出文件上下文句柄后,我们需要添加一路音频流和一路视频流,此时我们需要用到函数avformat_new_stream();在调用此函数后,我们会得到AVStream *类型的指针。然后,我们需要将输入视频文件和音频文件的编码器相关参数复制到输出的视频流和音频流编码器中。最后,打开输出文件,将文件的I/O结构对应到输出文件的AVFormatContext结构。代码如下:
static int32_t init_output(const char *output_file){ int32_t result=0; avformat_alloc_output_context2(&output_fmt_ctx, nullptr, nullptr,output_file); if(!output_fmt_ctx){ cerr<<"Error:avformat_alloc_output_context2 failed."<oformat; cout<<"Default video codec id:"< video_codec<<", audio codec id:"< audio_codec< index; in_video_st_idx= av_find_best_stream(video_fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1, nullptr,0); if(in_video_st_idx<0){ cerr<<"Error:find video stream in input video file failed."< codecpar,video_fmt_ctx->streams[in_video_st_idx]->codecpar); if(result<0){ cerr<<"avcodec_parameters_copy failed."< id=output_fmt_ctx->nb_streams-1; video_stream->time_base=AVRational {1,STREAM_FRAME_RATE}; AVStream *audio_stream= avformat_new_stream(output_fmt_ctx, nullptr); if(!audio_stream){ cerr<<"Error:add audio stream to output format context failed."< index; in_audio_st_idx= av_find_best_stream(audio_fmt_ctx,AVMEDIA_TYPE_AUDIO,-1,-1, nullptr,0); if(in_audio_st_idx<0){ cerr<<"Error:find audio stream in input audio file failed."< codecpar,audio_fmt_ctx->streams[in_audio_st_idx]->codecpar); if(result<0){ cerr<<"Error:copy audio codec parameters failed."< id=output_fmt_ctx->nb_streams-1; audio_stream->time_base=AVRational {1,audio_stream->codecpar->sample_rate}; av_dump_format(output_fmt_ctx,0,output_file,1); cout<<"Output video idx:"< flags&AVFMT_NOFILE)){//判断AVFMT_NOFILE标志位是否设置在fmt->flags中 result= avio_open(&output_fmt_ctx->pb,output_file,AVIO_FLAG_WRITE); if(result<0){ cerr<<"Error:avio_open failed."< 下面,给出初始化复用器的完整代码:
int32_t init_muxer(const char *video_input_file,const char *audio_input_file,const char *output_file){ int32_t result= init_input_video(video_input_file,"h264"); if(result<0){ return -1; } result= init_input_audio(audio_input_file,"mp3"); if(result<0){ return -1; } result=init_output(output_file); if(result<0){ return -1; } return 0;}二.复用音频流和视频流
在这里,我们也可以分三步进行:(1)写入输出文件的头结构 (2)循环写入音频包和视频包 (3)写入输出文件的尾结构
1.写入输出文件的头结构
这一步很简单,调用avformat_write_header()函数就可以轻松实现。
2.循环写入音频包和视频包
这一步比较复杂,我们首先需要确定音频包和视频包的时间戳,判断写入顺序;这里我们需要比较音频包和视频包的时间戳,如果当前记录的音频时间戳比视频时间戳新,则接下来就应该写入视频数据了。但是,从H.264格式的裸码流中读取的视频包中通常不包含时间戳数据,所以我们需要计算视频包的时间戳。我们可以先计算出每一帧的持续时长,然后乘以帧序号就可以得到这一帧的时间戳了。代码如下:
if(pkt->pts==AV_NOPTS_VALUE){ int64_t frame_duration=(double)AV_TIME_BASE/ av_q2d(in_video_st->r_frame_rate); pkt->duration=(double)frame_duration/(double)(av_q2d(in_video_st->time_base)*AV_TIME_BASE); pkt->pts=(double)video_frame_idx*pkt->duration; pkt->dts=pkt->pts; cout<<"frame_duration:"<<frame_duration<<",pkt->duration:"<duration<<",pkt->pts:"< pts< 还有一点需要注意的是,从输入文件读取的码流包中保存的时间戳是以输入流的time_base为基准的,在写入输出文件时,需要转换为以输出流的time_base为基准。代码如下:
pkt->pts= av_rescale_q_rnd(pkt->pts,input_stream->time_base,output_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));pkt->dts=av_rescale_q_rnd(pkt->dts,input_stream->time_base,output_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));pkt->duration=av_rescale_q(pkt->duration,input_stream->time_base,output_stream->time_base);3.写入输出文件的尾结构
调用av_write_trailer()函数即可
完整代码如下:
int32_t muxing(){ int32_t result=0; int64_t cur_video_pts=0,cur_audio_pts=0; AVStream *in_video_st=video_fmt_ctx->streams[in_video_st_idx]; AVStream *in_audio_st=audio_fmt_ctx->streams[in_audio_st_idx]; AVStream *output_stream= nullptr,*input_stream= nullptr; int32_t video_frame_idx=0; result= avformat_write_header(output_fmt_ctx, nullptr); if(result<0){ return result; } pkt=av_packet_alloc(); if(!pkt){ cerr<<"Error:av_packet_alloc failed."<r_frame_rate.num<<"/"< r_frame_rate.den< time_base.num<<"/"< time_base.den< time_base,cur_audio_pts,in_audio_st->time_base)<=0){ input_stream=in_video_st; result=av_read_frame(video_fmt_ctx,pkt); if(result<0){ av_packet_unref(pkt); break; } if(pkt->pts==AV_NOPTS_VALUE){ int64_t frame_duration=(double)AV_TIME_BASE/ av_q2d(in_video_st->r_frame_rate); pkt->duration=(double)frame_duration/(double)(av_q2d(in_video_st->time_base)*AV_TIME_BASE); pkt->pts=(double)video_frame_idx*pkt->duration; pkt->dts=pkt->pts; cout<<"frame_duration:"<<frame_duration<<",pkt->duration:"< duration<<",pkt->pts:"< pts< pts; pkt->stream_index=out_video_st_idx; output_stream=output_fmt_ctx->streams[out_video_st_idx]; } else{ input_stream=in_audio_st; result= av_read_frame(audio_fmt_ctx,pkt); if(result<0){ av_packet_unref(pkt); break; } cur_audio_pts=pkt->pts; pkt->stream_index=out_audio_st_idx; output_stream=output_fmt_ctx->streams[out_audio_st_idx]; } pkt->pts= av_rescale_q_rnd(pkt->pts,input_stream->time_base,output_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); pkt->dts=av_rescale_q_rnd(pkt->dts,input_stream->time_base,output_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); pkt->duration=av_rescale_q(pkt->duration,input_stream->time_base,output_stream->time_base); cout<<"Final pts:"< pts<<",duration:"< duration<<",output_stream->time_base:"< time_base.num<<"/"< time_base.den< 三.释放复用器实例
void destroy_muxer(){ avformat_free_context(video_fmt_ctx); avformat_free_context(audio_fmt_ctx); if(!(output_fmt_ctx->oformat->flags&AVFMT_NOFILE)){ avio_closep(&output_fmt_ctx->pb); } avformat_free_context(output_fmt_ctx);}四.最终的main函数如下:
int main(){ int32_t result=0; result= init_muxer("../input.h264","../input.mp3","../output.mp4"); if(result<0){ return result; } result=muxing(); if(result<0){ return result; } destroy_muxer(); return 0;}最后,使用以下指令可以播放输出的output.mp4文件:
ffplay -i output.mp4
关键词:
如何将视频文件.h264和音频文件.mp3复用为输出文件output.mp4?
天天热资讯!商品日报(6月29日):尿素再度拉涨超5% 供应利多刺激甲醇盘中涨超3%
联发科MT6825芯片组获上海MWC 2023亚洲突破性设备创新大奖!手机卫星可双向通信_焦点资讯
支持Type-C充电:英菲克F1无线鼠标24.9元抄底
天天热消息:做错N多年!央视科普:鸡蛋别再放到冰箱门上了
要求罚金30亿美元!Chatgpt涉嫌信息盗窃被起诉 全球视讯
官方辟谣激情誓师女生考508分:女生考了600多分 考得特别好 环球焦点
全球低水足迹倡议(LWFi)联盟扩容,伊利“双足迹”开启全链减碳新篇章_世界视点
IDA的使用-1_世界新消息
clop勒索软件攻击活动频发,西门子能源中招_世界观察
精彩看点:构建数字工厂丨数据分析与图表视图模型的配置用法
券商数字化创新场景数据中台实践
热门看点:C# 序列化大小写 序列化对象为大小写 JsonConvert.SerializeObject
新款2024MGCyberster泄露 当前热讯
第十四届夏季达沃斯论坛闭幕
天天快讯:暴露年龄!时隔16年 Office“大眼夹”回归Windows 11:功能焕然一新
16.5亿打造!《封神》妲己首次亮相引热议 网友称妆造诡异在拍画皮吗
苹果之后 三星被指侵犯加州理工Wi-Fi专利:索赔可达数十亿美元-世界新消息
“快乐水”不快乐了!阿斯巴甜将被定为可能致癌物质|天天热资讯
华为发布F5.5G智简全光联接四大创新:万兆时代来了
讯息:大宗交易:蓝色光标成交6967.8万元,折价1.96%(06-29)
解读 RocketMQ 5.0 全新的高可用设计
探秘华为云盘古大模型:AI for industries的身体力行_报道
天天速读:高铁踹老头底被曝
科创板收盘播报:科创50指数跌0.67% 新股时创能源较发行价涨63.91%|全球热闻
如何使用 iOS 17 将照片变成 iMessage 贴纸
多家高校下月起停用微信支付 微信团队致歉:即刻修正
鳄鱼独居16年产子 科学家:濒临灭绝物种的生存策略
南极人纯棉抗菌袜子8双14.9元:吸湿排汗 亲肤透气
【全球报资讯】多家高校下月起停用微信支付 腾讯回应网友不买账:专家称反垄断太有意义
Intel四代至强命运多舛:突曝严重Bug 部分停止出货
精彩看点:司法部出手!这项业务,有大变化!
【后端面经-Java】公平锁和加锁流程 全球简讯
讯息:玖章算术与百度智能云达成合作,「NineData SQL 开发」成为百度智能云主推的数据库工具
【高端访谈】中非经贸博览会将助力刚中贸易提质升级——访刚果(金)外贸部长布萨_当前视讯
央企改革三年重点任务考核结果出炉:三大运营商排名一一曝光
摩托骑手被汽车撞下高架 现场惨!官方通报:系被追尾 伤者暂无生命危险
立白洗衣液大促:山茶幽香、除菌除螨 10斤到手38元_每日简讯
MWC牌面!魅族Flyme Auto上央视:车机互联打通软硬件|当前快看
露牙媚眼羞涩笑主播圈粉中老年人:当当网李国庆在线求合作
每日消息!索尼ZV-E1“打鸡血”:免费升级4K 120p拍摄
年内8家“袖珍”IPO公司登陆港交所-天天观天下
鼎通科技(688668):该股换手率大于8%(06-29)_世界速讯
性能4倍于1060!RTX 4060今天开售:2399元 英伟达诚意感受到没-当前速读
世界即时看!疑因不满项目谈判被提前泄露:特斯拉或已放弃在西班牙建厂!
今日讯!内蒙古康巴什区:让“梧桐树”更加枝繁叶茂
环球播报:装机选500W电源就是万金油?你又错了
海南环岛旅游公路主线路基段即将完工:12月底通车 串联全省景点|独家
Windows自带杀软又出问题:Defender新版CPU占用过高|环球焦点
每部手机都有的出厂标签要改了!工信部:7月1日起正式启用新型进网许可标志
90后宝妈沙漠边缘送奶茶月入7000 我能赚钱生娃:直言男人除了赚钱还能干啥? 当前速递
卢卡申科:普京曾有意杀死普里戈任,我劝他不要鲁莽行事
数字经济催生的低代码开发浪潮,JNPF带你轻松实现应用程序拓展! 天天日报
直播平台源码功能分享:直播回放功能的实现_当前看点
【天天快播报】云顶新耀-B早盘持续走高涨近9% 中金维持跑赢行业评级
能在车上点外卖了!特斯拉或将推出应用商城 可支持第三方应用与服务 热点聚焦
法庭文件出纰漏 五星大饭店运营成本曝光|实时焦点
剑指比亚迪海豚 宝骏云朵外观细节图发布:全球顶级设计师操刀 环球观察
40度高温杀回马枪!南方多地加入高温群聊蒸桑拿
传奇女歌手麦当娜进ICU:因细菌感染_每日看点
宁德时代联合长安汽车等共设动力电池公司
js的Set数据类型
Linux_Centos 增加中文字体支持|环球视点
直播系统聊天技术(九):千万级实时直播弹幕的技术实践
天天看热讯:【Oracle】使用PL/SQL实现冒泡排序
BackboneJS教程_编程入门自学教程_菜鸟教程-免费教程分享 环球关注
环球快讯:智能合约在数字人民币中的应用与治理
2023年普通高校招生录取工作即将开始,教育部发出提醒——高校招生录取期间谨防受骗
世界速讯:47度高温!印度遭极端“烤验”:近期已造成多人死亡
网易游戏公布暑假未成年人限玩时间:大模型干预不理性消费_全球热头条
全球观速讯丨比NS还小却塞进AMD 7840U!AYANEO公布新掌机AIR 1S
焦点热门:599元 小米电视EA32上架:升级5GHz Wi-Fi、分辨率不足1080P
1099元起 Redmi Note 12R发布:首发第二代骁龙4
女子称喂奶后发现医院母婴室装有摄像头?院方回应 信息
天天新资讯:k8s 深入篇———— 守护容器[九]
Spring Boot 项目设计业务操作日志功能,写得太好了!-世界即时看
毕业季,科学城幼儿园大班萌娃用画笔勾勒未来|当前热文
辽宁:全链条打击证券犯罪 去年以来追赃挽损7.14亿余元
上海电气印度业务被诈骗88亿 反被索赔21亿?官方辟谣-环球微头条
腾讯回应数百人部门解散:正常架构调整 不涉及人员优化 每日聚焦
iPhone上市开售16周年:共38款机型 售价越来越贵_独家焦点
全国首位视障播音硕士毕业:键盘盲打完成6万字论文 9年读了百本盲书-天天热门
不惯着!女子人肉占车位撒泼打滚:结局舒适-世界要闻
一次日志配置未生效问题排查记录
linux把文件压缩成.tar.gz的命令&各个压缩解压命令大全--九五小庞
MFC中使用多线程
希望所有计算机专业学生都知道这门课-世界速看
我市举行天然气应急救援演练|世界快看点
7月见!华为大动作不断:将发布新款存储 面向AI大模型 世界观焦点
凯迪拉克格局打开!赞助节目中允许宣传理想L9 还邀请李想体验新车-天天即时
辣眼睛!男子鞋底塞112张《塞尔达传说:王国之泪》卡带入境被查|天天新消息
每日热点:董丽娜,毕业快乐!
环球快播:Linux-vs-MacOS-,你更喜欢哪个系统?
世界热点评!【读财报】一季度信用卡消费者投诉透视:监管处理信用卡业务投诉超3.2万件 工商银行被投诉总量高
cad什么版本最好用_cad那个版本比较好用
对标苹果Studio Display!三星首款5K显示器开售:9999元还送1T SSD
网飞版《三体》预告播放破千万 粉丝喊话别拍砸了:国内拍技术落后?_环球新资讯
ChatGPT假装奶奶哄睡:能免费生成Win系统激活码
热讯:“泡面神器”彻底凉凉!亚马逊Kindle中国电子书店明日停运
SSD等存储要拉开涨价序幕了:有厂商财报明确!