直接贴代码了:

ffmpegTest02.cs

    public partial class ffmpegTest02 : FormBase
{
private static readonly string TaskffmpegNETExeFullPath = ConfigurationManager.AppSettings["TaskffmpegNETExeFullPath"]; string _videoFileFullPath = @"D:\Workspace\TestVideo.mp4"; string _othereVideoFileFullPath = @"D:\Workspace\TestVideo{0}.mp4"; string snapshotParentDir = @"D:\Workspace\TestVideoSnapshot"; int exeMoreCrawlSnapshotCount = ; public ffmpegTest02()
{
base.InitForm();
InitializeComponent();
base.InitControls(this.listInfoLog);
} private void OnProgress(object sender, ConversionProgressEventArgs e)
{
ShowAndLog(string.Format("[{0} => {1}]", e.Input.FileInfo.Name, e.Output?.FileInfo.Name), false, null);
ShowAndLog(string.Format("Bitrate: {0}", e.Bitrate), false, null);
ShowAndLog(string.Format("Fps: {0}", e.Fps), false, null);
ShowAndLog(string.Format("Frame: {0}", e.Frame), false, null);
ShowAndLog(string.Format("ProcessedDuration: {0}", e.ProcessedDuration), false, null);
ShowAndLog(string.Format("Size: {0} kb", e.SizeKb), false, null);
ShowAndLog(string.Format("TotalDuration: {0}\n", e.TotalDuration), false, null);
} /// <summary>
/// 此事件短时间(比如:1秒以内)会调用多次
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnData(object sender, ConversionDataEventArgs e)
{
ShowAndLog(string.Format("[从源文件 {0} 到目标文件 {1}],数据 {2}", e.Input.FileInfo.Name, e.Output?.FileInfo.Name, e.Data),
false,
null);
} /// <summary>
/// 此事件短时间(比如:1秒以内)会调用多次
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDataSimpleShow(object sender, ConversionDataEventArgs e)
{
ShowAndLog(string.Format("[从源文件 {0} 到目标文件 {1}]。", e.Input.FileInfo.Name, e.Output?.FileInfo.Name),
false,
null);
} private void OnComplete(object sender, ConversionCompleteEventArgs e)
{
ShowAndLog(string.Format("从 {0} 到 {1} 处理完成。 ", e.Input.FileInfo.FullName, e.Output?.FileInfo.FullName),
false,
null);
} private void OnError(object sender, ConversionErrorEventArgs e)
{
ShowAndLog(string.Format("[{0} => {1}]: 错误: {2}\n{3}", e.Input.FileInfo.Name, e.Output?.FileInfo.Name, e.Exception.ExitCode, e.Exception.InnerException),
false,
null);
} private IEnumerable<TimeSpan> CreateTimeSpanArray()
{
for (int i = ; i < ; i++)
{
yield return new TimeSpan(, i, );
}
} private ConversionOptions GetConversionOptions(TimeSpan tsItem)
{
return new ConversionOptions
{
Seek = tsItem,
//下面表示3行代码表示需要自定义截图的尺寸
VideoSize = VideoSize.Custom,
CustomWidth = , // 截图的宽度
CustomHeight = , // 截图的高度
FFmpegDrawTextArgs = string.Format("borderw=10:bordercolor=white:fontcolor=#A9A9A8:fontsize=100:fontfile=FreeSerif.ttf:text='{0}\\:{1}\\:{2}':x =(w-text_w-50):y=(h-text_h-50)",
tsItem.Hours.ToString().PadLeft(, ''),
tsItem.Minutes.ToString().PadLeft(, ''),
tsItem.Seconds.ToString().PadLeft(, '')
),
ExtraFFmpegArgs = " -y " // -y 表示目标文件已经存在,则覆盖输出文件
};
} private async void btnStartConvertAndSnapshot_Click(object sender, EventArgs e)
{
string mkvOutputFileFullPath = string.Format(@"D:\Workspace\TestVideo-{0}.mkv", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
string mkvThumbOutputFileFullPath = string.Format(@"{0}\TestVideo-mkv-thumb-{1}.png", snapshotParentDir, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
try
{
var inputFile = new MediaFile(_videoFileFullPath);
var outputFile = new MediaFile(mkvOutputFileFullPath);
var thumbNailFile = new MediaFile(mkvThumbOutputFileFullPath); var ffmpeg = new Engine(TaskffmpegNETExeFullPath);
//ffmpeg.Progress += OnProgress;
//ffmpeg.Data += OnDataSimpleShow;
ffmpeg.Error += OnError;
ffmpeg.Complete += OnComplete;
var output = await ffmpeg.ConvertAsync(inputFile, outputFile);
var thumbNail = await ffmpeg.GetThumbnailAsync(output, thumbNailFile, GetConversionOptions(TimeSpan.FromSeconds()));
var metadata = await ffmpeg.GetMetaDataAsync(output);
Console.WriteLine(metadata.FileInfo.FullName);
Console.WriteLine(metadata);
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
} private async void btnGetVideoInfo_Click(object sender, EventArgs e)
{
ShowAndLog("ffmpeg 准备开始获取,请稍后...", false, null);
Stopwatch globalWatch = Stopwatch.StartNew();
var ffmpeg = new Engine(TaskffmpegNETExeFullPath);
//ffmpeg.Progress += OnProgress;
//ffmpeg.Data += OnDataSimpleShow;
ffmpeg.Error += OnError;
ffmpeg.Complete += OnComplete; var inputFile = new MediaFile(_videoFileFullPath);
MetaData md = await ffmpeg.GetMetaDataAsync(inputFile); ShowAndLog(string.Format("Duration:{0}", md.Duration), false, null);
ShowAndLog(string.Format("VideoData:{0}", JsonHelper.SerializeToJson(md.VideoData)), false, null);
ShowAndLog(string.Format("AudioData:{0}", JsonHelper.SerializeToJson(md.AudioData)), false, null); globalWatch.Stop();
ShowAndLog(string.Format("运行结束!共耗时 {0} 毫秒。", globalWatch.ElapsedMilliseconds), false, null); } private async void btnStartSingleSnapshot_Click(object sender, EventArgs e)
{
ShowAndLog("ffmpeg 准备开始转换,请稍后...", false, null);
Stopwatch globalWatch = Stopwatch.StartNew();
IEnumerable<TimeSpan> timeSpanArray = CreateTimeSpanArray();
var ffmpeg = new Engine(TaskffmpegNETExeFullPath);
//ffmpeg.Progress += OnProgress;
//ffmpeg.Data += OnDataSimpleShow;
ffmpeg.Error += OnError;
ffmpeg.Complete += OnComplete; var inputFile = new MediaFile(_videoFileFullPath); int i = ;
string mkvThumbOutputFileFullPath;
List<string> allThumbFullName = new List<string>();
foreach (TimeSpan tsItem in timeSpanArray)
{
i++;
mkvThumbOutputFileFullPath = string.Format(@"{0}\TestVideo-mp4-thumb-{1}-{2}.jpg", snapshotParentDir, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss.fff"), i);
allThumbFullName.Add(mkvThumbOutputFileFullPath);
var thumbNailFile = new MediaFile(mkvThumbOutputFileFullPath);
await ffmpeg.GetThumbnailAsync(inputFile, thumbNailFile, GetConversionOptions(tsItem) );
}
ShowAndLog("ffmpeg 转换完成。结果如下:", false, null);
globalWatch.Stop();
ShowAndLog(string.Format("运行结束!共耗时 {0} 毫秒。", globalWatch.ElapsedMilliseconds), false, null);
} private async void btnParelleSyncStartMoreCrawlSnapshot_ClickAsync(object sender, EventArgs e)
{
ShowAndLog("准备开始同步多个 TestVideo{n}.mp4 上截图,请稍后...", false, null);
Stopwatch globalWatch = Stopwatch.StartNew(); for (int i = ; i < exeMoreCrawlSnapshotCount; i++)
{
await CreateSnapshotCoreAsync(i + );
}
ShowAndLog("同步多个 TestVideo{n}.mp4 上截图完成。结果如下:", false, null);
globalWatch.Stop();
ShowAndLog(string.Format("运行结束!共耗时 {0} 毫秒。", globalWatch.ElapsedMilliseconds), false, null);
} private async Task CreateSnapshotCoreAsync(int fileId)
{
IEnumerable<TimeSpan> timeSpanArray = CreateTimeSpanArray();
var ffmpeg = new Engine(TaskffmpegNETExeFullPath);
//ffmpeg.Progress += OnProgress;
//ffmpeg.Data += OnDataSimpleShow;
ffmpeg.Error += OnError;
ffmpeg.Complete += OnComplete; var inputFile = new MediaFile(string.Format(_othereVideoFileFullPath, fileId)); //_videoFileFullPath int i = ;
string mkvThumbOutputFileFullPath;
List<string> allThumbFullName = new List<string>();
foreach (TimeSpan tsItem in timeSpanArray)
{
i++;
mkvThumbOutputFileFullPath = string.Format(@"{0}\TestVideo{1}-mp4-thumb-{2}-{3}.jpg", snapshotParentDir, fileId, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss.fff"), i);
allThumbFullName.Add(mkvThumbOutputFileFullPath);
var thumbNailFile = new MediaFile(mkvThumbOutputFileFullPath);
await ffmpeg.GetThumbnailAsync(inputFile, thumbNailFile, GetConversionOptions(tsItem));
}
} private async void btnParelleAsyncStartMoreCrawlSnapshot_ClickAsync(object sender, EventArgs e)
{
ShowAndLog("准备开始异步并行多个 TestVideo{n}.mp4 上截图,请稍后...", false, null);
Stopwatch globalWatch = Stopwatch.StartNew(); var tasks = Enumerable.Range(, exeMoreCrawlSnapshotCount).Select(i =>
{
return Task.Run(async () =>
{
await CreateSnapshotCoreAsync(i + );
});
});
await Task.WhenAll(tasks);
ShowAndLog("异步并行多个 TestVideo{n}.mp4 上截图完成。结果如下:", false, null);
globalWatch.Stop();
ShowAndLog(string.Format("运行结束!共耗时 {0} 毫秒。", globalWatch.ElapsedMilliseconds), false, null);
} private async void btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop_Click(object sender, EventArgs e)
{
ShowAndLog("准备开始异步并行多个 TestVideo{n}.mp4 上截图(限制最大异步处理单元),请稍后...", false, null);
Stopwatch globalWatch = Stopwatch.StartNew();
var tasks = Enumerable.Range(, exeMoreCrawlSnapshotCount).ParallelForEachAsync(i =>
{
return Task.Run(async () =>
{
await CreateSnapshotCoreAsync(i + );
});
}, Environment.ProcessorCount);
await Task.WhenAll(tasks);
ShowAndLog("异步并行多个 TestVideo{n}.mp4 上截图(限制最大异步处理单元)完成。结果如下:", false, null);
globalWatch.Stop();
ShowAndLog(string.Format("运行结束!共耗时 {0} 毫秒。", globalWatch.ElapsedMilliseconds), false, null);
}
}

ffmpegTest02.Designer.cs

    partial class ffmpegTest02
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows Form Designer generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartConvertAndSnapshot = new System.Windows.Forms.Button();
this.listInfoLog = new System.Windows.Forms.ListBox();
this.btnStartSingleSnapshot = new System.Windows.Forms.Button();
this.btnGetVideoInfo = new System.Windows.Forms.Button();
this.btnParelleSyncStartMoreCrawlSnapshot = new System.Windows.Forms.Button();
this.btnParelleAsyncStartMoreCrawlSnapshot = new System.Windows.Forms.Button();
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnStartConvertAndSnapshot
//
this.btnStartConvertAndSnapshot.Location = new System.Drawing.Point(, );
this.btnStartConvertAndSnapshot.Name = "btnStartConvertAndSnapshot";
this.btnStartConvertAndSnapshot.Size = new System.Drawing.Size(, );
this.btnStartConvertAndSnapshot.TabIndex = ;
this.btnStartConvertAndSnapshot.Text = "1. 开始先把 TestVideo.mp4 转换 mkv,再在第 1 分钟的时候截图";
this.btnStartConvertAndSnapshot.UseVisualStyleBackColor = true;
this.btnStartConvertAndSnapshot.Click += new System.EventHandler(this.btnStartConvertAndSnapshot_Click);
//
// listInfoLog
//
this.listInfoLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listInfoLog.Font = new System.Drawing.Font("宋体", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)()));
this.listInfoLog.FormattingEnabled = true;
this.listInfoLog.HorizontalScrollbar = true;
this.listInfoLog.Location = new System.Drawing.Point(, );
this.listInfoLog.Name = "listInfoLog";
this.listInfoLog.ScrollAlwaysVisible = true;
this.listInfoLog.Size = new System.Drawing.Size(, );
this.listInfoLog.TabIndex = ;
//
// btnStartSingleSnapshot
//
this.btnStartSingleSnapshot.Location = new System.Drawing.Point(, );
this.btnStartSingleSnapshot.Name = "btnStartSingleSnapshot";
this.btnStartSingleSnapshot.Size = new System.Drawing.Size(, );
this.btnStartSingleSnapshot.TabIndex = ;
this.btnStartSingleSnapshot.Text = "2. 不转码,直接在第 1分钟的时候从 TestVideo.mp4 上截图";
this.btnStartSingleSnapshot.UseVisualStyleBackColor = true;
this.btnStartSingleSnapshot.Click += new System.EventHandler(this.btnStartSingleSnapshot_Click);
//
// btnGetVideoInfo
//
this.btnGetVideoInfo.Location = new System.Drawing.Point(, );
this.btnGetVideoInfo.Name = "btnGetVideoInfo";
this.btnGetVideoInfo.Size = new System.Drawing.Size(, );
this.btnGetVideoInfo.TabIndex = ;
this.btnGetVideoInfo.Text = "3. 仅仅获取 TestVideo.mp4 视频的信息";
this.btnGetVideoInfo.UseVisualStyleBackColor = true;
this.btnGetVideoInfo.Click += new System.EventHandler(this.btnGetVideoInfo_Click);
//
// btnParelleSyncStartMoreCrawlSnapshot
//
this.btnParelleSyncStartMoreCrawlSnapshot.Location = new System.Drawing.Point(, );
this.btnParelleSyncStartMoreCrawlSnapshot.Name = "btnParelleSyncStartMoreCrawlSnapshot";
this.btnParelleSyncStartMoreCrawlSnapshot.Size = new System.Drawing.Size(, );
this.btnParelleSyncStartMoreCrawlSnapshot.TabIndex = ;
this.btnParelleSyncStartMoreCrawlSnapshot.Text = "4. 同步多个 TestVideo{n}.mp4 上截图";
this.btnParelleSyncStartMoreCrawlSnapshot.UseVisualStyleBackColor = true;
this.btnParelleSyncStartMoreCrawlSnapshot.Click += new System.EventHandler(this.btnParelleSyncStartMoreCrawlSnapshot_ClickAsync);
//
// btnParelleAsyncStartMoreCrawlSnapshot
//
this.btnParelleAsyncStartMoreCrawlSnapshot.Location = new System.Drawing.Point(, );
this.btnParelleAsyncStartMoreCrawlSnapshot.Name = "btnParelleAsyncStartMoreCrawlSnapshot";
this.btnParelleAsyncStartMoreCrawlSnapshot.Size = new System.Drawing.Size(, );
this.btnParelleAsyncStartMoreCrawlSnapshot.TabIndex = ;
this.btnParelleAsyncStartMoreCrawlSnapshot.Text = "5. 异步并行多个 TestVideo{n}.mp4 上截图";
this.btnParelleAsyncStartMoreCrawlSnapshot.UseVisualStyleBackColor = true;
this.btnParelleAsyncStartMoreCrawlSnapshot.Click += new System.EventHandler(this.btnParelleAsyncStartMoreCrawlSnapshot_ClickAsync);
//
// btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop
//
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.Location = new System.Drawing.Point(, );
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.Name = "btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop";
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.Size = new System.Drawing.Size(, );
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.TabIndex = ;
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.Text = "6. 异步并行多个 TestVideo{n}.mp4 上截图(限制最大异步处理单元)";
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.UseVisualStyleBackColor = true;
this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop.Click += new System.EventHandler(this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop_Click);
//
// ffmpegTest02
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop);
this.Controls.Add(this.btnParelleAsyncStartMoreCrawlSnapshot);
this.Controls.Add(this.btnParelleSyncStartMoreCrawlSnapshot);
this.Controls.Add(this.btnGetVideoInfo);
this.Controls.Add(this.btnStartSingleSnapshot);
this.Controls.Add(this.listInfoLog);
this.Controls.Add(this.btnStartConvertAndSnapshot);
this.Name = "ffmpegTest02";
this.Text = "ffmpegTest02";
this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button btnStartConvertAndSnapshot;
private System.Windows.Forms.ListBox listInfoLog;
private System.Windows.Forms.Button btnStartSingleSnapshot;
private System.Windows.Forms.Button btnGetVideoInfo;
private System.Windows.Forms.Button btnParelleSyncStartMoreCrawlSnapshot;
private System.Windows.Forms.Button btnParelleAsyncStartMoreCrawlSnapshot;
private System.Windows.Forms.Button btnParelleAsyncStartMoreCrawlSnapshotLimitMaxDop;
}

运行结果

图 01

图 02

图 03

图 04

图 05

图 06

图 07

图 08

谢谢浏览!

如何让 FFmpeg 支持异步并行转码、截图等等操作?的更多相关文章

