使用ffmpeg制作时光影集

2023-11-17

目前QQ、剪影等都有照片制作成视频的功能。研究一段时间,始终不得要点。目前能实现的方式有h5动感影集、webv格式视频以及传统的ffmpeg进行照片合成剪辑。H5动感影集没办法导出成视频、webv对于视频的编辑依托于js。因此最终选择了利用ffmpeg来实现。由于语言使用的是C#,所以只能利用windows命令来调用。如果使用nodejs,可以使用封装好的方法fluent-ffmpeg。
对于ffmpeg的各类命令,可以在网上搜索出来。但是大都是满足某一场景,最好还是自己研究参数。进入ffmpeg的官网,里面对每一个属性都有说明和示例。http://ffmpeg.org/ffmpeg-all.html
本示例实现的是多张照片合成一个视频。照片实现的效果有渐入渐出、放大、移动、模糊处理,视频可以添加背景音乐。整体思路是,读取某一文件夹中的所有照片,逐个加入ffmpeg动效参数,然后拼接成一个长的命令字符串,使用Process命令行调用ffmpeg执行该命令。
具体效果如下:
核心代码如下:

     public static string GetCommand(string[] files)
{
    //string[] files = Directory.GetFiles("d:/yb/ffmpeg/pic/", "*.jpg");
    StringBuilder sbFile = new StringBuilder();
    StringBuilder sbFilter = new StringBuilder();
    StringBuilder sbConcat = new StringBuilder();
    int w = 540;
    int h = 720;
    int second = 4;
    for (int i = 0; i < files.Length; i++)
    {
        sbFile.Append(string.Format("-i {0} ", files[i]));
        Image img = Image.FromFile(files[i]);
        int th = img.Height * w / img.Width;
        int offset = (second - 1) * i;
        string fade = string.Empty;
        if (offset > 0)
        {
            fade = string.Format(",fade =in:d = 1:alpha = 1,setpts = PTS - STARTPTS + {0} / TB", offset);
        }

        // 如果是宽图片,则需要添加模糊背景,采用横向滚动的方式
        if (th < h * 0.8)
        {
            sbFilter.Append(string.Format(" [{0}]zoompan=d={1}:s={2}x{3}, boxblur=10{4}[bg{5}];", i, second * 25, w, h, fade, i));
            sbFilter.Append(string.Format("[{0}]zoompan=z='{1}':x='if(lte(on,-1),(iw-iw/zoom)/2,x+{2})':d={3}:s={4}x{5}{6}[v{7}];", i, 1.5, (1.5 - 1) * w / ((second+1) * 25), second * 25, w, th, fade, i));
            if (i > 0)
            {
                sbConcat.Append(string.Format("[c{0}][bg{1}]overlay[cc{2}];", i - 1, i, i));
                sbConcat.Append(string.Format("[cc{0}][v{1}]overlay=y=(H-h)/2[c{2}];", i, i, i));
            }
            else
            {
                sbConcat.Append(string.Format("[bg0][v0]overlay=y=(H-h)/2[c0];"));
            }
        }
        else
        {
            //长图,假设比例合适
            //sbFilter.Append(string.Format(" [{0}]zoompan=d={1}, boxblur=10{2}[bg{3}];", i, second * 25, fade, i));
            //sbFilter.Append(string.Format("[{0}]zoompan=z='{1}':x='if(lte(on,-1),(iw-iw/zoom)/2,x+{2})':d={3}:s={5}x{6}{7}[v{8}];", i, 1.3, (1.3 - 1) * w / (second + 1), second * 25, w, th, fade, i));
            string[] effects = { "z='min(max(zoom,pzoom)+0.0015,1.5)'", "z='if(lte(zoom,1.0),1.5,max(1.001,zoom-0.0015))':y='ih*(1-max(zoom,pzoom))'", "z='1.5':x='if(lte(on,-1),(iw-iw/zoom)/2,x+1.25)'", "z='1.5':y='if(lte(on,-1),(ih-ih/zoom)/2,y+1.25)'" };
           // Random rn = new Random();
            string effect = effects[i%4];
            sbFilter.Append(string.Format(" [{0}] zoompan =d = {1}:{2}:s={3}x{4}{5}[{6}];", i, 125, effect, w, h, fade, i == 0 ? "c0" : "v" + i));
            if (i > 0)
            {
                sbConcat.Append(string.Format("[c{0}][v{1}]overlay[c{2}];", i - 1, i, i));
            }
        }
    }
    sbFile.Append("-i d:/yb/ffmpeg/music/02.mp3 ");
    string concat = sbConcat.ToString();
    concat = concat.Substring(0, concat.LastIndexOf('['));
    string result = string.Format("-y {0} -filter_complex \"{1} {2}, format=yuv420p[v]\"  -map \"[v]\"  -map {3}:a -shortest -movflags +faststart {4}", sbFile.ToString(), sbFilter.ToString(), concat, files.Length, "d:/yb/ffmpeg/video/" + DateTime.Now.ToString("HHmmss") + ".mp4");
    return result;
}

