ffmpeg + opencv 把摄像头画面保存为mp4文件(Ubuntu24.04)
参考链接
ffmpeg + opencv 把摄像头画面保存为mp4文件_ffmpeg转化摄像头mp4-CSDN博客
调试环境
Ubuntu24.04
ffmpeg 6.1.1
opencv 4.6
g++ 13.2.0
C++源码
#include <iostream>
#include <sys/time.h>
#include <string>#ifdef __cplusplus
extern "C"
{
#endif#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>#ifdef __cplusplus
} // endof extern "C"
#endif#include <opencv2/opencv.hpp>
using namespace cv;AVFrame *videoFrame = nullptr;
AVCodecContext *cctx = nullptr;
SwsContext *swsCtx = nullptr;
int frameCounter = 0;
AVFormatContext *ofctx = nullptr;
int fps = 30;
int width = 640;
int height = 480;
int bitrate = 2000;
long start_time = 0;
const std::string output_filename = "out.mp4";
// const std::string output_filename = "out.ts";long getCurrentTime()
{struct timeval tv;gettimeofday(&tv, NULL);return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}static void pushFrame(uint8_t *data, long currentTime)
{int err;AVPacket pkt = {0};int inLinesize[1] = {3 * cctx->width};// From RGB to YUVsws_scale(swsCtx, (const uint8_t *const *)&data, inLinesize, 0, cctx->height, videoFrame->data, videoFrame->linesize);videoFrame->pts = ((currentTime - start_time) / 1000.0) * 90000;std::cout << videoFrame->pts << " " << cctx->time_base.num << " " << cctx->time_base.den << " " << frameCounter << std::endl;if ((err = avcodec_send_frame(cctx, videoFrame)) < 0){std::cout << "Failed to send frame" << err << std::endl;return;}pkt.buf = NULL;pkt.side_data = NULL;pkt.data = NULL;pkt.size = 0;pkt.flags |= AV_PKT_FLAG_KEY;if (avcodec_receive_packet(cctx, &pkt) == 0){static int counter = 0;if (counter == 0){FILE *fp = fopen("dump_first_frame1.dat", "wb");fwrite(pkt.data, pkt.size, 1, fp);fclose(fp);}std::cout << "pkt key: " << (pkt.flags & AV_PKT_FLAG_KEY) << " " << pkt.size << " " << (counter++) << std::endl;uint8_t *size = ((uint8_t *)pkt.data);std::cout << "first: " << (int)size[0] << " " << (int)size[1] << " " << (int)size[2] << " " << (int)size[3] << " " << (int)size[4] << " " << (int)size[5] << " " << (int)size[6] << " " << (int)size[7] << std::endl;av_interleaved_write_frame(ofctx, &pkt);av_packet_unref(&pkt);}
}static void finish()
{// DELAYED FRAMESAVPacket pkt = {0};pkt.data = NULL;pkt.size = 0;while (true){avcodec_send_frame(cctx, NULL);if (avcodec_receive_packet(cctx, &pkt) == 0){av_interleaved_write_frame(ofctx, &pkt);av_packet_unref(&pkt);}else{break;}}av_write_trailer(ofctx);avformat_close_input(&ofctx);
}static void free()
{if (videoFrame){av_frame_free(&videoFrame);}if (cctx){avcodec_free_context(&cctx);}if (ofctx){avformat_free_context(ofctx);}if (swsCtx){sws_freeContext(swsCtx);}
}int main()
{// VideoCapture capture("road_test.mp4");VideoCapture capture(0);Mat frame;capture >> frame;width = frame.cols;height = frame.rows;avdevice_register_all();int err = avformat_alloc_output_context2(&ofctx, nullptr, nullptr, output_filename.c_str());if (err){std::cout << "can't create output context" << std::endl;return -1;}const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264);if (!codec){std::cout << "can't create codec" << std::endl;return -1;}AVStream *stream = avformat_new_stream(ofctx, codec);if (!stream){std::cout << "can't find format" << std::endl;return -1;}cctx = avcodec_alloc_context3(codec);if (!cctx){std::cout << "can't create codec context" << std::endl;return -1;}stream->codecpar->codec_id = AV_CODEC_ID_H264;stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;stream->codecpar->width = width;stream->codecpar->height = height;stream->codecpar->format = AV_PIX_FMT_YUV420P;stream->codecpar->bit_rate = bitrate * 1000;avcodec_parameters_to_context(cctx, stream->codecpar);cctx->time_base = (AVRational){1, 1};cctx->max_b_frames = 2;cctx->gop_size = 12;cctx->framerate = (AVRational){fps, 1};if (stream->codecpar->codec_id == AV_CODEC_ID_H265){av_opt_set(cctx, "preset", "ultrafast", 0);}avcodec_parameters_from_context(stream->codecpar, cctx);if ((err = avcodec_open2(cctx, codec, NULL)) < 0){std::cout << "Failed to open codec" << err << std::endl;return -1;}if ((err = avio_open(&ofctx->pb, output_filename.c_str(), AVIO_FLAG_WRITE)) < 0){std::cout << "Failed to open file" << err << std::endl;return -1;}if ((err = avformat_write_header(ofctx, NULL)) < 0){std::cout << "Failed to write header" << err << std::endl;return -1;}av_dump_format(ofctx, 0, output_filename.c_str(), 1);videoFrame = av_frame_alloc();videoFrame->format = AV_PIX_FMT_YUV420P;videoFrame->width = cctx->width;videoFrame->height = cctx->height;if ((err = av_frame_get_buffer(videoFrame, 32)) < 0){std::cout << "Failed to allocate picture" << err << std::endl;return -1;}swsCtx = sws_getContext(cctx->width, cctx->height, AV_PIX_FMT_BGR24, cctx->width, cctx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, 0, 0, 0);start_time = getCurrentTime();for (int i = 0; i < 100; ++i){capture >> frame;pushFrame(frame.data, getCurrentTime());}finish();free();return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)project(recordStudy)find_package(OpenCV REQUIRED)include_directories(. ${OpenCV_INCLUDE_DIRS})link_libraries(avformat)
link_libraries(avcodec)
link_libraries(avutil)
link_libraries(swscale)
link_libraries(avdevice)add_executable(recordStudy main.cpp)
target_link_libraries(recordStudy ${OpenCV_LIBS})
牢骚
我是在VirtualBox里装的Ubuntu24.04,干啥都卡,启动都卡
VMBox 7.0.18, Ubuntu 24.04 LTS - virtualbox.org
相关文章:
ffmpeg + opencv 把摄像头画面保存为mp4文件(Ubuntu24.04)
参考链接 ffmpeg opencv 把摄像头画面保存为mp4文件_ffmpeg转化摄像头mp4-CSDN博客 调试环境 Ubuntu24.04 ffmpeg 6.1.1 opencv 4.6 g 13.2.0 C源码 #include <iostream> #include <sys/time.h> #include <string>#ifdef __cplusplus extern "…...
Fastapi 项目第二天首次访问时数据库连接报错问题Can‘t connect to MySQL server
问题描述 Fastapi 项目使用 sqlalchemy 连接的mysql 数据库,每次第二天首次访问数据库相关操作,都会报错:sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, “Can’t connect to MySQL server on ‘x.x.x.x’ ([Err…...
尚硅谷k8s 2
p54-56 k8s核心实战 service服务发现 Service:将一组 Pods 公开为网络服务的抽象方法。 #暴露Deploy,暴露deploy会出现在svc kubectl expose deployment my-dep --port8000 --target-port80#使用标签检索Pod kubectl get pod -l appmy-depapiVersion: v1 kind: Service metad…...
机器学习---线性回归
1、线性回归 例如:对于一个房子的价格,其影响因素有很多,例如房子的面积、房子的卧室数量、房子的卫生间数量等等都会影响房子的价格。这些影响因子不妨用 x i x_{i} xi表示,那么房价 y y y可以用如下公式表示: y …...
字符串去重、集合遍历 题目
题目 JAVA38 字符串去重描述输入描述:输出描述: 示例:分析:代码:大佬代码: JAVA39 集合遍历描述输入描述:输出描述: 示例:分析:代码: JAVA38 字符串去重 描述 从键盘获取…...
SQL窗口函数详解
详细说明在sql中窗口函数是什么,为什么需要窗口函数,有普通的聚合函数了那窗口函数的意义在哪,窗口函数的执行逻辑是什么,over中的字句是如何使用和理解的(是不是句句戳到你的痛点,哼哼~&#x…...
如何用Java写一个整理Java方法调用关系网络的程序
大家好,我是猿码叔叔,一位 Java 语言工作者,也是一位算法学习刚入门的小学生。很久没有为大家带来干货了。 最近遇到了一个问题,大致是这样的:如果给你一个 java 方法,如何找到有哪些菜单在使用。我的第一想…...
基于STM32设计的管道有害气体检测装置(ESP8266局域网)176
基于STM32设计的管道有害气体检测装置(176) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成【3】ESP8266模块配置【4】上位机开发思路【5】项目模块划分【6】LCD显示屏界面布局【7】上位机界面布局1.2 项目功能需求1.3 项目开发背景1.4 开发工具的选择1…...
iCloud照片库全指南:云端存储与智能管理
iCloud照片库全指南:云端存储与智能管理 在数字化时代,照片和视频成为了我们生活中不可或缺的一部分。随着手机摄像头质量的提升,我们记录生活点滴的方式也越来越丰富。然而,这也带来了一个问题:如何有效管理和存储日…...
IDEA中使用Maven打包及碰到的问题
1. 项目打包 IDEA中,maven打包的方式有两种,分别是 install 和 package ,他们的区别如下: install 方式 install 打包时做了两件事,① 将项目打包成 jar 或者 war,打包结果存放在项目的 target 目录下。…...
TreeMap、HashMap 和 LinkedHashMap 的区别
TreeMap、HashMap 和 LinkedHashMap 的区别 1、HashMap2、LinkedHashMap3、TreeMap4、总结 💖The Begin💖点点关注,收藏不迷路💖 在 Java 中,TreeMap、HashMap 和 LinkedHashMap 是三种常用的集合类,它们在…...
【跟我学K8S】45天入门到熟练详细学习计划
目录 一、什么是K8S 核心功能 架构组件 使用场景 二、入门到熟练的学习计划 第一周:K8s基础和概念 第二周:核心对象和网络 第三周:进阶使用和管理 第四周:CI/CD集成和监控 第五周:实战模拟和案例分析 第六周…...
ubuntu下载Nginx
一、Nginx下载安装(Ubuntu系统) 1.nginx下载 sudo apt-get install nginx2.nginx启动 启动命令 sudo nginx重新编译(每次更改完nginx配置文件后运行): sudo nginx -s reload3.测试nginx是否启动成功 打开浏览器访问本机80端口…...
【区分vue2和vue3下的element UI Dialog 对话框组件,分别详细介绍属性,事件,方法如何使用,并举例】
在 Vue 2 和 Vue 3 中,Element UI(针对 Vue 2)和 Element Plus(针对 Vue 3)提供了 Dialog 对话框组件,用于在页面中显示模态对话框。这两个库中的 Dialog 组件在属性、事件和方法的使用上有所相似ÿ…...
docker push 推送镜像到阿里云仓库
1.登陆阿里云 镜像服务,跟着指引操作就行 创建个人实例,创建命名空间、镜像仓库,绑定代码源头 2.将镜像推送到Registry $ docker login --username*** registry.cn-beijing.aliyuncs.com $ docker tag [ImageId] registry.cn-beijing.aliy…...
伯克利、斯坦福和CMU面向具身智能端到端操作联合发布开源通用机器人Policy,可支持多种机器人执行多种任务
不同于LLM或者MLLM那样用于上百亿甚至上千亿参数量的大模型,具身智能端到端大模型并不追求参数规模上的大,而是指其能吸收大量的数据,执行多种任务,并能具备一定的泛化能力,如笔者前博客里的RT1。目前该领域一个前沿工…...
昇思25天学习打卡营第17天(+1)|Diffusion扩散模型
1. 学习内容复盘 本文基于Hugging Face:The Annotated Diffusion Model一文翻译迁移而来,同时参考了由浅入深了解Diffusion Model一文。 本教程在Jupyter Notebook上成功运行。如您下载本文档为Python文件,执行Python文件时,请确…...
【Leetcode笔记】406.根据身高重建队列
文章目录 1. 题目要求2.解题思路 注意3.ACM模式代码 1. 题目要求 2.解题思路 首先,按照每个人的身高属性(即people[i][0])来排队,顺序是从大到小降序排列,如果遇到同身高的,按照另一个属性(即p…...
Linux 安装pdfjam (PDF文件尺寸调整)
跟Ghostscript搭配使用,这样就可以将不同尺寸的PDF调整到相同尺寸合并了。 在 CentOS 上安装 pdfjam 需要安装 TeX Live,因为 pdfjam 是基于 TeX Live 的。以下是详细的步骤来安装 pdfjam: ### 步骤 1: 安装 EPEL 仓库 首先,安…...
python+playwright 学习-90 and_ 和 or_ 定位
前言 playwright 从v1.34 版本以后支持and_ 和 or_ 定位 XPath 中的and和or xpath 语法中我们常用的有text()、contains() 、ends_with()、starts_with() //*[text()="文本"] //*[contains(@id, "xx")] //...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
