ffmpeg实现视频的合成与分割
视频合成与分割程序使用
作者开发了一款软件,可以实现对视频的合成和分割,界面如下:

播放时,可以选择多个视频源;在选中“保存视频”情况下,会将多个视频源合成一个视频。如果只取一个视频源中一段视频,就实现了视频分割。下载视频合成与分割程序。
对视频的处理采用了ffmpeg库。作者在此库的基础上,做了进一步封装,使用起来更加简便。
底层处理逻辑可用如下函数表示:
bool InitVideo(); bool AddImage(unsigned char* imageFileBuffer, int bufferSize); bool CloseVideo();
可见底层函数是十分简洁的; 但是ffmpeg函数调用复杂,使用起来不便; 将ffmpeg封装亦非易事;本文就讲述对ffmpeg封装的过程。
视频编码与解码
对视频的处理分为两种:解码和编码。视频播放属于解码,视频生成属于编码。视频播放方面的文章和例子很多;我也写过一篇文章《使用Emgu.CV开发视频播放器简述》。
视频其实就是连续的图片,编码的作用就是压缩图片,减小视频文件的占用。可以把视频文件想象成容器,把一些列图片放入容器,经过编码,生成标准格式的视频文件(如mp4),这个过程就是编码;
把不同视频来源的图片放入容器,就实现了视频的合成;把视频中某段包含的图片放入容器,就实现了视频的分割。只要实现了对多个图片到视频的编码,就实现了视频的合成和分割。

