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

FFmpeg-- c++实现:音频流aac和视频流h264封装

文章目录

      • 流程
      • api
      • 核心代码
        • muxer.h
        • muxer.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.h"Muxer::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;
}

相关文章:

FFmpeg-- c++实现:音频流aac和视频流h264封装

文章目录 流程api核心代码muxer.hmuxer.cpp aac 和 h264 封装为视频流&#xff0c;封装为c的Muxter类 流程 分配视频文件上下文 int Init(const char *url); 创建流&#xff0c;赋值给视频的音频流和视频流 int AddStream(AVCodecContext *codec_ctx); 写视频流的head int Se…...

单片机烧录方式,JTAG,ISP,SWD,

常见的词汇 参考 ISP&#xff1a;In System Programing&#xff0c;在系统编程 IAP&#xff1a;In Application Programing&#xff0c;在应用编程 ICP&#xff1a;In Circuit Programing&#xff0c;在电路编程 ICSP全称是In Circuit Serial Programming JTAG(Joint Test Act…...

【项目管理后台】Vue3+Ts+Sass实战框架搭建一

项目管理后台 建立项目最好是卸载Vetur 新建.env.d.ts文件安装Eslint安装校验忽略文件添加运行脚本 安装prettier新建.prettierrc.json添加规则新建.prettierignore忽略文件 安装配置stylelint新建.stylelintrc.cjs 添加后的运行脚本配置husky配置commitlint配置husky 强制使用…...

基于python 变配电室运行状态评估与预警系统flask-django-nodejs-php

变配电室电气设备运行状态和环境信息缺乏必要的监测评估预警手段&#xff0c;如有一日遭遇突发情况&#xff0c;将危及电气设备安全稳定运行,易造成设备损坏和电力供应中断[2]。 目前&#xff0c;我国变配电室常采用无人管理的室内站设计方案&#xff0c;长期以来变配电室运维工…...

【自记录】VS2022编译OpenSSL1.0.2u

因为突然要编译一个老工程&#xff0c;老工程里面用到了OpenSSL 1.0.x。 于是官网下载了最后一个1.0.x版本1.0.2u。 1 下载安装Perl 去Perl官网下载即可。 使用vcpkg直接安装也可以&#xff0c;比前者更方便 vcpkg install perl #根据实际路径调整 set PATHD:\vcpkg\downloa…...

ES代替品:轻量级搜索引擎MeiliSearch

痛点 虽然Elasticsearch足够灵活强大、扩展性和实时性也较好。但是对于中小型项目来说&#xff0c;Elasticsearch还是显得有些庞大&#xff0c;对硬件设备的要求也较高。那么&#xff0c;在要求不是很高的情况下&#xff0c;我们可以考虑另一种搜索引擎方案&#xff1a;MeiliSe…...

用C语言打造自己的Unix风格ls命令

在Unix或类Unix操作系统中&#xff0c;ls是一个非常基础且实用的命令&#xff0c;它用于列出当前目录或指定目录下的文件和子目录。下面&#xff0c;我们将通过C语言编写一个简化的ls命令&#xff0c;展示如何利用dirent.h头文件提供的函数接口实现这一功能。 #include "…...

git的起源

开篇一张图&#xff1a; 开源项目linux kernel开发&#xff0c;参与开发与维护者众多。1991至2005年期间绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上。 在2002 年&#xff0c;整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维…...

软件杯 深度学习 python opencv 火焰检测识别

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…...

C# double类型计算精度问题解决

问题&#xff1a;res 的值0.112450000001&#xff0c;精度不对&#xff0c;预期是0.11245 double force112.45&#xff1b; double res force / Math.Pow(10, index * 3); double force112.45; double res force / Math.Pow(10, index * 3); string str res.ToString(&qu…...

基于Springcloud+Vue校园招聘系统 Eureka分布式微服务

以行动研究为主&#xff0c;辅以文献法、教育实验法和个案研究法等方法相结合的研究方法。在研究方法&#xff0c;遵循软件工程中软件生命周期的规则。概括来讲可以划分成三大步&#xff1a;系统规划、系统开发和系统运行维护。将其上述步骤细分下来&#xff0c;可以分为以下8小…...

【NLP笔记】RNN总结

文章目录 经典RNN单向RNN双向RNNDeep RNNRNN特性总结 变体RNNLSTMGRU 参考及转载内容&#xff1a; 循环神经网络&#xff08;RNN&#xff09;深度学习05-RNN循环神经网络完全理解RNN&#xff08;循环神经网络&#xff09; 传统的CNN&#xff08;Covolutional Neural Network&am…...

[c++]内存管理

1. C/C内存分布 我们先来看下面的一段代码和相关问题 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd"; const char* pChar3 "abcd"; …...

k8s通过编排文件,实现服务的滚动更新

k8s通过编排文件&#xff0c;实现服务的滚动更新 apiVersion: apps/v1 kind: pod metadata:name: ‘servicename’labels:app: ‘servicename’ spec:replicas: 4 ##pod启动数量最少为2&#xff0c;不然滚动更新无意义strategy:type: RollingUpdate ##设置类型为滚动更新以及…...

安卓面试题多线程 96-100

96. 简述notify()和notifyAll()有什么区别 ?notify可能会导致死锁,而notifyAll则不会任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码 使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一…...

第二十六章 配置 Web Gateway 的默认参数

文章目录 第二十六章 配置 Web Gateway 的默认参数网络网关实例主机名最大连接数最大缓存大小网络服务器 ID Cookie 第二十六章 配置 Web Gateway 的默认参数 本页介绍如何通过 Web Gateway 管理页面配置 IRIS Web Gateway 的默认参数。其他文章介绍了如何配置服务器和应用程序…...