  1. Java Web 中使用ffmpeg实现视频转码、视频截图

    Java Web 中使用ffmpeg实现视频转码.视频截图 转载自:[ http://www.cnblogs.com/dennisit/archive/2013/02/16/2913287.html  ...

  2. windows下使用ffmpeg进行视频转换和截图。

    author:fanfq(xiaoban) Email:fangqing.fan#gmail.comlink:http://fanfq.iteye.com/admin/blogs/655569chan ...

  3. C# 使用 ffmpeg 进行音频转码

    先放一下 ffmpeg 的官方文档以及下载地址: 官方文档:http://ffmpeg.org/ffmpeg.html 下载地址:http://ffmpeg.org/download.html 用 f ...

  4. FFmpeg:视频转码、剪切、合并、播放速调整

    原文:https://fzheng.me/2016/01/08/ffmpeg/ FFmpeg:视频转码.剪切.合并.播放速调整 2016-01-08 前阵子帮导师处理项目 ppt,因为插入视频的格式问 ...

  5. 使用ffmpeg.exe进行转码参数说明

    使用ffmpeg.exe进行转码参数说明 摘自:https://blog.csdn.net/coloriy/article/details/47337641 2015年08月07日 13:04:32  ...

  6. ubuntu系统下安装gstreamer的ffmpeg支持

    当您在安装gstreamer到您的ubuntu系统中时,为了更好地进行流媒体开发,需要安装ffmpeg支持,但一般情况下,直接使用 sudo apt-get install gstreamer0.10 ...

  7. [IBM][CLI Driver] SQL0270N 函数不受支持(原因码:"75")。 SQLSTATE=42997

    db2 update dbm cfg  using FEDERATED  yes 与 自动维护 (AUTO_MAINT) = ON 自动数据库备份 (AUTO_DB_BACKUP) = OFF 自动表 ...

  8. Python3选择支持非ASCII码标识符的缘由

    原文在: PEP 3131 -- Supporting Non-ASCII Identifiers. Python2并不支持非ASCII码标识符. PEP的全称是Python Enhancement ...

  9. API Studio 5.1.2 版本更新:加入全局搜索、支持批量测试API测试用例、读取代码注解生成文档支持Github与码云等

    最近在EOLINKER的开发任务繁重,许久在博客园没有更新产品动态了,经过这些日子,EOLINKER又有了长足的进步,增加了更多易用的功能,比如加入全局搜索.支持批量测试API测试用例.读取代码注解生 ...

随机推荐

  1. RabbitMQ的消息持久化处理

    1.RabbitMQ的消息持久化处理,消息的可靠性是 RabbitMQ 的一大特色,那么 RabbitMQ 是如何保证消息可靠性的呢——消息持久化. 2.autoDelete属性的理解. 1).@Qu ...

