c#文案语音配图片一键生成视频

高手略过吧,功能太简单,我自己都不好意思。。

这个是我自己的需要,做产品类的短视频,东搞西搞剪辑啊啥的,特别麻烦,所以先搞这个最简版,以后再一步步丰富功能。

需求:几张图片生成视频,视频长度以文案内容生成的语音为准。

c#准备数据即视频每一帧的图片和文案生成的语音,最后调用ffmpeg生成视频,顺序如下:

1、准备数据文件,约定第一行为文案文本,用这个生成语音文件,作视频配音,其他行为图片文件名。

 2、解析数据文件,拿到文案文本和图片数组

private bool Parse()
        {
            if (!System.IO.File.Exists("source\\data.txt"))
            {
                log("找不到数据文件data.txt");
                return false;
            }            
            int i = 0;
            Image img;
            ImgFileList = new List<string>();
            foreach (string line in System.IO.File.ReadLines("source\\data.txt"))
            {
                if (i++ == 0)
                {
                    wenzi = line;
                    continue;
                }
                if (!System.IO.File.Exists(line))
                {
                    log("文件:" + line + ",不存在");
                    continue;
                }
                img = Image.FromFile(line);
                if (img == null)
                {
                    log("文件:" + line + ",不是图片");
                    continue;
                }
                img.Dispose();
                ImgFileList.Add(line);
            }
            return ImgFileList.Count > 0;
        }

3,调用百度api,生成语音,存放到data\ee.mp3,返回语音长度。

private bool GetBaiDuAudio(string str,out int len,out string filename)
        {
            //这里换成你自己的百度key
            const string API_KEY = "asdfasdfasdfasfdasfd";
            const string SECRET_KEY = "asdfasdfasfdasfd";
            var client = new Baidu.Aip.Speech.Tts(API_KEY, SECRET_KEY);
            client.Timeout = 60000;  // 修改超时时间

            // 可选参数
            var option = new Dictionary<string, object>()
            {
                {"spd", 5}, // 语速
                {"vol", 5}, // 音量
                {"per", 103},  // 发音人,4:情感度丫丫童声                
            };
            var result = client.Synthesis(str, option);
            if (result.ErrorCode == 0)  // 或 result.Success
            {
                //取得当前路径
                string path = System.AppDomain.CurrentDomain.BaseDirectory;                
                if (!Directory.Exists(path + "data"))
                {
                    Directory.CreateDirectory(path + "data");
                }
                File.WriteAllBytes("data\\ee.mp3", result.Data);
                len = Mp3.GetLength("data\\ee.mp3");
                filename = "data\\ee.mp3";
                return true;
            }
            len = 0;
            filename = "";
            return false;
        }

