当前位置: 首页 > news >正文

在.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 开发中的建议&#xff1a; 1.4 Enum中的常用方法 1.5 熟悉Enum类中常用的方法 1.6 枚举类实现接口的操作 1.7 jdk5.0之前定义枚举类的方式 &#xff08;了解即可&#xff09; 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…...

春季开学即将到来!大学生活必备数码清单奉上

马上就要开学了&#xff0c;你的返校装备是否已经准备齐全了呢&#xff1f;对于高校学生来说&#xff0c;很多数码产品都属于必备装备&#xff0c;比如下面这几款产品就受到了大量年轻消费者的喜爱&#xff0c;在它们的帮助下能够让大家的学习时光变得更快乐。1、不入耳黑科技骨…...

ubuntu18.04 天选2 R95900hx 3060显卡驱动安装

天选2 R95900hx 3060显卡驱动安装需求问题解决内核集显显卡驱动需求 外接显示器&#xff0c;安装nvidia驱动 问题 由于一开始直接在软件和更新中附加读懂安装了nvidia-470&#xff0c;导致系统黑屏。 解决 grub页面系统选择进入ubuntu recovery模式&#xff0c;选择root&a…...

Harbor安装部署实战详细手册

文章目录前言一、安装docker二、安装docker-compose1.下载2.赋权3.测试三、安装harbor1.下载2.解压3.修改配置文件4.部署5.配置开机自启动6.登录验证7.补充说明四、harbor使用问题1.docker login问题&#xff1a;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】信号量

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…...

android-java同步方法和异步方法

接口 Java接口是一系列方法的声明&#xff0c;是一些方法特征的集合&#xff0c;一个接口只有方法的特征没有方法的实现&#xff0c;因此这些方法可以在不同的地方被不同的类实现&#xff0c;而这些实现可以具有不同的行为&#xff08;功能&#xff09;。 两种含义&#xff1a…...

Flask入门(5):请求和响应

目录5.请求和响应5.1 请求5.2 响应5.请求和响应 5.1 请求 request对象封装解析了请求报文中的数据&#xff0c;其大部分功能是由依赖包werkzeug完成的&#xff0c;并且每个request对象都是线程隔离的&#xff0c;保证了数据的安全性。 request对象的属性 1.request.method …...

记进组后第五次组会汇报

2023年2月14日 日记一、小组组会二、实验室组会1、汇报内容&#xff08;1&#xff09;参考文献&#xff08;2&#xff09;CQF机制a.研究现状b.相关思考&#xff08;3&#xff09;研究计划2、汇报反馈一、小组组会 上午十点整&#xff0c;小组组会开始&#xff0c;有两个同学我…...

nil Foundation的Placeholder证明系统(2)

前序博客&#xff1a; nil Foundation的Placeholder证明系统&#xff08;1&#xff09; nil; Foundation团队2022年11月论文《Placeholder证明系统》。[2022年11月29日版本] 8. 优化 8.1 Batched FRI 不同于单独检查每个commitment&#xff0c;可对其进行FRI聚合。如对多项…...

QHash源码解读

QT版本 v5.12.10 元素 // 重点说明QHashData的函数&#xff0c;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的区别

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐Dynamic和Kinematic的区别⭐ 文章目录⭐Dynamic和Kinematic的区别⭐&#x1f3…...

【C++、数据结构】哈希 — 闭散列与哈希桶的模拟实现

文章目录&#x1f4d6; 前言1. STL中哈希表的两个应用⚡1.1 &#x1f31f;unordered_set1.2 &#x1f31f;unordered_map2. 常见查找的性能对比&#x1f4a5;3. 哈希表模拟实现&#x1f3c1;3.1 哈希的概念&#xff1a;3.2 哈希函数&#xff1a;3.3 哈希冲突&#xff1a;3.4 闭…...

vue 开发环境 卸载node 版本 切换新的 node 版本 mac电脑

注意&#xff1a;操作的机器当前是mac&#xff0c;先卸载&#xff0c;再安装 1.查看现有 node 版本 node -v2.卸载现有 node 版本&#xff0c; 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

记录&#xff1a;377场景&#xff1a;在CentOS 7.9操作系统安装Nacos-2.1.1。在Windows操作系统上安装Nacos-2.1.1。Nacos&#xff1a;Nacos: Dynamic Naming and Configuration Service。Nacos提供动态配置服务、服务发现及管理、动态DNS服务功能。版本&#xff1a;JDK 1.8 Na…...

解决QML debugging is enabled.Only use this in a safe environment.警告

系列文章目录 文章目录系列文章目录前言一、警告原因二、解决办法参考前言 我试图运行一个非常简单的程序&#xff0c;当单击退出按钮时关闭窗口&#xff0c;但获取以下输出&#xff0c;前提是包含按钮的应用程序窗口不显示&#xff1a; 您已启用QML调试(实际上它默认启用)&…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...