重点参数解释:
模糊化效果
string.Format(" [{0}]zoompan=d={1}:s={2}x{3}, boxblur=10{4}[bg{5}];", i, second * 25, w, h, fade, i)
[0]:代表操作第一个图片;
[bg0]:代表将[0]第一个图片做成的视频命名为bg0;
zoompan:主要使用该属性来实现效果,d为总帧数,默认的fps为25帧,如果要设置一个5s的效果,那么d就可以设置为125;当然如果为了提高流畅度,可以这样设置一个5s的效果zoompan=d=300:fps=60; s代表第一个照片输出的尺寸,固定尺寸后可以放大再 进行移动。以上的命令字符串代表让第n个照片boxblue模糊后作为底层;
sbFilter.Append(string.Format(" [{0}]zoompan=d={1}:s={2}x{3}, boxblur=10{4}[bg{5}];", i, second * 25, w, h, fade, i));
sbFilter.Append(string.Format("[{0}]zoompan=z=’{1}’:x=‘if(lte(on,-1),(iw-iw/zoom)/2,x+{2})’:d={3}:s={4}x{5}{6}[v{7}];", i, 1.5, (1.5 - 1) * w / ((second+1) * 25), second * 25, w, th, fade, i));
let:小于等于;gte:大于等于。
将图片首先以背景模糊输出,然后在同一时间段覆盖上图片动效。效果如下:
在这里插入图片描述
sbConcat.Append(string.Format("[c{0}][bg{1}]overlay[cc{2}];", i - 1, i, i));
sbConcat.Append(string.Format("[cc{0}][v{1}]overlay=y=(H-h)/2[c{2}];", i, i, i));
合并视频,此处采用的是overlay覆盖合并,concat是顺序合并。将c0视频覆盖在bg0视频上,合并后的视频命名为cc0;将cc0视频合并到v0视频上,位置是垂直居中;
fade = string.Format(",fade =in:d = 1:alpha = 1,setpts = PTS - STARTPTS + {0} / TB", offset);
fade是渐入渐出的控制;in/out渐入/减出;d=1为渐变时间持续1s;setpts 是为了让第一个视频渐出的时间和第二个视频渐入的时间进行重叠,不至于突然变黑很突兀。setpts = PTS - STARTPTS + {0} / TB,offset是第二个视频渐入的时间,比如两个5s的视频,该值应该这是为4,在第4秒进行渐入;
代码可在此处下载https://download.csdn.net/download/wuwo333/12500865

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用ffmpeg制作时光影集 的相关文章