npm i安装依赖报错,但是cnpm i 却安装成功

问题描述&#xff1a;在a项目中npm i 安装依赖时发生以上报错&#xff0c;但是cnpm i 却成功&#xff0c;而且在其他项目中npm i 安装其他项目依赖也能成功.... 解决办法&#xff1a;删除项目中package-lock.json文件后再npm i 即可...

C语言经典算法-9

文章目录 其他经典例题跳转链接46.稀疏矩阵47.多维矩阵转一维矩阵48.上三角、下三角、对称矩阵49.奇数魔方阵50.4N 魔方阵51.2(2N1) 魔方阵 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&#xff09;6.…...

React 19的变化

并发模式&#xff08;非实验&#xff09;: React 的并发模式终于从实验阶段毕业了。这一改变游戏规则的功能允许 React 应用程序同时准备多个版本的 UI。有着更平滑的过渡和更灵敏的用户体验&#xff0c;因为 React 现在可以处理高优先级更新&#xff0c;同时保持应用程序的交互…...

Kafka整理-Kafka与传统消息队列系统(如RabbitMQ, ActiveMQ)的区别是什么?

Apache Kafka与传统消息队列系统(如RabbitMQ, ActiveMQ)虽然都是处理消息和数据流的中间件,但它们在设计理念、架构、功能和使用场景方面有显著的区别。下面是Kafka与传统消息队列系统的主要区别: 1. 设计目的和使用场景 Kafka: 设计初衷是为处理大量的实时数据流。强调高…...

STM32F103C8T6的读保护功能,到底怎么用才安全?一个真实案例带你避坑

STM32读保护功能实战指南&#xff1a;从原理到避坑全解析 记得去年接手一个工业控制器项目时&#xff0c;团队里有位新人工程师在调试STM32F103C8T6时不小心触发了读保护&#xff0c;导致整批样品芯片集体"罢工"。那天的紧急加班让我深刻意识到——读保护功能就像一把…...

GitHub加速革命:告别龟速下载,提升开发效率的终极方案

GitHub加速革命&#xff1a;告别龟速下载&#xff0c;提升开发效率的终极方案 【免费下载链接】Fast-GitHub 国内Github下载很慢&#xff0c;用上了这个插件后&#xff0c;下载速度嗖嗖嗖的~&#xff01; 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 在深…...

终极罗技鼠标宏压枪指南:告别PUBG后坐力困扰的3个秘诀

终极罗技鼠标宏压枪指南&#xff1a;告别PUBG后坐力困扰的3个秘诀 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 还在为绝地求生中的武器后坐力…...

Clawdbot汉化版企业微信入口教程:5分钟搭建专属AI助手,小白也能搞定

Clawdbot汉化版企业微信入口教程&#xff1a;5分钟搭建专属AI助手&#xff0c;小白也能搞定 1. 为什么选择Clawdbot汉化版&#xff1f; Clawdbot汉化版是一个完全本地化的AI对话系统&#xff0c;它解决了企业用户最关心的三个核心问题&#xff1a; 数据安全&#xff1a;所有…...

忍者像素绘卷基础教程:3步完成‘火之意志’提示词→像素绘卷生成

忍者像素绘卷基础教程&#xff1a;3步完成火之意志提示词→像素绘卷生成 1. 认识忍者像素绘卷 忍者像素绘卷是一款基于Z-Image-Turbo深度优化的图像生成工具&#xff0c;它将传统忍者文化与16-Bit复古游戏美学完美结合。不同于常见的暗色调像素艺术&#xff0c;这款工具采用了…...

Intv_AI_MK11 Node.js全栈开发指南:环境配置与AI服务端集成

Node.js全栈开发指南&#xff1a;环境配置与AI服务端集成 1. 前言&#xff1a;为什么选择Node.js开发AI应用 Node.js已经成为现代Web开发的热门选择&#xff0c;特别是在需要处理高并发、实时数据流的场景下。当我们将AI能力集成到Web应用中时&#xff0c;Node.js的非阻塞I/O…...

OpenClaw日志分析技巧:千问3.5-9B辅助故障定位

OpenClaw日志分析技巧&#xff1a;千问3.5-9B辅助故障定位 1. 为什么需要AI辅助日志分析&#xff1f; 上周排查一个OpenClaw任务失败的问题时&#xff0c;我盯着3MB的日志文件看了整整两小时。那些重复的报错堆栈和模糊的警告信息像迷宫一样——直到我意识到&#xff1a;与其…...

SEO_网站SEO优化完整教程:从入门到精通

SEO优化入门&#xff1a;从零基础到实战操作 随着互联网的迅猛发展&#xff0c;网站SEO优化成为了网站推广的重要手段。SEO&#xff0c;即搜索引擎优化&#xff0c;是通过优化网站的各项因素&#xff0c;使其在搜索引擎中获得更好的排名&#xff0c;从而吸引更多的流量。如何从…...

告别手动备份!用Power Automate Desktop自动备份桌面重要文件并生成日志

告别手动备份&#xff01;用Power Automate Desktop打造智能文件备份系统 每天下班前&#xff0c;你是否会习惯性地将桌面上的重要文件拖拽到U盘或移动硬盘&#xff1f;这种重复性操作不仅耗时耗力&#xff0c;还容易因疏忽导致文件遗漏。更糟糕的是&#xff0c;当系统崩溃或误…...

终极GRUB配置指南:让build-linux系统成功启动的7个关键步骤

终极GRUB配置指南&#xff1a;让build-linux系统成功启动的7个关键步骤 【免费下载链接】build-linux A short tutorial about building Linux based operating systems. 项目地址: https://gitcode.com/gh_mirrors/bu/build-linux build-linux项目是一个构建Linux操作系…...