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

2023-05-16

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

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

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

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、运行图面

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

项目源码:https://download.csdn.net/download/xchenbb/87608144

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

c#文案语音配图片一键生成视频 的相关文章

随机推荐

  • 一个程序员的一生

    一个程序员的一生 作者 佚名 我在程序员的时候 xff0c 我一开始追逐这个API怎么用 xff0c 数据库SQL怎么写更优化 xff0c Dcom技术的细节 xff0c 然后我发现我写出来的产品为了符合客户 需求必须要大量修改 xff0c
  • E: Package ‘cmake‘ has no installation candidate

    在ubuntu中使用 sudo apt get install cmake 报错 xff1a E Package 39 cmake 39 has no installation candidate 解决方法 xff1a sudo apt g
  • 函数程序设计实验五:打印购物小票

    module HaskellStore where import Text Printf type Items 61 Item type Item 61 Name Amount Price type Name 61 String type
  • CSS实战——百度搜索首页

    成果 支持搜索内容 步骤 一般来说 xff1a 使用css 43 div进行页面的布局 xff0c css一般是用外联进行开发使用html进行每一个页面的填充 注意事项 id的命名规范 xff1a 父标签id 自己的idcss一般一个选择器
  • UNIX环境高级编程

    环境配置 1 下载apue 3e文件夹 xff0c 可以通过http www apuebook com code3e html现在源码 2 解压后执行进入apue 3e中执行make指令 如果出现 96 96 96 collect2 err
  • 常见的亮灭屏流程分析

    一 亮屏主要关键log 驱动按键时间 lt 3 gt 14082 058160 0 70 pmic thread kpd Power Key generate pressed 61 1 上层按键时间 09 25 15 13 07 19666
  • 冒烟测试和回归测试的区别

    每次新的版本出来的时候 xff0c 老大就让我们 冒烟 虽然不知道冒烟测试的含义 xff0c 但由于没有给用例 xff0c 我就随便跑跑 跑完冒烟后 xff0c 老大就让做 回归测试 xff0c 把bug回归掉 但是其实对2个概念还是不太理
  • 老旧电脑在虚拟机安装ubuntu运行环境的步骤及注意事项

    花了一天的时间在我的老电脑上用虚拟机装上了ubuntu xff0c 多灾多难 xff0c 记录一下问题和注意事项 老电脑的配置 xff1a cpu xff1a Intel Core TM 2 Duo CPU E7500 64 2 93GHz
  • x11vnc

    x11vnc display 0 auth guess rfbport 5900 forever shared noxdamage noncache repeat amp auth 关窗口退出 auth guess 关窗口不退出 用户注销退
  • 多个生产者和消费者线程

    span class token comment 作者 xff1a kuma 版本 xff1a v1 0 span span class token keyword public span span class token keyword
  • C/C++ 开源库及示例代码

    C C 43 43 开源库及示例代码 说明 本页面汇总俺收集的各种 C 和 C 43 43 的开源代码库 xff0c 不定期更新 如果你发现本页面的开源库有错漏之处 xff0c 非常欢迎给俺提供反馈 有 GitHub 帐号的同学 xff0c
  • UEFI分区的重建办法,不需要额外软件

    如果你的EFI分区还在 只是被破坏需要修复的话 xff0c 执行 bcdboot c windows l cn zh 即可 xff0c c是Windows安装的盘符 xff0c 如果是装机工具启动可能window的分区不是显示的c 如果连E
  • powershell 设置环境变量

    cmd 是用set 导出变量 xff0c 到了powershell中不好使了 xff0c 下面介绍下导出变量的方法 xff0c 比如想设置 ETCDCTL API 61 3 在powershell中执行下面命令就可以了 Env ETCDCT
  • Httpd 服务

    httpd服务 1 httpd服务简介 Apache HTTP Server xff08 简称Apache或httpd xff09 是Apache软件基金会的一个开放源代码的网页服务器软件 xff0c 旨在为unix xff0c windo
  • Lottie—json文件解析

    Lottie主要类图 xff1a Lottie对外通过控件LottieAnimationView暴露接口 xff0c 控制动画 LottieAnimationView继承自ImageView xff0c 通过当前时间绘制canvas显示到界
  • Android中获取应用程序(包)的信息-----PackageManager的使用

    Android系统为我们提供了很多服务管理的类 xff0c 包括ActivityManager PowerManager 电源管理 AudioManager 音频管理 等 除此之外 xff0c 还提供了一个PackageManger管理类
  • Android开发与调试二:串口uart Debug

    安卓智能硬件开发板 xff0c 往往会预留一个 uart口 xff0c 串口的形式打出 log出来 xff0c 便于我们开发的时候 debug 工具 xff1a 1个 FT232的模块 xff08 如下图 xff0c 淘宝有卖 xff09
  • 正则表达式以及Java中的一个正则表达式处理库

    如果你不熟悉这个术语 xff0c 那么 正则表达式 xff08 Regular Expression xff09 就是一个字符构成的串 xff0c 它定义了一个用来搜索匹配字符串的模式 正则表达式30分钟入门教程 常用正则表达式 许多语言
  • Ubuntu包安装问题(E: Broken packages)[2014-01-03更新]

    问题描述 使用apt get安装软件包时不能正确安装 xff0c 出现提示如下 xff1a apt get install libgtk2 0 dev Reading package lists Done Building dependen
  • c#文案语音配图片一键生成视频

    高手略过吧 xff0c 功能太简单 xff0c 我自己都不好意思 这个是我自己的需要 xff0c 做产品类的短视频 xff0c 东搞西搞剪辑啊啥的 xff0c 特别麻烦 xff0c 所以先搞这个最简版 xff0c 以后再一步步丰富功能 需求