【FFmpeg学习】视频变慢处理

news/发布时间2024/6/8 2:18:48

视频慢动作处理是个比较常用的操作,可以在播放的时候处理,这里我们考虑把视频修改为慢动作,使用ffmpeg命令,可以这样

ffmpeg -i test.mp4 -vf "setpts=5*PTS" -an test_slow3.mp4

这里把视频放慢了5倍,生成的文件大小也变大了几倍。

怎么用程序来实现呢,参考一下GPT给出的code,

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
}// 慢速播放的速度因子
const double SLOWDOWN_FACTOR = 2.0;int main(int argc, char* argv[]) {if (argc < 3) {std::cout << "Usage: " << argv[0] << " input_file output_file" << std::endl;return 1;}const std::string inputFileName = argv[1];const std::string outputFileName = argv[2];av_register_all();AVFormatContext* inputFormatContext = nullptr;if (avformat_open_input(&inputFormatContext, inputFileName.c_str(), nullptr, nullptr) != 0) {std::cerr << "Failed to open input file: " << inputFileName << std::endl;return 1;}if (avformat_find_stream_info(inputFormatContext, nullptr) < 0) {std::cerr << "Failed to retrieve input stream information" << std::endl;avformat_close_input(&inputFormatContext);return 1;}AVFormatContext* outputFormatContext = nullptr;if (avformat_alloc_output_context2(&outputFormatContext, nullptr, nullptr, outputFileName.c_str()) < 0) {std::cerr << "Failed to allocate output format context" << std::endl;avformat_close_input(&inputFormatContext);return 1;}for (unsigned int i = 0; i < inputFormatContext->nb_streams; ++i) {AVStream* inputStream = inputFormatContext->streams[i];AVStream* outputStream = avformat_new_stream(outputFormatContext, nullptr);if (!outputStream) {std::cerr << "Failed to allocate output stream" << std::endl;avformat_close_input(&inputFormatContext);avformat_free_context(outputFormatContext);return 1;}if (avcodec_parameters_copy(outputStream->codecpar, inputStream->codecpar) < 0) {std::cerr << "Failed to copy codec parameters" << std::endl;avformat_close_input(&inputFormatContext);avformat_free_context(outputFormatContext);return 1;}outputStream->time_base = inputStream->time_base;}if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {if (avio_open(&outputFormatContext->pb, outputFileName.c_str(), AVIO_FLAG_WRITE) < 0) {std::cerr << "Failed to open output file: " << outputFileName << std::endl;avformat_close_input(&inputFormatContext);avformat_free_context(outputFormatContext);return 1;}}if (avformat_write_header(outputFormatContext, nullptr) < 0) {std::cerr << "Failed to write output file header" << std::endl;avformat_close_input(&inputFormatContext);avformat_free_context(outputFormatContext);return 1;}AVPacket packet;while (av_read_frame(inputFormatContext, &packet) >= 0) {AVStream* outputStream = outputFormatContext->streams[packet.stream_index];// 慢速播放的时间戳调整packet.pts *= static_cast<int64_t>(SLOWDOWN_FACTOR);packet.dts *= static_cast<int64_t>(SLOWDOWN_FACTOR);packet.duration = static_cast<int>(packet.duration * SLOWDOWN_FACTOR);av_interleaved_write_frame(outputFormatContext, &packet);av_packet_unref(&packet);}av_write_trailer(outputFormatContext);avformat_close_input(&inputFormatContext);avformat_free_context(outputFormatContext);return 0;
}

这个代码执行后并没有实现变慢,参考一下,进行修改后可以实现慢动作处理,如下


int slow() {std::string filename = "test.mp4";     // 输入MP4文件名std::string outputFilename = "test_slow.mp4";  // 输出图片文件名AVFormatContext* ofmt_ctx = nullptr;avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, outputFilename.c_str());const AVOutputFormat* ofmt = ofmt_ctx->oformat;AVFormatContext* formatContext = nullptr;if (avformat_open_input(&formatContext, filename.c_str(), nullptr, nullptr) != 0) {std::cerr << "Error opening input file" << std::endl;return -1;}if (avformat_find_stream_info(formatContext, nullptr) < 0) {std::cerr << "Error finding stream information" << std::endl;avformat_close_input(&formatContext);return -1;}const AVCodec* codec = nullptr;int videoStreamIndex = -1;for (unsigned int i = 0; i < formatContext->nb_streams; i++) {if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {videoStreamIndex = i;codec = avcodec_find_decoder(formatContext->streams[i]->codecpar->codec_id);//AVStream* out_stream = avformat_new_stream(ofmt_ctx, NULL);avcodec_parameters_copy(out_stream->codecpar, formatContext->streams[i]->codecpar);out_stream->codecpar->codec_tag = 0;break;}}avio_open(&ofmt_ctx->pb, outputFilename.c_str(), AVIO_FLAG_WRITE);avformat_write_header(ofmt_ctx, NULL);AVPacket packet;av_init_packet(&packet);// 计算目标时间戳int64_t targetTimestamp = targetSecond * AV_TIME_BASE;// 查找目标时间戳所对应的帧AVFrame* frame = av_frame_alloc();bool foundTargetFrame = false;int count = 0;while (av_read_frame(formatContext, &packet) >= 0) {if (packet.stream_index == videoStreamIndex) {AVStream* inputStream = formatContext->streams[packet.stream_index];AVStream* outputStream = ofmt_ctx->streams[packet.stream_index];// 计算新的时间戳cout << "1, pts=" << packet.pts << endl;packet.pts = av_rescale_q_rnd(packet.pts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF);packet.dts = av_rescale_q_rnd(packet.dts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF);packet.duration = av_rescale_q(packet.duration, inputStream->time_base, outputStream->time_base);packet.pos = -1;cout << "2, pts=" << packet.pts << endl;// 慢速播放的时间戳调整packet.pts *= 5;packet.dts *= 5;packet.duration *= 5;//          av_log(NULL, AV_LOG_INFO, "...av_write_frame(ofmt_ctx, packet);\n");int ret = av_write_frame(ofmt_ctx, &packet);if (ret < 0) {std::cerr << "Error av_write_frame" << std::endl;}count++;}av_packet_unref(&packet);}av_write_trailer(ofmt_ctx);return 1;
}

通过pts的修改来实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/yOkJ/289.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

Linux:信号的处理

文章目录 信号处理 本篇总结的是关于信号的处理 信号处理 在之前有这样的观点&#xff1a;信号在合适的时候被处理好&#xff0c;当进程收到信号后&#xff0c;当前进程可能在做优先级更高的事&#xff0c;所以它来不及处理这个信号&#xff0c;那么就会把这个信号暂时保存起…

解读OpenAI视频生成模型Sora背后的原理:Diffusion Transformer

Diffusion Models视频生成-博客汇总 前言&#xff1a;OpenAI最近推出的视频生成模型Sora在效果上实现了真正的遥遥领先&#xff0c;很多博主都介绍过Sora&#xff0c;但是深入解读背后原理的博客却非常少。Sora的原理最主要的是核心模型主干《Scalable Diffusion Models with T…

2024.2.10 HCIA - Big Data笔记

1. 大数据发展趋势与鲲鹏大数据大数据时代大数据的应用领域企业所面临的挑战和机遇华为鲲鹏解决方案2. HDFS分布式文件系统和ZooKeeperHDFS分布式文件系统HDFS概述HDFS相关概念HDFS体系架构HDFS关键特性HDFS数据读写流程ZooKeeper分布式协调服务ZooKeeper概述ZooKeeper体系结构…

【精品】关于枚举的高级用法

枚举父接口 public interface BaseEnum {Integer getCode();String getLabel();/*** 根据值获取枚举** param code* param clazz* return*/static <E extends Enum<E> & BaseEnum> E getEnumByCode(Integer code, Class<E> clazz) {Objects.requireNonN…

[嵌入式系统-16]:RT-Thread -2- 主要功能功能组件详解与API函数说明

目录 一、RT-Thread主要功能组件 二、内核组件 2.1 概述 2.2 API 三、设备驱动 3.1 概述 3.2 API 四、通信组件 4.1 概述 4.4 API 五、网络组件 5.1 概述 5.2 API 5.3 补充&#xff1a;MQTT协议 六、文件系统 6.1 概述 6.2 API 七、GUI 组件 7.1 概述 7.2 …

外包干了10个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

【漏洞复现-通达OA】通达OA video_file.php 任意文件下载漏洞

一、漏洞简介 通达OA video_file.php文件存在任意文件下载漏洞&#xff0c;攻击者通过漏洞可以读取服务器敏感文件。 二、影响版本 ● 通达OA2011 三、资产测绘 ● hunterapp.name"通达 OA" ● 特征 四、漏洞复现 GET /general/mytable/intel_view/video_file.…

vmware workstation群晖虚拟机vmdk文件导出

为了防止群晖虚拟机中整个挂掉&#xff0c;里面的文件导不出来&#xff0c;尝试直接从vmdk中获取内容。 1、想采用diskgenius去读取文件&#xff0c;发现volume1是空的。只能读取群晖的系统文件。 2、选择另一个linux系统的虚拟机&#xff0c;选择对应的vmdk 3、如果有文件管理…

ElasticSearch之Mapping

写在前面 本文看下es的mapping的设置。es支持两种mapping&#xff0c;一种式dynamic mapping&#xff0c;另外一种是显式的mapping设置。分别来看下。 在正式开始之前我们需要先看下es提供的字段数据类型: 1&#xff1a;dynamic mapping 我们在使用关系型数据库的时候必须…

选择大语言模型:2024 年开源 LLM 入门指南

作者&#xff1a;来自 Elastic Aditya Tripathi 如果说人工智能在 2023 年起飞&#xff0c;这绝对是轻描淡写的说法。数千种新的人工智能工具被推出&#xff0c;人工智能功能被添加到现有的应用程序中&#xff0c;好莱坞因对这项技术的担忧而戛然而止。 甚至还有一个人工智能工…

notepad++打开文本文件乱码的解决办法

目录 第一步 在编码菜单栏下选择GB2312中文。如果已经选了忽略这一步 第二步 点击编码&#xff0c;红框圈出来的一个个试。我切换到UTF-8编码就正常了。 乱码如图。下面分享我的解决办法 第一步 在编码菜单栏下选择GB2312中文。如果已经选了忽略这一步 第二步 点击编码&#…

Vector - CANoe - CAPL重启VN设备退出BusOff

在总线测试中进行BusOff测试的时候&#xff0c;偶尔会遇到将Vector工具链下的VN系列设备进入到BusOff状态&#xff0c;这个时候我们就只能重启CANoe才能将VN系列设备进行重启&#xff0c;才可以再次在Trace窗口上看到发送和接收的报文。不过在某些特定的情况的下&#xff0c;我…

FPGA_简单工程_拨码开关

一 框图 二 波形图 三 代码 3.1 工程代码 module bomakiaguan (input [15:0] switch, // 输入16路拨码开关output reg [15:0] led // 输出16个LED灯 );always (switch) beginled < switch; // 将拨码开关的值直接赋给LED灯 end // 将拨码开关的值直接赋给LED灯 endmodu…

深度学习技巧应用37-模型训练过程中训练曲线的观察方法与超参数随机搜索方法

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用37-模型训练过程中训练曲线的观察方法与超参数随机搜索方法。观察训练曲线可以帮助了解模型性能和诊断问题,如过拟合或欠拟合。超参数随机搜索是一种自动选择最优超参数组合的方法,通过在给定空间内随机选择超参数组合…

【机器学习笔记】14 关联规则

关联规则概述 关联规则&#xff08;Association Rules&#xff09;反映一个事物与其他事物之间的相互依存性和关联性。如果两个或者多个事物之间存在一定的关联关系&#xff0c;那么&#xff0c;其中一个事物就能够通过其他事物预测到。 关联规则可以看作是一种IF-THEN关系。…

github使用问题汇总

1. Permission denied 1.1. 问题描述 Permission denied (publickey). fatal: Could not read from remote repository. 1.2. 解决方法 生成公钥 ssh-keygen -t ed25519 -C "your_emailexample.com" 点击回车三次 Generating public/private ed25519 key pair. …

自动化AD域枚举和漏洞检测脚本

linWinPwn 是一个 bash 脚本&#xff0c;可自动执行许多 Active Directory 枚举和漏洞检查。该脚本基于很多现有工具实现其功能&#xff0c;其中包括&#xff1a;impacket、bloodhound、netexec、enum4linux-ng、ldapdomaindump、lsassy、smbmap、kerbrute、adidnsdump、certip…

WordPress主题YIA在广告位添加图片广告时下方有空白怎么办?

YIA主题设置中默认有4个广告位&#xff0c;而侧边栏的广告位由站长自行添加。boke112百科在这些广告位添加图片广告后发现图片下方有空白&#xff0c;导致下方的两个角没有变圆角&#xff0c;看起来也有点不好看。具体如下图所示&#xff1a; 其实&#xff0c;这个问题就是典型…

鸿蒙系统优缺点,能否作为开发者选择

凡是都有对立面&#xff0c;就直接说说鸿蒙的优缺点吧。 鸿蒙的缺点&#xff1a; 鸿蒙是从2019年开始做出来的&#xff0c;那时候是套壳Android大家都知晓。从而导致大家不看鸿蒙系统&#xff0c;套壳Android就是多次一举。现在鸿蒙星河版已经是纯血鸿蒙&#xff0c;但是它的…

Linux ipvlan详解(l2、l3、l3s和bridge、private和vepa模式)

Linux ipvlan详解&#xff0c;测试l2、l3、l3s和bridge、private和vepa模式。 最近在看Docker的网络&#xff0c;看到关于ipvlan网络的介绍。查阅了相关资料&#xff0c;记录如下。 参考 1.图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN 2.IPVlan 详…
推荐文章