这里吐槽下百度生成的mp3,ffmpeg -i ee.mp3,居然拿不到长度,为了拿到这个长度,费了好长时间,获取mp3长度代码如下:

 public class APIClass
    {

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        // 获取短文件名
        public static extern int GetShortPathName(
            string lpszLongPath,
            string shortFile,
            int cchBuffer
            );

        [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
        public static extern int mciSendString(
            string lpstrCommand,
            string lpstrReturnString,
            int uReturnLength,
            int hwndCallback
            );
    }
    class Mp3
    {
        public static int GetLength(string filename)
        {
            string Name = "";
            Name = Name.PadLeft(260, Convert.ToChar(" "));
            APIClass.GetShortPathName(filename, Name, Name.Length);
            Name = GetCurrPath(Name);
            Name = "open " + Convert.ToChar(34) + Name + Convert.ToChar(34) + " alias media";
            APIClass.mciSendString(Name, "", 0, 0);
            string durLength = "";
            durLength = durLength.PadLeft(128, Convert.ToChar(" "));
            APIClass.mciSendString("status media length", durLength, durLength.Length, 0);
            APIClass.mciSendString("close media", "", 128, 0);
            APIClass.mciSendString("close all", "", 128, 0);
            durLength = durLength.Trim();
            if (durLength == "") return 0;
            return (int)(Convert.ToDouble(durLength)); 
        }
        private static string GetCurrPath(string name)
        {
            if (name.Length < 1) return "";
            name = name.Trim();
            name = name.Substring(0, name.Length - 1);
            return name;
        }
    }

Mp3.GetLength函数返回的是毫秒。

4、根据mp3的长度来计算生成多少帧图片,源图片每张又生成多少张,最后生成图片。

图片总数:mp3长度/40,1000/40=25,我们按照每秒25帧来计算。

private void CreateImg()
        {
            //audion是百度音频长度,单位毫秒
            //几张图片平均分布,按照每秒25帧来算是,就是40毫秒一张图片
            int photon = audiolen / ImgFileList.Count / 40;
            string file, extname, newfile;
            int n;
            int counta = 1;
            //在data目录下生成1-n.jpg
            for (int i = 0; i < ImgFileList.Count; i++)
            {
                file = ImgFileList[i];
                n = file.LastIndexOf(".");
                extname = file.Substring(n, file.Length - n);
                for (int j = 0; j < photon; j++)
                {
                    newfile = "data\\" + counta + extname;
                    File.Copy(file, newfile);
                    counta++;
                }
            }
        }

生成图片如下

5,调用ffmpeg命令行生成视频

命令:ffmpeg -f image2 -i data\\%d.jpg -i data\\ee.mp3 data\output.mp4

private string CreateVideo()
        {
            string DstFile = "data\\output.mp4";
            string strCmd = string.Format("-f image2 -i {0} -i {1} {2} -y", "data\\%d.jpg", audiofile, DstFile);
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "ffmpeg.exe";//要执行的程序名称
            p.StartInfo.Arguments = " " + strCmd;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = false;//可能接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = false;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = false;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = false;//不显示程序窗口

            p.Start();//启动程序
            p.WaitForExit();//等待程序执行完退出进程

            if (System.IO.File.Exists(DstFile))
            {
                return DstFile;
            }
            return "";
        }

6、运行图面

 至此视频文件就生成了,视频长度与音乐长度完全匹配。

代码已经上传到我的资源。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全行业0-5年规划,零基础如何入门网络渗透?

前言 网络安全这个行业优势有&#xff1a;需求量大&#xff0c;人才紧急&#xff0c;门槛低&#xff0c;工资高。对于许多未曾涉足IT行业「小白」来说&#xff0c;深入地学习网络安全是一件十分困难的事。 关于我 本人是一位90后奇安信驻场网络安全工程师。上海交通大学软件…

Web前端学习:章四 -- JavaScript初级(四)-- BOM

138&#xff1a;Object数据格式简介 1、object对象 JS中独有 的一种数据格式 名字可以随便取&#xff0c;值一般就那几种数据格式 139&#xff1a;BOM - JS跳转页面 BOM Browser Object Model&#xff1a;浏览器对象模型 使用JavaScript控制浏览器交互 控制浏览器里面的内…

【数据结构与算法】队列和栈的相互实现以及循环队列

目录&#x1f314;一.用队列实现栈&#x1f319;1.题目描述&#x1f319;2.思路分析&#x1f319;3.代码实现⛈二.用栈实现队列☔1.题目描述☔2.思路分析☔3.代码实现&#x1f308;三.实现循环队列&#x1f314;一.用队列实现栈 &#x1f319;1.题目描述 我们先看一下题目链接…

大数据技术之Hive SQL题库-初级

第一章环境准备1.1 建表语句hive>-- 创建学生表 DROP TABLE IF EXISTS student; create table if not exists student_info(stu_id string COMMENT 学生id,stu_name string COMMENT 学生姓名,birthday string COMMENT 出生日期,sex string COMMENT 性别 ) row format delim…

STM32学习(九)

IWDG的本质 Independent watchdog&#xff0c;即独立看门狗。 本质是&#xff1a;能产生系统复位信号的计时器。 递减的计数器。时钟由独立的RC振荡器提供&#xff08;不是来自于主时钟HSE或HSI&#xff09;&#xff0c;可在待机或者停止模式下运行。看门狗被激活后&#xff…

【云原生 • Docker】cAdvisor+Prometheus+Grafana 10分钟搞定Docker容器监控平台

文章目录cAdvisorPrometheusGrafana 10分钟搞定Docker容器监控平台cAdvisor部署Prometheus部署Grafana部署cAdvisorPrometheusGrafana 10分钟搞定Docker容器监控平台 cAdvisor(Container Advisor) 是 Google 开源的一个容器监控工具&#xff0c;可用于对容器资源的使用情况和性…

【网络安全必备知识】本地提权漏洞分析

0. 前言 CVE-2023-21752 是 2023 年开年微软第一个有 exploit 的漏洞&#xff0c;原本以为有利用代码会很好分析&#xff0c;但是结果花费了很长时间&#xff0c;难点主要了两个&#xff1a;漏洞点定位和漏洞利用代码分析&#xff0c;欢迎指正。 1. 漏洞简介 根据官方信息&a…

【数据结构】二叉树的遍历以及基本操作

目录 1.树形结构 1.概念 2.二叉树 2.1概念 2.2 两种特殊的二叉树 2.3二叉树的存储 2.4二叉树的基本操作 1.手动快速创建一棵简单的二叉树 2.二叉树的遍历 (递归) 3.二叉树的层序遍历 4.获取树中节点的个数 5.获取叶子节点的个数 6.获取第K层节点的个数 7.获取二叉…

Python深度学习实战:人脸关键点(15点)检测pytorch实现

引言 人脸关键点检测即对人类面部若干个点位置进行检测&#xff0c;可以通过这些点的变化来实现许多功能&#xff0c;该技术可以应用到很多领域&#xff0c;例如捕捉人脸的关键点&#xff0c;然后驱动动画人物做相同的面部表情&#xff1b;识别人脸的面部表情&#xff0c;让机…

线程池的讲解和实现

&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;大家好,今天为大家带来线程池相关知识的讲解,并且实现一个线程池 &#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;…

DM的学习心得和知识总结(一)|DM数据库Real Application Testing之Database Reply实操(一)

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、达梦数据库产品及解决方案&#xff0c;点击前往 2、达梦技术文档&#xff0c;点击前往 3、武汉达梦数据库有限公司 官网首页&#xff0c;点击前往 1、本文内容全部…

OpenFeign#1 - FeignClient 是如何注册的?

文章目录EnableFeignClientsFeignClientsRegistrarregisterDefaultConfigurationregisterFeignClientsFeignClientFeignClientFactoryBeanFeignContextfeign(FeignContext)EnableFeignClients 该注解会导致 FeignClientsRegistrar 的注入. Retention(RetentionPolicy.RUNTIME…

如何用canvas制作一个华容道小游戏(乞丐版)

我大抵是废了φ(&#xff0e;&#xff0e;) &#xff0c;横竖都学不进去&#xff0c;上课知识不进脑子&#xff0c;学习光想划水摸鱼&#xff0c;心中仅剩的良知告诉我这样下去是铁定不行的哇&#xff0c;既然学不进去&#xff0c;何不打把游戏&#xff0c;既然要打游戏&#x…

HTML5 Video(视频)

HTML5 Video(视频) 在本节内容中&#xff0c;你将了解到在HTML5中视频是如何工作的、主流浏览器支持的视频格式以及如何对网页中的视频进行控制。 很多站点都会使用到视频. HTML5 提供了展示视频的标准。 检测您的浏览器是否支持 HTML5 视频&#xff1a; Web站点上的视频 直…

SeNet论文解读/总结

此文章为深度学习在计算机视觉领域的图片分类经典论文SeNet&#xff08;Squeeze-and-Excitation Networks&#xff09;论文总结。 此系列文章是非常适合深度学习领域的小白观看的图像分类经典论文。系列文章如下&#xff1a; AlexNet&#xff1a;AlexNet论文解读/总结_alexnet…

在CentOS上安装Docker引擎

1,先决条件#### 1-1操作系统要求1-2 卸载旧版本 2,安装方法2-1使用存储库安装设置存储库安装 Docker 引擎 本文永久更新地址: 官方地址&#xff1a;https://docs.docker.com/engine/install/centos/ 1,先决条件 #### 1-1操作系统要求 要安装 Docker Engine&#xff0c;您需要…

【基础算法】链表相关题目

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招算法的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于代码随想录进行的&#xff0c;每个算法代码参考leetcode高赞回答和…

官宣|Apache Flink 1.17 发布公告

Apache Flink PMC&#xff08;项目管理委员&#xff09;很高兴地宣布发布 Apache Flink 1.17.0。Apache Flink 是领先的流处理标准&#xff0c;流批统一的数据处理概念在越来越多的公司中得到认可。得益于我们出色的社区和优秀的贡献者&#xff0c;Apache Flink 在 Apache 社区…

STM32F407控制微型推拉式电磁铁(通过继电器)

1、继电器 继电器相当于开关&#xff0c;单片机通过io口高低电平的控制来控制继电器的开闭。采用继电器的好处除了能够用低电压控制高电压&#xff08;如32单片机控制220V的电压&#xff09;外&#xff0c;还可以防止电流反冲&#xff0c;弄烧单片机。 本文采用3.3v的电磁铁&am…

三、MyBatis核心配置文件详解

核心配置文件中的标签必须按照固定的顺序(有的标签可以不写&#xff0c;但顺序一定不能乱)&#xff1a; properties、settings、typeAliases、typeHandlers、objectFactory、objectWrapperFactory、reflectorFactory、plugins、environments、databaseIdProvider、mappers 一、…