  2. PHP中设计模式以及魔术方法

    1.设计模式        1.1单例模式        口诀:三私一公 1.私有的静态属性用来保存对象的单例 2.私有的构造方法用来阻止在类的外部实例化 3.私有的__clone阻止在类的外部clo ...

  3. v8js-在PHP中运行javascript代码

    起因之前写自动登录操作一个网站的PHP脚本,但是发现该网站用js代码做了cookie的计算和验证,所以使用了v8js. 安装安装v8.(Mac:brew install v8)使用pecl insta ...

  4. 一文解读5G (转)

    今天要研究的对象,是5G接入网. 什么是接入网?相信不少同学,对这个概念一定不会陌生. 搬出这张移动通信架构图: 接入网,在我们无线通信里,一般指无线接入网,也就是通常所说的RAN(Radio Acc ...

  5. win10安装ubuntu系统出现的一些问题以及解决方案

    前言 在win10系统进行安装新的ubuntu环境的时候遇到的一些问题,以及解决方案,供以后参考. 准备 从ubuntu官网下载最近版本的ubuntu系统,Ubuntu最新版本下载地址 操作系统:wi ...

  6. java:数据结构(四)二叉查找树以及树的三种遍历

    @TOC 二叉树模型 二叉树是树的一种应用,一个节点可以有两个孩子:左孩子,右孩子,并且除了根节点以外每个节点都有一个父节点.当然这种简单的二叉树不能解决让树保持平衡状态,例如你一直往树的左边添加元素 ...

  7. nginx在centos下的安装

    第一步:打开浏览器下载,再上传到centOS系统中 http://nginx.org/download/ 或者在 centOS系统输入: wget http://nginx.org/download/ ...

  8. [日常] 安装windows+deepin双系统

    我的测试电脑上安装了三个系统,分别是win7 , ubuntu16.04 ,deepin15.11下面的步骤是安装deepin系统的过程 1.制作启动u盘,直接使用官方工具制作就可以了,我的已经制作好 ...

  9. python使用face_recognition包的环境设置

    在使用face_recognition包进行人脸识别时,环境是非常重要的,但是网上办法特别纷杂,今天介绍一种特别简单的办法,希望能帮助到大家,少走些坑. 1.首先应该下载dlib安装包(例如:dlib ...

  10. Pwn-level3

    题目地址 https://dn.jarvisoj.com/challengefiles/level3.rar.2047525b05c499c9dd189ba212bba1f8 借鉴 https://w ...