初始化编码器,包括选择编码器,生成输入流,写入文件头等操作。
bool ImageToVideo::InitVideo()
{InitFfmpeg();AVFormatContext* pFormatCtx = NULL;_errnum = avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, _destVideoFileName.c_str());if (_errnum < 0){av_strerror(_errnum, _errbuf, sizeof(_errbuf));return false;}_initFree.pFormatCtx = pFormatCtx;// h264视频编码器const AVCodec* vcodec = avcodec_find_encoder(AVCodecID::AV_CODEC_ID_H264);if (!vcodec){return false;}// 创建编码器上下文AVCodecContext* pVideoCodecCtx = avcodec_alloc_context3(vcodec);if (!pVideoCodecCtx){return false;}_initFree.pVideoCodecCtx = pVideoCodecCtx;// 比特率、宽度、高度pVideoCodecCtx->bit_rate = 4000000;pVideoCodecCtx->width = _videoWidth; // 视频宽度pVideoCodecCtx->height = _videoHeight; // 视频高度// 时间基数、帧率pVideoCodecCtx->time_base = { 1, 25 };pVideoCodecCtx->framerate = { 25, 1 };// 关键帧间隔pVideoCodecCtx->gop_size = 10;// 不使用b帧pVideoCodecCtx->max_b_frames = 0;// 帧、编码格式pVideoCodecCtx->pix_fmt = AVPixelFormat::AV_PIX_FMT_YUV420P;pVideoCodecCtx->codec_id = AVCodecID::AV_CODEC_ID_H264;// 预设:快速av_opt_set(pVideoCodecCtx->priv_data, "preset", "superfast", 0);// 全局头pVideoCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;_errnum = avcodec_open2(pVideoCodecCtx, vcodec, NULL);if (_errnum < 0){return false;}// 为封装器创建视频流AVStream* pVideoStream = avformat_new_stream(pFormatCtx, NULL);if (!pVideoStream){return false;}_initFree.pVideoStream = pVideoStream;pVideoStream->codec->codec_tag = 0;pVideoStream->codecpar->codec_tag = 0;// 配置视频流的编码参数avcodec_parameters_from_context(pVideoStream->codecpar, pVideoCodecCtx);// 打开输出流IO_errnum = avio_open(&pFormatCtx->pb, _destVideoFileName.c_str(), AVIO_FLAG_WRITE); // 打开AVIO流if (_errnum < 0){avio_close(pFormatCtx->pb);return false;}_errnum = avformat_write_header(pFormatCtx, NULL);if (_errnum < 0){return false;}return true;
}
添加图片
1 对添加的图片缩放处理:
SwsContext* pSwsCtx = sws_getContext(imageWidth, imageHeight, srcFormat, _initFree.pVideoCodecCtx->width, _initFree.pVideoCodecCtx->height, AVPixelFormat::AV_PIX_FMT_YUV420P, // 输出SWS_BICUBIC, 0, 0, 0);
2 发送frame ,接收编码后的packet
vframe->pts = vpts++;
_errnum = avcodec_send_frame(_initFree.pVideoCodecCtx, vframe);
if (_errnum < 0)
{// cout << "avcodec_send_frame failed" << endl;av_frame_free(&vframe);return false;
}// 视频编码报文
AVPacket* packet = av_packet_alloc();
int writeCount = 0;while (true)
{_errnum = avcodec_receive_packet(_initFree.pVideoCodecCtx, packet);if (_errnum < 0 || packet->size <= 0){int e1 = AVERROR_EOF;int e2 = AVERROR(EAGAIN);if (writeCount == 0){av_frame_free(&vframe);av_packet_free(&packet);// cout << "avcodec_receive_packet failed" << endl;return false;}else{break;}}
编码完成:写入文件尾数据,释放资源
_errnum = av_write_trailer(_initFree.pFormatCtx);
if (_errnum != 0)
{return false;
}if (pFormatCtx != NULL)
{avio_closep(&pFormatCtx->pb);avformat_close_input(&pFormatCtx);
}if (pVideoCodecCtx != NULL)
{avcodec_close(pVideoCodecCtx);avcodec_free_context(&pVideoCodecCtx);
}if (pSwsCtx != NULL)
{sws_freeContext(pSwsCtx);
}
后记:对于视频的合成和分割,网上有不少这方面的文章,大都是讲述如何使用ffmpeg工具操作,这些方法不灵活,很难满足个性化的需求。本文从视频最基本的原理剖析,实现了图片合成视频的功能;这样就为上层丰富多彩的应用打开了大门。
比如 将两个视频文件合成到一个播放画面;处理过程为:同时读取两个视频源的文件,将两个图片拼接,再放入视频容器。
相关文章:
ffmpeg实现视频的合成与分割
视频合成与分割程序使用 作者开发了一款软件,可以实现对视频的合成和分割,界面如下: 播放时,可以选择多个视频源;在选中“保存视频”情况下,会将多个视频源合成一个视频。如果只取一个视频源中一段视频…...
团体标准的十大优势
一、团体标准是什么 团体标准是指由社会团体(行业协会、联合会、企业联盟等)按照自己确立的制定程序,自主制定、发布、采纳,并由社会自愿采用的标准。简单的说,就是社会团体为了满足市场和创新需要,协调相…...
java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务
java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务 添加对应的maven <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version…...
sqlgun靶场漏洞挖掘
1.xss漏洞 搜索框输入以下代码,验证是否存在xss漏洞 <script>alert(1)</script> OK了,存在xss漏洞 2.SQL注入 经过测试,输入框存在SQL注入漏洞 查询数据库名 查询管理员账号密码 此处密码为MD5加密,解码内容如下 找…...
好用的 Markdown 编辑器组件
ByteMD bytedance/bytemd: ByteMD v1 repository (github.com) 这里由于我的项目是 Next,所以安装 bytemd/react, 阅读官方文档,执行命令来安装编辑器主体、以及 gfm(表格支持)插件、highlight 代码高亮插件…...
uniapp vite3 require导入commonJS 的js文件方法
vite3 导入commonJS 方式导出 在Vite 3中,你可以通过配置vite.config.js来实现导入CommonJS(CJS)风格的模块。Vite 默认支持ES模块导入,但如果你需要导入CJS模块,可以使用特定的插件,比如originjs/vite-pl…...
通义灵码用户说:“人工编写测试用例需要数十分钟,通义灵码以毫秒级的速度生成测试代码,且准确率和覆盖率都令人满意”
通过一篇文章,详细跟大家分享一下我在使用通义灵码过程中的感受。 一、定义 通义灵码,是一个智能编码助手,它基于通义大模型,提供代码智能生成、研发智能问答能力。 在体验过程中有任何问题均可点击下面的连接前往了解和学习。 …...
MySQL中的约束
约束概述 1.1 为什么需要约束 数据完整性(Data Integrity)是指数据的精确性(Accuracy)和可靠性(Reliability)。它是防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信…...
Leetcode 寻找重复数
可以使用 位运算 来解决这道题目。使用位运算的一个核心思想是基于数字的二进制表示,统计每一位上 1 的出现次数,并与期望的出现次数做比较。通过这种方法,可以推断出哪个数字重复。 class Solution { public:int findDuplicate(vector<i…...
大一新生以此篇开启你的算法之路
各位大一计算机萌新们,你们好,本篇博客会带领大家进行算法入门,给各位大一萌新答疑解惑。博客文章略长,可根据自己的需要观看,在博客中会有给大一萌新问题的解答,请不要错过。 入门简介: 算法…...
【AI大模型】ChatGPT模型原理介绍(上)
目录 🍔 什么是ChatGPT? 🍔 GPT-1介绍 2.1 GPT-1模型架构 2.2 GPT-1训练过程 2.2.1 无监督的预训练语言模型 2.2.2 有监督的下游任务fine-tunning 2.2.3 整体训练过程架构图 2.3 GPT-1数据集 2.4 GPT-1模型的特点 2.5 GPT-1模型总结…...
基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模
前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博…...
C++竞赛初阶L1-15-第六单元-多维数组(34~35课)557: T456507 图像旋转
题目内容 输入一个 n 行 m 列的黑白图像,将它顺时针旋转 90 度后输出。 输入格式 第一行包含两个整数 n 和 m,表示图像包含像素点的行数和列数。1≤n≤100,1≤m≤100。 接下来 n 行,每行 m 个整数,表示图像的每个像…...
无线领夹麦克风哪个牌子好?西圣、罗德、猛犸领夹麦克风深度评测
如今短视频和直播行业蓬勃发展,无线领夹麦克风成为了许多创作者不可或缺的工具。然而,市场上的无线领夹麦克风品牌众多、质量参差不齐,为了帮助大家挑选到满意的产品,我作为数码测评博主,对无线领夹麦克风市场进行了…...
React Native 0.76,New Architecture 将成为默认模式,全新的 RN 来了
关于 React Native 的 New Architecture 概念,最早应该是从 2018 年 RN 团队决定重写大量底层实现开始,因为那时候 React Native 面临各种结构问题和性能瓶颈,最终迫使 RN 团队开始进行重构。 而从 React Native 0.68 开始,New A…...
Java并发:互斥锁,读写锁,Condition,StampedLock
3,Lock与Condition 3.1,互斥锁 3.1.1,可重入锁 锁的可重入性(Reentrant Locking)是指在同一个线程中,已经获取锁的线程可以再次获取该锁而不会导致死锁。这种特性允许线程在持有锁的情况下,可…...
客户端负载均衡Ribbon实例
文章目录 一,概述二,实现过程三,项目源码1. 源码放送:2. 部署方式 四,功能演示五,其他 一,概述 一般来说,提到负载均衡,大家一般很容易想到浏览器 -> NGINX -> 反…...
MySQL数据库负载均衡
数据库负载均衡是通过将数据库请求分散到多个数据库服务器上,以提高数据库的处理能力和可用性。在高并发的场景下,使用数据库负载均衡器可以有效避免单点故障,提高系统的整体性能和可靠性。 数据库负载均衡器 数据库负载均衡器可以是硬件设…...
达梦CASE_SENSITIVE参数解析
1. 参数含义 标识符大小写敏感,默认值为 Y。 当大小写敏感时,小写的标识符应用双引号括起,否则被转换为大写;当大小写不敏感时,系统不自动转换标识符的大小写,在标识符比较时也不区分大小写。 CASE_SENS…...
酒店智能轻触开关工作原理
在现代化酒店中,智能轻触开关已成为提升宾客居住体验的重要设备之一。这些开关不仅操作便捷,而且功能丰富,能够实现对灯光、窗帘、空调等设备的精准控制。本文将深入探讨酒店智能轻触开关的工作原理。 一、智能轻触开关的基本概念 智能轻触开…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