随机推荐

  • 2016阿里云121款产品和解决方案全向图(9月制)

    2016阿里云121款产品和解决方案全向图 9月制 摘要 云栖社区在9月底又更新了 2016阿里云产品全向图和解决方案全向图 导语 DT时代 一切都将走向数据化 可视化 在阿里云所阐述的 技术拓展商业的边界 商业驱动技术的变革 理念中 密集
  • 汇编语言(王爽第三版) 实验5编写、调试具体多个段的程序

    参考 http blog sina com cn s blog 171daf8e00102xclx html 汇编语言实验答案 王爽 https wenku baidu com view a1cd7c6c1fb91a37f111f18583
  • muduo网络库学习笔记(13):TcpConnection生命期的管理

    本篇通过分析muduo中TcpConnection对断开连接事件的处理 来学习muduo网络库对TcpConnection生命期的管理 TcpConnection对连接断开事件的处理 首先 我们来看一下TcpConnection处理连接断开
  • 华为OD题目: 整理扑克牌

    package com darling boot order od od12 import java util 整理扑克牌 题目描述 给定一组数字 表示扑克牌的牌面数字 忽略扑克牌的花色 请按如下规则对这一组扑克牌进行整理 步骤1 对扑克牌
  • 关于Bert被质疑利用“虚假统计性提示”的ACL论文

    曾经狂扫11项记录的谷歌NLP模型BERT 近日遭到了网友的质疑 该模型在一些基准测试中的成功仅仅是因为利用了数据集中的虚假统计线索 如若不然 还没有随机的结果好 这项研究已经在Reddit得到了广泛的讨论 引用自 新智元 真的不想那么标题
  • 社会中的学费

    上学期间 我们交学费是为了学习课本知识 我们也确实从中学到了很多有用的东西 这些学费我们觉得是物有所值的 当我们踏入社会的时候 我们也是要向社会交一定的学费 这种学费 我们能够学到的东西就是社会经验 这是东西是无形的 我们总会觉得自己的钱没
  • ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29‘ not foun

    复现代码过程中 无意间出现这个问题 本以为很好解决 没想到还是花了我好几个小时的时间 总结一下趴 我的环境是cuda11 3 python3 9 pytoch1 10 问题如图 图1 bug示意图 在网上找了很多答案 要么就是没说清的 要么
  • HTTPS网络编程——S代表SSL协议也叫TLS协议

    参考 HTTPS简介以及SSL协议详解 地址 https qingmu blog csdn net article details 108209248 spm 1001 2014 3001 5502 目录 1 HTTPS简介 2 SSL协议
  • stm32 的 ESP8266 wifi 模块 (ESP - 12s) 的使用

    1 ESP8266 的器件介绍 2 ESP2866外设 的引脚 3 我所用的的ESP2866 的引脚图 4 代码 编程的串口 5 wifi 的指令 1 AT 测试指令 2 AT RST 重启模块 3 AT GMR 查看版本信息 4 AT R
  • 家政行业丨制作便捷高效的家政小程序

    随着现代生活节奏的加快和家庭需求的多样化 越来越多的人开始寻找一种更方便 更高效的方式来获取家政服务 而家政小程序的兴起为这一需求提供了理想的解决方案 本文将简要介绍家政小程序是什么 探讨家政小程序的好处 并提供一些制作搭建家政小程序的方法
  • 【Python】记录一次 Linux + Python + RocketMQ 辛酸历程

    文章目录 安装Python 准备环境 编译安装 遇到问题 安装openssl 重新编译 安装依赖库 准备代码 验证 这是记录一次辛酸的Linux Python RocketMQ使用历程 需求背景是需要验证线上一个RocketMQ服务和里面的
  • 2014.12.17笔记

    我记得科学松鼠会的姬十三曾在一篇文章中写到 开始干一件好事情就像拿着锣一敲 然后志同道合的人就从四面八方赶来 开源之美 仅在于此 不要问怎么入门 直接上路吧 您刚才那个问题是说大数据跟人工智能和深度学习怎么划等号 是这么一个关系 大数据是一
  • XML可扩展标记语言

    XML可扩展标记语言 XML ExtensibleMarkup Language 可扩展标记语言是一种基于文本的格式用于展示结构化的信息 主要用于传输和存储数据 属于W3C World Wide Web Consortium 标准 XML的
  • hdfs怎么处理小文件问题

    一 HAR文件方案 为了缓解大量小文件带给namenode内存的压力 Hadoop 0 18 0引入了Hadoop Archives HAR files 其本质就是在HDFS之上构建一个分层文件系统 通过执行hadoop archive 命
  • 递归下降算法语法分析c语言

    递归下降算法 自上而下文法的递归下降的预测分析 从根节点出发逐步构造分析树 所以被称作自上而下文法 在文法中有递归的函数 例如 E gt TE 所以叫做递归下降算法 使用的文法如下 E gt TE E gt TE e T gt FT T g
  • fcfs调度算法_使用C程序实现先到先服务(FCFS)CPU调度算法

    fcfs调度算法 CPU scheduling decides which of the available processes in the ready queue is to be allocated the CPU There are
  • ORACLE 序列sequence小结

    创建序列语法 需要获取相应的权限 create sequence NAME INCREMENT BY START WITH integer 初始值和递增间隔 MAXVALUE integer NOMAXVALUE 上界或无上界 MINVAL
  • python实训报告心得体会-Python学习心得体会

    首先最开始 我们要明确一点 学习编程不是一日之功 需要每天投入时间学习 也不可纸上谈兵 需要自己亲自操作 不动手就不会发现问题 动了手印象才会深刻 记得更靠 接下来我就稍微总结一下 我在学习中遇到的问题和一些心得体会 1 修改字符串大小写时
  • WPS插件开发流程(1)

    OneKey Lite是一款由 只为设计 独立开发的WPS演示免费插件 在开发过程中 感恩于网上那些无私分享代码的陌生人 给我这个开发小白提供了重要的借鉴参考 于是我决定把用C 和Visual Studio开发WPS插件的每一个具体步骤分享
  • 使用ffmpeg制作时光影集

    目前QQ 剪影等都有照片制作成视频的功能 研究一段时间 始终不得要点 目前能实现的方式有h5动感影集 webv格式视频以及传统的ffmpeg进行照片合成剪辑 H5动感影集没办法导出成视频 webv对于视频的编辑依托于js 因此最终选择了利用