在.net中运用ffmpeg 操作视频
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace learun.util
{
/// <summary>
/// ffmpeg视频相关处理的类
/// </summary>
public class FFmpegUtil
{
public static int Run(string cmd)
{
try
{
//string ffmpeg = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"FFmpeg\ffmpeg.exe";
string ffmpeg = ConfigHelper.GetConfig().MultimediaFile.Replace("/", "\\") + @"FFmpeg\ffmpeg.exe";
ProcessStartInfo startInfo = new ProcessStartInfo(ffmpeg);
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = cmd;
Process process = Process.Start(startInfo);
//process.WaitForExit(3000);
process.Kill();
return 1;
}
catch (Exception ex)
{
return -1;
}
}
public static int Run1(string cmd)
{
int r = 0;
try
{
//string ffmpeg = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"FFmpeg\ffmpeg.exe";
string ffmpeg = ConfigHelper.GetConfig().MultimediaFile.Replace("/", "\\") + @"FFmpeg\ffmpeg.exe";
Process p = new Process();
p.StartInfo.FileName = ffmpeg;
p.StartInfo.Arguments = cmd;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
string a = string.Empty;
p.ErrorDataReceived += new DataReceivedEventHandler((s, message) =>
{
//Response.Write(message.Data);
a = message.Data;
});//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
p.Start();//启动线程
p.BeginErrorReadLine();//开始异步读取
p.WaitForExit();//阻塞等待进程结束
p.Close();//关闭进程
p.Dispose();//释放资源
r = 1;
}
catch (Exception ex)
{
r = -1;
}
return r;
}
/// <summary>
/// 按时间获取某帧图片
/// </summary>
/// <param name="videoPath">视频路径</param>
/// <param name="outPath">输出路径</param>
/// <param name="frameTime">时间(格式:00:00:01)</param>
public static void GetFrame(string videoPath, string outPath, string frameTime)
{
Run(string.Format("-ss 00:00:01 -i {1} {2}", frameTime, videoPath, outPath));
}
/ <summary>
/ 批量添加图片水印
/ </summary>
/ <param name="videoPath"></param>
/ <param name="outPath"></param>
/ <param name="listImg"></param>
//public static void AddListImageMark(string videoPath, string outPath, List<ImgMark> listImg)
//{
// string imgs = "", postions = "";
// foreach (ImgMark mark in listImg)
// {
// imgs += " -i " + mark.ImgPath;
// postions += "overlay=" + mark.Postion.X + ":" + mark.Postion.Y + ",";
// }
// postions = postions.Remove(postions.Length - 1);
// Run(string.Format("-i {0}{1} -filter_complex \"{2}\" {3}", videoPath, imgs, postions, outPath));
//}
/ <summary>
/ 批量添加图片水印
/ </summary>
/ <param name="videoPath"></param>
/ <param name="outPath"></param>
/ <param name="listImg"></param>
//public static void AddImageMark(string videoPath, string outPath, ImgMark img)
//{
// Run(string.Format("-i {0} -i {1} -filter_complex overlay {2}", videoPath, img.ImgPath, outPath));
// //./ ffmpeg -i input.mp4 -i iQIYI_logo.png - filter_complex overlay output.mp4
//}
/ <summary>
/ 添加文字水印
/ </summary>
/ <param name="videoPath">视频路径</param>
/ <param name="outPath">输出路径</param>
/ <param name="textMark">水印属性</param>
//public static void AddTextMark(string videoPath, string outPath, TextMark textMark)
//{
// Run(string.Format(" -i {0} -vf \"drawtext=fontfile={1}: text='{2}':x={3}:y={4}:fontsize={5}:fontcolor={6}\" {7}", videoPath, textMark.FontFile, textMark.Text, textMark.X, textMark.Y, textMark.FontSize, textMark.FontColor.Name.ToLower(), outPath));
// //@"%{localtime\:%Y\-%m\-%d %H-%M-%S}"
//}
/// <summary>
/// 获取视频时长
/// </summary>
/// <param name="sourceFile"></param>
/// <returns></returns>
public static int GetVideoDuration(string sourceFile)
{
//string ffmpegfile = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"FFmpeg\ffmpeg.exe";
string ffmpegfile = ConfigHelper.GetConfig().MultimediaFile.Replace("/", "\\") + @"FFmpeg\ffmpeg.exe";
try
{
using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process())
{
String duration; // soon will hold our video's duration in the form "HH:MM:SS.UU"
String result; // temp variable holding a string representation of our video's duration
StreamReader errorreader; // StringWriter to hold output from ffmpeg
// we want to execute the process without opening a shell
ffmpeg.StartInfo.UseShellExecute = false;
//ffmpeg.StartInfo.ErrorDialog = false;
ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
// redirect StandardError so we can parse it
// for some reason the output comes through over StandardError
ffmpeg.StartInfo.RedirectStandardError = true;
// set the file name of our process, including the full path
// (as well as quotes, as if you were calling it from the command-line)
ffmpeg.StartInfo.FileName = ffmpegfile;
// set the command-line arguments of our process, including full paths of any files
// (as well as quotes, as if you were passing these arguments on the command-line)
ffmpeg.StartInfo.Arguments = "-i " + sourceFile;
// start the process
ffmpeg.Start();
// now that the process is started, we can redirect output to the StreamReader we defined
errorreader = ffmpeg.StandardError;
// wait until ffmpeg comes back
ffmpeg.WaitForExit();
// read the output from ffmpeg, which for some reason is found in Process.StandardError
result = errorreader.ReadToEnd();
// a little convoluded, this string manipulation...
// working from the inside out, it:
// takes a substring of result, starting from the end of the "Duration: " label contained within,
// (execute "ffmpeg.exe -i somevideofile" on the command-line to verify for yourself that it is there)
// and going the full length of the timestamp
duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
string[] ss = duration.Split(':');
int h = int.Parse(ss[0]);
int m = int.Parse(ss[1]);
int s = int.Parse(ss[2]);
return h * 3600 + m * 60 + s;
}
}
catch (System.Exception ex)
{
//记录日志
return -1;
}
}
/// <summary>
/// 图片合成视频
/// </summary>
/// <param name="alljpgPath">所有的图片路径</param>
/// <param name="outputMp4Path">输出合成图片视频的所有路径</param>
public static void ImageConvertVideo(string alljpgPath, string outputMp4Path)
{
//string cmd = string.Format(" -i {0} -f segment -segment_time {1} -c copy {2}", targetMp3path, time, outputmp3Path);
//string jpgpath = @"D:\yunyunWork\xinjiang\TestMultiMedia\WindowsFormsApp1\bin\Debug\李梦真\%2d.jpg";
//string mp4path = pathString + string.Format(@"FFmpeg\vedio\o{0}.mp4", Guid.NewGuid().ToString());
string cmd = string.Format("-r 1 -f image2 -i {0} -vcodec libx264 -s 640*480 -g 1 -keyint_min 1 -sc_threshold 0 -pix_fmt yuv420p {1}", alljpgPath, outputMp4Path);
Run1(cmd);
}
/// <summary>
/// 分隔音乐时长
/// </summary>
/// <param name="targetMp3path">目标mp3文件</param>
/// <param name="time">分隔时长</param>
/// <param name="outputmp3Path">输出的目录如</param>
public static void SeparateMusicDuration(string targetMp3path, int time, string outputmp3Path)
{
string cmd = string.Format(" -i {0} -f segment -segment_time {1} -c copy {2}", targetMp3path, time, outputmp3Path);
Run1(cmd);
}
/// <summary>
/// 视频时长大于音乐时长,视频中轮询播放mp3
/// </summary>
/// <param name="inputMp4Path"></param>
/// <param name="mp3Path"></param>
/// <param name="outputMp4Path"></param>
public static void VideoLoopMusic(string inputMp4Path, string mp3Path, string outputMp4Path)
{
string cmd = string.Format("-i {0} -stream_loop -1 -i {1} -filter_complex [0:a][1:a]amix -t 60 -y {2}", inputMp4Path, mp3Path, outputMp4Path);
Run(cmd);
}
/// <summary>
/// 视频中添加音乐
/// </summary>
/// <param name="mp3path">mp3所在的路径</param>
/// <param name="targetMp4Path">需要添加音乐的视频</param>
/// <param name="outputMp4Path">输出添加音乐后的视频</param>
public static void VideoAddMusic(string mp3path, string targetMp4Path, string outputMp4Path)
{
string cmd = string.Format(" -i {0} -i {1} -y {2}", mp3path, targetMp4Path, outputMp4Path);
Run1(cmd);
}
}
}
相关文章:
在.net中运用ffmpeg 操作视频
using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Text;namespace learun.util{/// <summary>/// ffmpeg视频相关处理的类/// </summary>public class FFmpegUtil{public static int Run(string cmd){try{//…...
05- 线性回归算法 (LinearRegression) (算法)
线性回归算法(LinearRegression)就是假定一个数据集合预测值与实际值存在一定的误差, 然后假定所有的这些误差值符合正太分布, 通过方程求这个正太分布的最小均值和方差来还原原数据集合的斜率和截距。当误差值无限接近于0时, 预测值与实际值一致, 就变成了求误差的极小值。 fr…...
JAVA补充知识01之枚举enum
目录 1. 枚举类的使用 1.1 枚举类的理解 1.2 举例 1.3 开发中的建议: 1.4 Enum中的常用方法 1.5 熟悉Enum类中常用的方法 1.6 枚举类实现接口的操作 1.7 jdk5.0之前定义枚举类的方式 (了解即可) 1.8 jdk5.0之后定义枚举类的方式 1…...
jenkins下配置maven
1. 先在jenkins服务器上安装maven 下载-解压-重命名-启动 [rootVM-0-12-centos local]# wget https://mirrors.aliyun.com/apache/maven/maven-3/3.9.0/binaries/apache-maven-3.9.0-bin.tar.gz [rootVM-0-12-centos local]# tar xf apache-maven-3.9.0-bin.tar.gz [rootVM-0…...
春季开学即将到来!大学生活必备数码清单奉上
马上就要开学了,你的返校装备是否已经准备齐全了呢?对于高校学生来说,很多数码产品都属于必备装备,比如下面这几款产品就受到了大量年轻消费者的喜爱,在它们的帮助下能够让大家的学习时光变得更快乐。1、不入耳黑科技骨…...
ubuntu18.04 天选2 R95900hx 3060显卡驱动安装
天选2 R95900hx 3060显卡驱动安装需求问题解决内核集显显卡驱动需求 外接显示器,安装nvidia驱动 问题 由于一开始直接在软件和更新中附加读懂安装了nvidia-470,导致系统黑屏。 解决 grub页面系统选择进入ubuntu recovery模式,选择root&a…...
Harbor安装部署实战详细手册
文章目录前言一、安装docker二、安装docker-compose1.下载2.赋权3.测试三、安装harbor1.下载2.解压3.修改配置文件4.部署5.配置开机自启动6.登录验证7.补充说明四、harbor使用问题1.docker login问题:Error response from daemon: Get https://: http: server gave …...
华为OD机试真题JAVA实现【箱子之形摆放】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出描述示例一输入输出说明备注解题思路Code运行结果版权说明...
华为OD机试 - 事件推送(Python)| 真题+思路+考点+代码+岗位
事件推送 题目 同一个数轴 X 上有两个点的集合 A={A1, A2, …, Am} 和 B={B1, B2, …, Bn}, Ai 和 Bj 均为正整数,A、B 已经按照从小到大排好序,A、B 均不为空, 给定一个距离 R (正整数), 列出同时满足如下条件的所有(Ai, Bj)数对: Ai <= BjAi, Bj 之间的距离小于…...
【Linux】信号量
🎇Linux: 博客主页:一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 看似不起波澜的日复一日,一定会在某一天让你看见坚持…...
android-java同步方法和异步方法
接口 Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 两种含义:…...
Flask入门(5):请求和响应
目录5.请求和响应5.1 请求5.2 响应5.请求和响应 5.1 请求 request对象封装解析了请求报文中的数据,其大部分功能是由依赖包werkzeug完成的,并且每个request对象都是线程隔离的,保证了数据的安全性。 request对象的属性 1.request.method …...
记进组后第五次组会汇报
2023年2月14日 日记一、小组组会二、实验室组会1、汇报内容(1)参考文献(2)CQF机制a.研究现状b.相关思考(3)研究计划2、汇报反馈一、小组组会 上午十点整,小组组会开始,有两个同学我…...
nil Foundation的Placeholder证明系统(2)
前序博客: nil Foundation的Placeholder证明系统(1) nil; Foundation团队2022年11月论文《Placeholder证明系统》。[2022年11月29日版本] 8. 优化 8.1 Batched FRI 不同于单独检查每个commitment,可对其进行FRI聚合。如对多项…...
QHash源码解读
QT版本 v5.12.10 元素 // 重点说明QHashData的函数,QHashData是QHash的基础 struct QHashData {struct Node {Node *next;uint h;};Node *fakeNext; // 永为nullNode **buckets; // Node *数组QtPrivate::RefCount ref;int size; // node个数int nodeSize; /…...
【Unity细节】RigidBody中Dynamic和Kinematic的区别
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity细节和bug ⭐Dynamic和Kinematic的区别⭐ 文章目录⭐Dynamic和Kinematic的区别⭐dz…...
【C++、数据结构】哈希 — 闭散列与哈希桶的模拟实现
文章目录📖 前言1. STL中哈希表的两个应用⚡1.1 🌟unordered_set1.2 🌟unordered_map2. 常见查找的性能对比💥3. 哈希表模拟实现🏁3.1 哈希的概念:3.2 哈希函数:3.3 哈希冲突:3.4 闭…...
vue 开发环境 卸载node 版本 切换新的 node 版本 mac电脑
注意:操作的机器当前是mac,先卸载,再安装 1.查看现有 node 版本 node -v2.卸载现有 node 版本, 1.卸载从node官网下载pkg安装的node sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node…...
在Linux和Windows上安装Nacos-2.1.1
记录:377场景:在CentOS 7.9操作系统安装Nacos-2.1.1。在Windows操作系统上安装Nacos-2.1.1。Nacos:Nacos: Dynamic Naming and Configuration Service。Nacos提供动态配置服务、服务发现及管理、动态DNS服务功能。版本:JDK 1.8 Na…...
解决QML debugging is enabled.Only use this in a safe environment.警告
系列文章目录 文章目录系列文章目录前言一、警告原因二、解决办法参考前言 我试图运行一个非常简单的程序,当单击退出按钮时关闭窗口,但获取以下输出,前提是包含按钮的应用程序窗口不显示: 您已启用QML调试(实际上它默认启用)&…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
