├── ExpertVideoToolbox
├── App.config
├── packages.config
├── MediaInfoDotNet.dll.config
├── Properties
│ ├── Settings.settings
│ ├── AssemblyInfo.cs
│ ├── Settings.Designer.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── ExpertVideoToolbox.csproj.user
├── Program.cs
├── TaskManager
│ ├── videoTask.cs
│ ├── runningPool.cs
│ ├── tasksQueue.cs
│ └── Job.cs
├── cmdCodeGenerator
│ ├── filePathStorage.cs
│ ├── taskSetting.cs
│ └── cmdCode.cs
├── MainForm.resx
├── RunningStatusForm.resx
├── ExpertVideoToolbox.csproj
├── ProcessControl.cs
├── RunningStatusForm.cs
├── RunningStatusForm.Designer.cs
├── MainForm.Designer.cs
└── MainForm.cs
├── .gitignore
├── ExpertVideoToolbox.sln
└── README.md
/ExpertVideoToolbox/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/MediaInfoDotNet.dll.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/ExpertVideoToolbox.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 发布\
5 |
6 |
7 |
8 |
9 |
10 | zh-CN
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace ExpertVideoToolbox
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// 应用程序的主入口点。
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new MainForm());
20 | //Application.EnableVisualStyles();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
49 | .exe
50 | .dll
51 |
52 | obj/
53 | x86/
54 | x64/
55 | bin/
56 | packages/
57 | *.264
58 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/TaskManager/videoTask.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ExpertVideoToolbox.TaskManager
8 | {
9 | class videoTask
10 | {
11 | private string filePath;
12 | private string setting;
13 |
14 | public videoTask(string path)
15 | {
16 | this.filePath = path;
17 | }
18 |
19 | public videoTask(string path, string setting)
20 | {
21 | this.filePath = path;
22 | this.setting = setting;
23 | }
24 |
25 | public string printTask()
26 | {
27 | return this.filePath;
28 | }
29 |
30 | public string getFP()
31 | {
32 | return this.filePath;
33 | }
34 |
35 | public string getSetting()
36 | {
37 | return this.setting;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpertVideoToolbox", "ExpertVideoToolbox\ExpertVideoToolbox.csproj", "{6DE600BF-C56C-4E2D-B1DD-73217764A806}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {6DE600BF-C56C-4E2D-B1DD-73217764A806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {6DE600BF-C56C-4E2D-B1DD-73217764A806}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {6DE600BF-C56C-4E2D-B1DD-73217764A806}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {6DE600BF-C56C-4E2D-B1DD-73217764A806}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ExpertVideoToolbox
2 | A lightweight, versatile GUI of x264, x265. Nearly full input formats support, .mkv and .mp4 output support. Avs support has been added.
3 |
4 | = Mandatory Prerequisites =
5 | * NuGet packages: MediaInfoDotNet and Newtonsoft.Json
6 | * Multiple tools in tools/. (See README.jpg or download one of releases to obtain these tools).
7 | Includes ffmpeg.exe, mkvmerge.exe, qaac.exe (need some .dll files to run without QuickTime), mp4Box.exe(libgpac_static.lib needed), x26x.
8 | Currently,
9 | x265 binary comes from http://msystem.waw.pl/x265/
10 | x264 and ffmpeg binaries come from http://maruko.appinn.me/7mod.html
11 |
12 | = Features =
13 | * Easy to bulk convert videos, even with different parameters.
14 | * Full video conversion process (Audio and Video) in one step.
15 | * For expert, easy to modify x26x command lines parameters.
16 | * Low speed mode. Set CPU affinity to one quarter logcial processors. Users do not need to stop the video converting process when playing games or other tasks need CPU.
17 | * Support .avs script file. Also support audio process (Copy audio & qaac) in avs mode.
18 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过以下
6 | // 特性集控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("ExpertVideoToolbox")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ExpertVideoToolbox")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 使此程序集中的类型
18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | // 则将该类型上的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("aaced22e-6296-4617-bd9b-ea2318a87d3e")]
24 |
25 | // 程序集的版本信息由下面四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.2.3")]
36 | [assembly: AssemblyFileVersion("0.2.3.173")]
37 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34014
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ExpertVideoToolbox.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/cmdCodeGenerator/filePathStorage.cs:
--------------------------------------------------------------------------------
1 | using ExpertVideoToolbox.TaskManager;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 |
10 | namespace ExpertVideoToolbox.cmdCodeGenerator
11 | {
12 | class filePathStorage
13 | {
14 | private videoTask[] storage;
15 | private int count;
16 | private int maxCount;
17 |
18 | public filePathStorage(int maxCount)
19 | {
20 | this.maxCount = maxCount;
21 | this.count = 0;
22 | this.storage = new videoTask[maxCount]; // 根据文件个数分配存储空间
23 | }
24 |
25 | public videoTask get(int index)
26 | {
27 | return storage[index];
28 | }
29 |
30 | public void add(videoTask t)
31 | {
32 | try
33 | {
34 | if (this.count == maxCount)
35 | {
36 | throw new Exception("Overflow");
37 | } else
38 | {
39 | this.storage[count++] = t;
40 | }
41 | }
42 | catch (Exception ex)
43 | {
44 | MessageBox.Show("Error: Could not add any more tasks. Original error: " + ex.Message);
45 | }
46 | }
47 |
48 | public int Count()
49 | {
50 | return this.maxCount;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/cmdCodeGenerator/taskSetting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ExpertVideoToolbox.cmdCodeGenerator
8 | {
9 | class taskSetting
10 | {
11 | public string name;
12 |
13 | public string encoder; // 视频编码器
14 | public string outputFormat; // 输出格式
15 | public string encoderSetting; // 参数
16 |
17 | public string audioEncoder;
18 | public string audioProfile;
19 | public string audioCodecMode;
20 | public string audioQuality;
21 | public string audioKbps;
22 |
23 | public taskSetting(string name, // 名称
24 | string e, // 视频编码器
25 | string of, // 输出格式
26 | string es, // 编码器参数
27 | string aE, // 音频编码器
28 | string aP, // 音频Profile
29 | string aMode, // 音频编码模式
30 | string aQ, // 音频质量或码率
31 | string aK)
32 | {
33 | this.encoder = e;
34 | this.outputFormat = of;
35 | this.encoderSetting = es;
36 | this.audioEncoder = aE;
37 | this.audioProfile = aP;
38 | this.audioCodecMode = aMode;
39 | this.audioQuality = aQ;
40 | this.audioKbps = aK;
41 | this.name = name;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/TaskManager/runningPool.cs:
--------------------------------------------------------------------------------
1 | using ExpertVideoToolbox.TaskManager;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace ExpertVideoToolbox.taskManager
10 | {
11 | class runningPool
12 | {
13 | public int max; // 最大允许同时运行任务数
14 | public videoTask[] tPool; // 正在运行的任务数组
15 | public int currentCount; // 目前在运行的任务数
16 |
17 | private tasksQueue waitingQueue;
18 | private tasksQueue completedQueue;
19 | private tasksQueue failedQueue;
20 |
21 | public delegate void setFpsHandler(string fps);
22 | public event setFpsHandler setFpsEvent;
23 |
24 | public runningPool(int num, videoTask[] tasks) // 默认构造函数,同时运行1个任务
25 | {
26 | this.max = 1;
27 | this.currentCount = 0;
28 | this.tPool = new videoTask[this.max];
29 |
30 | // 初始化queue
31 | this.waitingQueue = new tasksQueue(num, tasks);
32 | this.completedQueue = new tasksQueue(num);
33 | this.failedQueue = new tasksQueue(num);
34 | }
35 |
36 | public videoTask getTask()
37 | {
38 | // 取一个任务(取出后该任务即从队列中移除了)
39 | videoTask t = this.waitingQueue.pop();
40 | if (t != null)
41 | {
42 | // 赋config值
43 | //t.setConfig();
44 |
45 | return t;
46 | }
47 | return t; // 如果未取得task,返回null,交job处理
48 | }
49 |
50 | public void removeTask(videoTask t, bool isfailed)
51 | {
52 | // 移动到指定的队列
53 | if (!isfailed)
54 | {
55 | this.completedQueue.add(t);
56 | }
57 | else
58 | {
59 | this.failedQueue.add(t);
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本: 4.0.30319.34014
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace ExpertVideoToolbox.Properties
12 | {
13 |
14 |
15 | ///
16 | /// 一个强类型的资源类,用于查找本地化的字符串等。
17 | ///
18 | // 此类是由 StronglyTypedResourceBuilder
19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
21 | // (以 /str 作为命令选项),或重新生成 VS 项目。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// 返回此类使用的、缓存的 ResourceManager 实例。
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ExpertVideoToolbox.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// 为所有资源查找重写当前线程的 CurrentUICulture 属性,
56 | /// 方法是使用此强类型资源类。
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/TaskManager/tasksQueue.cs:
--------------------------------------------------------------------------------
1 | using ExpertVideoToolbox.TaskManager;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace ExpertVideoToolbox.taskManager
10 | {
11 | class tasksQueue
12 | {
13 | public int length; // 现在的长度(不包含空)
14 | public videoTask[] tQueue; // 队列
15 | public int max; // 最大长度
16 |
17 | private int front; // 队头指针
18 | private int rear; // 队尾指针
19 |
20 | private Object lockObj = new Object();
21 |
22 | public tasksQueue(int taskLength, videoTask[] tq)
23 | {
24 | this.length = taskLength;
25 | this.max = taskLength;
26 | this.tQueue = new videoTask[taskLength + 1]; // 采用循环队列,浪费一个存储空间
27 | for (int i = 0; i < taskLength; i++)
28 | {
29 | this.tQueue[i] = tq[i];
30 | }
31 | this.tQueue[taskLength] = null;
32 | this.front = 0;
33 | this.rear = taskLength; // 队尾指针指向队尾元素之后的一个空元素
34 | }
35 |
36 | public tasksQueue(int taskLength) // 只传入值时,队列为空
37 | {
38 | this.length = 0;
39 | this.max = taskLength;
40 | this.tQueue = new videoTask[taskLength + 1];
41 | for (int i = 0; i < taskLength + 1; i++)
42 | {
43 | this.tQueue[i] = null;
44 | }
45 | this.front = this.rear = 0;
46 | }
47 |
48 | public videoTask pop()
49 | {
50 | lock(lockObj) // 锁定,不允许其他线程同时运行这段代码
51 | {
52 | // 取出队首Task并且从队列中移除
53 | if (this.front == this.rear)
54 | {
55 | return null; // 队列为空返回null由运行池处理
56 | } else
57 | {
58 | videoTask x = this.tQueue[this.front];
59 | this.front = (this.front + 1) % (this.max + 1);
60 |
61 | this.length--; // 长度-1
62 | return x;
63 | }
64 | }
65 | }
66 |
67 | public void add(videoTask t)
68 | {
69 | lock(lockObj)
70 | {
71 | // 在队列中添加
72 | // 此处不判断队列是否为满,请在上层对象中加以判断
73 | this.tQueue[this.rear] = t;
74 | this.rear = (this.rear + 1) % (this.max + 1);
75 | this.length++; // 长度+1
76 | }
77 | }
78 |
79 | public void clear()
80 | {
81 | lock (lockObj)
82 | {
83 | // 清空队列
84 | for (int i = 0; i < this.max + 1; i++)
85 | {
86 | this.tQueue[i] = null;
87 | }
88 | this.front = this.rear = 0;
89 | this.length = 0;
90 | }
91 | }
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/RunningStatusForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/ExpertVideoToolbox.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6DE600BF-C56C-4E2D-B1DD-73217764A806}
8 | WinExe
9 | Properties
10 | ExpertVideoToolbox
11 | ExpertVideoToolbox
12 | v4.5
13 | 512
14 | 发布\
15 | true
16 | Disk
17 | false
18 | Foreground
19 | 7
20 | Days
21 | false
22 | false
23 | true
24 | 0
25 | 1.0.0.%2a
26 | false
27 | false
28 | true
29 |
30 |
31 | AnyCPU
32 | true
33 | full
34 | false
35 | bin\Debug\
36 | DEBUG;TRACE
37 | prompt
38 | 4
39 |
40 |
41 | AnyCPU
42 | pdbonly
43 | true
44 | bin\Release\
45 | TRACE
46 | prompt
47 | 4
48 |
49 |
50 |
51 | ..\packages\MediaInfoDotNet.0.7.79.40925\lib\net45\MediaInfoDotNet.dll
52 | True
53 |
54 |
55 | False
56 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | Form
76 |
77 |
78 | MainForm.cs
79 |
80 |
81 |
82 |
83 |
84 | Form
85 |
86 |
87 | RunningStatusForm.cs
88 |
89 |
90 |
91 |
92 |
93 |
94 | MainForm.cs
95 |
96 |
97 | ResXFileCodeGenerator
98 | Resources.Designer.cs
99 | Designer
100 |
101 |
102 | True
103 | Resources.resx
104 |
105 |
106 | RunningStatusForm.cs
107 |
108 |
109 | Always
110 |
111 |
112 |
113 | SettingsSingleFileGenerator
114 | Settings.Designer.cs
115 |
116 |
117 | True
118 | Settings.settings
119 | True
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | Always
128 |
129 |
130 | Always
131 |
132 |
133 |
134 |
135 | False
136 | Microsoft .NET Framework 4.5 %28x86 和 x64%29
137 | true
138 |
139 |
140 | False
141 | .NET Framework 3.5 SP1 Client Profile
142 | false
143 |
144 |
145 | False
146 | .NET Framework 3.5 SP1
147 | false
148 |
149 |
150 |
151 |
152 | IncBuildNo.exe "$(PROJECTDIR)\Properties\AssemblyInfo.cs" "\[assembly: AssemblyFileVersion\(\"\d+\.\d+\.\d+\.(\d+)" 1
153 |
154 |
161 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/ProcessControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Management;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | namespace ExpertVideoToolbox
13 | {
14 | public class ProcessControl
15 | {
16 | const int IDLE = 64;
17 | const int BELOWNORMAL = 16384;
18 | const int NORMAL = 32;
19 | const int ABOVENORMAL = 32768;
20 | const int HIGHPRIORITY = 128;
21 | const int REALTIME = 256;
22 |
23 | private string processName;
24 |
25 | public int numberOfLogicalProcessors = -1;
26 |
27 | private Process cmdProcess;
28 |
29 | public void setProcessName(string name)
30 | {
31 | this.processName = name;
32 | }
33 |
34 | public ProcessControl()
35 | {
36 | cmdProcess = new System.Diagnostics.Process();
37 |
38 | cmdProcess.StartInfo.FileName = "cmd";
39 |
40 | // 必须禁用操作系统外壳程序
41 | cmdProcess.StartInfo.UseShellExecute = false;
42 | cmdProcess.StartInfo.CreateNoWindow = true;
43 | cmdProcess.StartInfo.RedirectStandardInput = true;
44 | cmdProcess.Start();
45 | }
46 |
47 | // 耗时操作
48 | public int GetNumberOfLogicalProcessors()
49 | {
50 | return Environment.ProcessorCount;
51 | }
52 |
53 | // 设置进程的优先级
54 | public void SetProcessPriority(int priority)
55 | {
56 | string command = "wmic process where name=" + "\"" + processName + "\"" + " CALL setpriority ";
57 | switch(priority)
58 | {
59 | case IDLE:
60 | command += IDLE.ToString();
61 | break;
62 | case BELOWNORMAL:
63 | command += BELOWNORMAL.ToString();
64 | break;
65 | case NORMAL:
66 | command += NORMAL.ToString();
67 | break;
68 | case ABOVENORMAL:
69 | command += ABOVENORMAL.ToString();
70 | break;
71 | case HIGHPRIORITY:
72 | command += HIGHPRIORITY.ToString();
73 | break;
74 | case REALTIME:
75 | command += REALTIME.ToString();
76 | break;
77 | }
78 |
79 | MaintainCmdProcessRunning();
80 | this.cmdProcess.StandardInput.WriteLine(command);
81 | }
82 |
83 | // 设置进程的cpu相关性,限制视频编码器占用逻辑处理器数为满载的1/4(默认值,且至少有一个逻辑处理器)
84 | public void ReduceProcessCpuUsage(int slice = 4)
85 | {
86 | string command = "PowerShell \"$Process = Get-Process " + changeFileExtName(this.processName) + "; $Process.ProcessorAffinity=";
87 |
88 | int affinity = 0;
89 | int k = this.numberOfLogicalProcessors;
90 |
91 | if (slice <= 1)
92 | {
93 | affinity = (int)Math.Pow(2, k) - 1;
94 | }
95 | else
96 | {
97 | int numberOfLimitedLogicalProcessors = k / slice;
98 | if (numberOfLimitedLogicalProcessors < 1)
99 | {
100 | numberOfLimitedLogicalProcessors = 1;
101 | }
102 |
103 | // 设置affinity的值,如有8个处理器,affinity则是8位二进制数,每一位上0、1表示该处理器的开关状态,越高位表示的CPU编号越大。
104 | // 如:测试机i7 四核八线程视为八个处理器,10100000表示打开了CPU7和CPU5
105 | // 在PowerShell命令中affinity值要转换为十进制数
106 | k--;
107 | for (int i = 0; i < numberOfLimitedLogicalProcessors; i++)
108 | {
109 | affinity += (int)Math.Pow(2, k);
110 | k -= 2;
111 | }
112 | }
113 |
114 | command += affinity.ToString() + "\"";
115 |
116 | MaintainCmdProcessRunning();
117 | this.cmdProcess.StandardInput.WriteLine(command);
118 | }
119 |
120 | public void ResumeDefalutCpuAffinity()
121 | {
122 | ReduceProcessCpuUsage(1); // 设置进程使用的逻辑处理器数量为总数除以1,即恢复到满载状态
123 | }
124 |
125 | // 检查进程是否在运行,如果不是则重新开始
126 | private void MaintainCmdProcessRunning()
127 | {
128 | if (this.cmdProcess.HasExited) // 如果进程已经退出则再次开始
129 | {
130 | this.cmdProcess.Start();
131 | }
132 | }
133 |
134 | private string changeFileExtName(string originFp, string ext = "")
135 | {
136 | string[] s = originFp.Split(new char[] { '.' });
137 | int length = s.Length;
138 | s[length - 1] = ext;
139 | string finalFileName = "";
140 | for (int i = 0; i < length; i++)
141 | {
142 | finalFileName += s[i];
143 | if (i != length - 1)
144 | {
145 | finalFileName += ".";
146 | }
147 | }
148 | if (string.IsNullOrWhiteSpace(ext)) // 当需要的扩展名为空时,去除字符串最后位置的一个点
149 | {
150 | finalFileName = finalFileName.Substring(0, finalFileName.Length - 1);
151 | }
152 | return finalFileName;
153 | }
154 |
155 | ///
156 | /// A utility class to determine a process parent.
157 | ///
158 | [StructLayout(LayoutKind.Sequential)]
159 | public struct ParentProcessUtilities
160 | {
161 | // These members must match PROCESS_BASIC_INFORMATION
162 | internal IntPtr Reserved1;
163 | internal IntPtr PebBaseAddress;
164 | internal IntPtr Reserved2_0;
165 | internal IntPtr Reserved2_1;
166 | internal IntPtr UniqueProcessId;
167 | internal IntPtr InheritedFromUniqueProcessId;
168 |
169 | [DllImport("ntdll.dll")]
170 | private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
171 |
172 | ///
173 | /// Gets the parent process of the current process.
174 | ///
175 | /// An instance of the Process class.
176 | public static Process GetParentProcess()
177 | {
178 | return GetParentProcess(Process.GetCurrentProcess().Handle);
179 | }
180 |
181 | ///
182 | /// Gets the parent process of specified process.
183 | ///
184 | /// The process id.
185 | /// An instance of the Process class.
186 | public static Process GetParentProcess(int id)
187 | {
188 | Process process = Process.GetProcessById(id);
189 | return GetParentProcess(process.Handle);
190 | }
191 |
192 | ///
193 | /// Gets the parent process of a specified process.
194 | ///
195 | /// The process handle.
196 | /// An instance of the Process class or null if an error occurred.
197 | public static Process GetParentProcess(IntPtr handle)
198 | {
199 | ParentProcessUtilities pbi = new ParentProcessUtilities();
200 | int returnLength;
201 | int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
202 | if (status != 0)
203 | return null;
204 |
205 | try
206 | {
207 | return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
208 | }
209 | catch (ArgumentException)
210 | {
211 | // not found
212 | return null;
213 | }
214 | }
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/RunningStatusForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Diagnostics;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Management;
9 | using System.Text;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 | using System.Windows.Forms;
13 |
14 | namespace ExpertVideoToolbox
15 | {
16 | public partial class RunningStatusForm : Form
17 | {
18 | const int IDLE = 64;
19 | const int BELOWNORMAL = 16384;
20 | const int NORMAL = 32;
21 | const int ABOVENORMAL = 32768;
22 | const int HIGHPRIORITY = 128;
23 | const int REALTIME = 256;
24 |
25 | delegate void SetTextCallback(string commandLine);
26 |
27 | public delegate void AbortHandler(); //声明委托
28 | public event AbortHandler AbortEvent; //声明事件
29 |
30 | public delegate void ClosingHandler(); //声明委托
31 | public event ClosingHandler ClosingEvent; //声明事件
32 | public Process process = null;
33 |
34 | public int PID;
35 |
36 | const int AUDIOENCODE = 0;
37 | const int VIDEOENCODE = 1;
38 | const int MUXER = 2;
39 | const int AUDIOCOPY = 3;
40 |
41 | public string encodingProgram = "";
42 |
43 | public ProcessControl processControl;
44 |
45 | public RunningStatusForm()
46 | {
47 | this.processControl = new ProcessControl();
48 | InitializeComponent();
49 | }
50 |
51 | public void setPercent(string percent, int mode = VIDEOENCODE)
52 | {
53 | if (!percent.Contains("-"))
54 | {
55 | if (mode == VIDEOENCODE)
56 | {
57 | double videoEncodePst = Convert.ToDouble(percent) / 100.0;
58 | double globelPst100x = 1.0 + 98.0 * videoEncodePst;
59 | this.progress.Value = (int)globelPst100x;
60 | this.progressLabel.Text = globelPst100x.ToString("0.0") + "%";
61 | }
62 | else
63 | {
64 | this.progressLabel.Text = percent + "%"; // 这一模式下传进来的字符串已经保留一位小数
65 | }
66 |
67 | }
68 | else
69 | {
70 | if (String.Equals(percent, "-1"))
71 | {
72 | this.progress.Value = 0;
73 | } else if (String.Equals(percent, "-2"))
74 | {
75 | this.progress.Value = 99;
76 | } else
77 | {
78 | this.progress.Value = 100;
79 | }
80 | this.progressLabel.Text = "";
81 | }
82 | }
83 |
84 | public void setTime(string time)
85 | {
86 | this.currentPostionDataTB.Text = time;
87 | this.currentPostionDataTB.Select(this.currentPostionDataTB.TextLength, 0);
88 | }
89 |
90 | public void setFps(string fps)
91 | {
92 | this.fpsDataTB.Text = fps;
93 | }
94 |
95 | public void setEta(string eta)
96 | {
97 | this.estETADataTB.Text = eta;
98 | }
99 |
100 | public void setEstKbps(string kbps)
101 | {
102 | this.estKbpsDataTB.Text = kbps;
103 | }
104 |
105 | private void RunningStatusForm_FormClosed(object sender, FormClosedEventArgs e)
106 | {
107 | if (process != null)
108 | {
109 | process.Close();
110 | }
111 | }
112 | public void setStopBtnState(bool enabled)
113 | {
114 | this.stopBtn.Enabled = enabled;
115 | }
116 |
117 | public string getCurrentTimeText()
118 | {
119 | return this.currentPostionDataTB.Text;
120 | }
121 |
122 | public void setWindowTitle(string title)
123 | {
124 | this.Text = title;
125 | }
126 |
127 | public void setStatusBarFilesCountLabel(int finished, int all)
128 | {
129 | string suffix = this.filesCountLabel.ForeColor == Color.Red ? " (存在失败任务) 请查询日志" : "";
130 | string s = finished.ToString() + "/" + all.ToString() + suffix;
131 | this.filesCountLabel.Text = s;
132 | }
133 |
134 | public void setStatusBarLabelTextColorRED()
135 | {
136 | this.filesCountLabel.ForeColor = Color.Red;
137 | }
138 |
139 | public void SetTaskStepsLabel(string tss)
140 | {
141 | this.taskStepsLabel.Text = tss;
142 | }
143 |
144 | public void SetTaskStepsLabel(bool finish, int currentStepIndex = 0, int totalStepsCount = 0, int mode = 0)
145 | {
146 | string tss = "";
147 | if (finish)
148 | {
149 | tss = "已完成";
150 | }
151 | else
152 | {
153 | tss = "正在进行:步骤 " + currentStepIndex.ToString() + "/" + totalStepsCount.ToString() + " - ";
154 | string modeName = "";
155 | switch (mode)
156 | {
157 | case AUDIOENCODE:
158 | modeName = "音频编码";
159 | break;
160 | case AUDIOCOPY:
161 | modeName = "复制音频";
162 | break;
163 | case VIDEOENCODE:
164 | modeName = "视频编码";
165 | break;
166 | case MUXER:
167 | modeName = "封装";
168 | break;
169 | default:
170 | break;
171 | }
172 | tss += modeName;
173 | }
174 |
175 | this.SetTaskStepsLabel(tss);
176 | }
177 |
178 | private void stopBtn_Click(object sender, EventArgs e)
179 | {
180 | DialogResult dr = MessageBox.Show("确定要中止转换吗?", "确认中止", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
181 | if (dr == DialogResult.OK)
182 | {
183 | // 点确定的代码
184 | // 传入字符串不可加.exe
185 | //Process[] p = Process.GetProcessesByName(this.encodingProgram.Substring(0, this.encodingProgram.Length - 4));
186 |
187 | //int count = p.Length;
188 | //for (int i = 0; i < count; i++)
189 | //{
190 | // p[i].Kill();
191 | //}
192 | //this.stopBtn.Enabled = false;
193 |
194 | KillProcessAndChildren(PID);
195 |
196 | string stopWindowTitle = "用户中止操作";
197 | this.setWindowTitle(stopWindowTitle);
198 |
199 | AbortEvent();
200 | ClosingEvent();
201 |
202 | this.stopBtn.Enabled = false;
203 | }
204 | else
205 | {
206 | //点取消的代码
207 | }
208 | }
209 |
210 | /**
211 | * 传入参数:父进程id
212 | * 功能:根据父进程id,杀死与之相关的进程树
213 | */
214 | private static void KillProcessAndChildren(int pid)
215 | {
216 | ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
217 | ManagementObjectCollection moc = searcher.Get();
218 | foreach (ManagementObject mo in moc)
219 | {
220 | KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
221 | }
222 | try
223 | {
224 | Process proc = Process.GetProcessById(pid);
225 | Console.WriteLine(pid);
226 | proc.Kill();
227 | }
228 | catch (ArgumentException)
229 | {
230 | /* process already exited */
231 | }
232 | }
233 | private void RunningStatusForm_FormClosing(object sender, FormClosingEventArgs e)
234 | {
235 | ClosingEvent();
236 | }
237 |
238 | private void RunningStatusForm_Shown(object sender, EventArgs e)
239 | {
240 |
241 | }
242 |
243 | // 选择低速模式
244 | private void lowSpeedBtn_Click(object sender, EventArgs e)
245 | {
246 | if (this.lowSpeedBtn.ForeColor != Color.White)
247 | {
248 | this.lowSpeedBtn.BackColor = Color.FromArgb(253, 105, 89);
249 | this.lowSpeedBtn.ForeColor = Color.White;
250 |
251 | this.fullSpeedBtn.BackColor = Button.DefaultBackColor;
252 | this.fullSpeedBtn.ForeColor = Button.DefaultForeColor;
253 |
254 | this.lowSpeedBtn.Enabled = false;
255 | this.fullSpeedBtn.Enabled = false;
256 |
257 | this.processControl.ReduceProcessCpuUsage();
258 |
259 | Thread.Sleep(1500);
260 |
261 | this.lowSpeedBtn.Enabled = true;
262 | this.fullSpeedBtn.Enabled = true;
263 | }
264 | }
265 |
266 | // 选择正常模式
267 | private void fullSpeedBtn_Click(object sender, EventArgs e)
268 | {
269 | if (this.fullSpeedBtn.ForeColor != Color.White)
270 | {
271 | this.fullSpeedBtn.BackColor = Color.FromArgb(18, 173, 30);
272 | this.fullSpeedBtn.ForeColor = Color.White;
273 |
274 | this.lowSpeedBtn.BackColor = Button.DefaultBackColor;
275 | this.lowSpeedBtn.ForeColor = Button.DefaultForeColor;
276 |
277 | this.lowSpeedBtn.Enabled = false;
278 | this.fullSpeedBtn.Enabled = false;
279 |
280 | this.processControl.ResumeDefalutCpuAffinity();
281 |
282 | Thread.Sleep(1500);
283 |
284 | this.lowSpeedBtn.Enabled = true;
285 | this.fullSpeedBtn.Enabled = true;
286 | }
287 | }
288 |
289 | public void HideVideoEncoderSetting()
290 | {
291 | this.encoderPriority.Visible = false;
292 | this.priorityCB.Visible = false;
293 | this.fullSpeedBtn.Visible = false;
294 | this.lowSpeedBtn.Visible = false;
295 | }
296 |
297 | public void ShowVideoEncoderSetting()
298 | {
299 | this.encoderPriority.Visible = true;
300 | this.priorityCB.Visible = true;
301 | this.fullSpeedBtn.Visible = true;
302 | this.lowSpeedBtn.Visible = true;
303 |
304 | this.fullSpeedBtn.BackColor = Color.FromArgb(18, 173, 30);
305 | this.fullSpeedBtn.ForeColor = Color.White;
306 |
307 | this.lowSpeedBtn.BackColor = Button.DefaultBackColor;
308 | this.lowSpeedBtn.ForeColor = Button.DefaultForeColor;
309 |
310 | this.priorityCB.SelectedIndex = 1;
311 | this.priorityCB.SelectedIndex = 0;
312 | }
313 |
314 | private void priorityCB_SelectedIndexChanged(object sender, EventArgs e)
315 | {
316 | this.processControl.setProcessName(this.encodingProgram);
317 | ComboBox comboBox = (ComboBox)sender;
318 | if (String.Equals(comboBox.Text, "低"))
319 | {
320 | this.processControl.SetProcessPriority(IDLE);
321 | }
322 | else if (String.Equals(comboBox.Text, "低于正常"))
323 | {
324 | this.processControl.SetProcessPriority(BELOWNORMAL);
325 | }
326 | else if (String.Equals(comboBox.Text, "正常"))
327 | {
328 | this.processControl.SetProcessPriority(NORMAL);
329 | }
330 | else if (String.Equals(comboBox.Text, "高于正常"))
331 | {
332 | this.processControl.SetProcessPriority(ABOVENORMAL);
333 | }
334 | else if (String.Equals(comboBox.Text, "高"))
335 | {
336 | this.processControl.SetProcessPriority(HIGHPRIORITY);
337 | }
338 | else if (String.Equals(comboBox.Text, "实时"))
339 | {
340 | this.processControl.SetProcessPriority(REALTIME);
341 | }
342 | }
343 |
344 | private void fullSpeedBtn_VisibleChanged(object sender, EventArgs e)
345 | {
346 | if (((Button)sender).Visible == true && this.processControl.numberOfLogicalProcessors == -1)
347 | {
348 | this.fullSpeedBtn.Enabled = false;
349 | this.lowSpeedBtn.Enabled = false;
350 | InitializeNumberOfLogicalProcessors();
351 | }
352 | }
353 |
354 | private void InitializeNumberOfLogicalProcessors()
355 | {
356 | this.processControl.numberOfLogicalProcessors = this.processControl.GetNumberOfLogicalProcessors();
357 | this.fullSpeedBtn.Enabled = true;
358 | this.lowSpeedBtn.Enabled = true;
359 | }
360 | }
361 | }
362 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/cmdCodeGenerator/cmdCode.cs:
--------------------------------------------------------------------------------
1 | using MediaInfoLib;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 |
10 | namespace ExpertVideoToolbox.cmdCodeGenerator
11 | {
12 | class cmdCode
13 | {
14 | const int AUDIOENCODE = 0;
15 | const int VIDEOENCODE = 1;
16 | const int MUXER = 2;
17 | const int AUDIOCOPY = 3;
18 | const int DELETEVIDEOTEMP = 4;
19 | const int DELETEAUDIOTEMP = 5;
20 |
21 | const int ONLYVIDEO = 0;
22 | const int SUPPRESSAUDIO = 1;
23 | const int COPYAUDIO = 2;
24 |
25 | const int NORMAL = 0;
26 | const int AVS = 1;
27 | const int VPY = 2;
28 |
29 | private string filePath;
30 | private taskSetting ts;
31 | private string outputFolderPath;
32 | private string outputAudioFormat;
33 |
34 | private string avsVideoPath;
35 |
36 | public cmdCode(string fp, taskSetting t, string ofp)
37 | {
38 | this.filePath = fp;
39 | this.ts = t;
40 | this.outputFolderPath = ofp;
41 | }
42 |
43 | public void setFilePath(string fp)
44 | {
45 | this.filePath = fp;
46 | }
47 |
48 | public int taskType()
49 | {
50 | if (String.Equals(this.ts.audioEncoder, "无音频流"))
51 | {
52 | return ONLYVIDEO;
53 | } else if (String.Equals(this.ts.audioEncoder, "复制音频流"))
54 | {
55 | // 判断是否为avs文件
56 |
57 | string ext = this.getFileExtName(this.filePath);
58 | if (String.Equals(ext, "avs", StringComparison.CurrentCultureIgnoreCase))
59 | {
60 | string[] avsLines = File.ReadAllLines(this.filePath);
61 | for (int i = 0; i < avsLines.Length; i++)
62 | {
63 | int startIdx = avsLines[i].IndexOf("Source(\"");
64 | int endIdx;
65 | if (startIdx != -1)
66 | {
67 | endIdx = avsLines[i].IndexOf("\")");
68 | startIdx += 8;
69 | this.avsVideoPath = avsLines[i].Substring(startIdx, endIdx - startIdx);
70 | break;
71 | }
72 | }
73 | MediaInfo MI = new MediaInfo();
74 | string duration;
75 | MI.Open(this.avsVideoPath);
76 | duration = MI.Get(StreamKind.Audio, 0, 69);
77 | this.outputAudioFormat = MI.Get(StreamKind.Audio, 0, "Format");
78 | if (String.IsNullOrWhiteSpace(duration))
79 | {
80 | return ONLYVIDEO;
81 | }
82 | else
83 | {
84 | if (CheckBoxCompatibility(this.outputAudioFormat, this.ts.outputFormat))
85 | {
86 | return COPYAUDIO;
87 | }
88 | else
89 | {
90 | this.outputAudioFormat = "aac";
91 | return SUPPRESSAUDIO;
92 | }
93 | }
94 | }
95 | else
96 | {
97 | MediaInfo MI = new MediaInfo();
98 | string duration;
99 | MI.Open(this.filePath);
100 | duration = MI.Get(StreamKind.Audio, 0, 69);
101 | this.outputAudioFormat = MI.Get(StreamKind.Audio, 0, "Format");
102 | if (String.IsNullOrWhiteSpace(duration))
103 | {
104 | return ONLYVIDEO;
105 | }
106 | else
107 | {
108 | if (CheckBoxCompatibility(this.outputAudioFormat, this.ts.outputFormat))
109 | {
110 | return COPYAUDIO;
111 | }
112 | else
113 | {
114 | this.outputAudioFormat = "aac";
115 | return SUPPRESSAUDIO;
116 | }
117 | }
118 | }
119 | } else
120 | {
121 | // 判断是否为avs文件
122 |
123 | string ext = this.getFileExtName(this.filePath);
124 | if (String.Equals(ext, "avs", StringComparison.CurrentCultureIgnoreCase))
125 | {
126 | string[] avsLines = File.ReadAllLines(this.filePath);
127 | for (int i = 0; i < avsLines.Length; i++)
128 | {
129 | int startIdx = avsLines[i].IndexOf("Source(\"");
130 | int endIdx;
131 | if (startIdx != -1)
132 | {
133 | endIdx = avsLines[i].IndexOf("\")");
134 | startIdx += 8;
135 | this.avsVideoPath = avsLines[i].Substring(startIdx, endIdx - startIdx);
136 | break;
137 | }
138 | }
139 | MediaInfo MI = new MediaInfo();
140 | string duration;
141 | MI.Open(this.avsVideoPath);
142 | duration = MI.Get(StreamKind.Audio, 0, 69);
143 | if (String.IsNullOrWhiteSpace(duration))
144 | {
145 | return ONLYVIDEO;
146 | }
147 | else
148 | {
149 | this.outputAudioFormat = "aac";
150 | return SUPPRESSAUDIO;
151 | }
152 | }
153 | else
154 | {
155 | MediaInfo MI = new MediaInfo();
156 | string duration;
157 | MI.Open(this.filePath);
158 | duration = MI.Get(StreamKind.Audio, 0, 69);
159 | if (String.IsNullOrWhiteSpace(duration))
160 | {
161 | return ONLYVIDEO;
162 | }
163 | else
164 | {
165 | this.outputAudioFormat = "aac";
166 | return SUPPRESSAUDIO;
167 | }
168 | }
169 | }
170 | }
171 |
172 | public string getAudioSource()
173 | {
174 | string audioSource = String.IsNullOrEmpty(this.avsVideoPath) ? this.filePath : this.avsVideoPath;
175 | return audioSource;
176 | }
177 |
178 | public string cmdCodeGenerate(int mode, int vmode = 0)
179 | {
180 | string fp = this.filePath;
181 | string audioSource = String.IsNullOrEmpty(this.avsVideoPath) ? fp : this.avsVideoPath;
182 |
183 | string qaacPath = System.Windows.Forms.Application.StartupPath + "\\tools\\qaac\\qaac.exe";
184 | string ffmpegPath = System.Windows.Forms.Application.StartupPath + "\\tools\\ffmpeg\\ffmpeg.exe";
185 | string x26xPath = System.Windows.Forms.Application.StartupPath + "\\tools\\x26x\\" + ts.encoder;
186 | string mp4BoxPath = System.Windows.Forms.Application.StartupPath + "\\tools\\mp4Box\\MP4Box.exe";
187 | //string lsmashRemuxerPath = System.Windows.Forms.Application.StartupPath + "\\tools\\L-Smash\\remuxer.exe";
188 | string mkvmergePath = System.Windows.Forms.Application.StartupPath + "\\tools\\mkvmerge\\mkvmerge.exe";
189 | string avsPath = System.Windows.Forms.Application.StartupPath + "\\tools\\avs\\avs4x265.exe";
190 |
191 | string code = "";
192 |
193 | string suffix = this.taskType() == ONLYVIDEO ? "_evt" : "_temp";
194 | if (String.IsNullOrWhiteSpace(this.outputFolderPath))
195 | {
196 | this.outputFolderPath = getPureFolderName(fp);
197 | }
198 |
199 | string outputFilePath = this.outputFolderPath + getPureFileName(fp) + "_" + this.ts.name + "." + ts.outputFormat;
200 | string videoTempExt = ts.encoder == "x265-10bit.exe" ? ".hevc" : ".264";
201 | string videoTempPath = this.outputFolderPath + ts.name + "_temp" + videoTempExt;
202 | string mp4BoxTempPath = this.outputFolderPath.Substring(0, this.outputFolderPath.Length - 1); // tmp路径末尾不能有斜杠,否则parse出错(坑爹的gpac)
203 | string audioTempPath = this.outputFolderPath + getPureFileName(fp) + "_audioTemp." + this.outputAudioFormat;
204 |
205 | switch (mode)
206 | {
207 | case VIDEOENCODE:
208 | switch (vmode)
209 | {
210 | case NORMAL:
211 | string y4m = ts.encoder == "x265-10bit.exe" ? " --y4m " : " --demuxer y4m ";
212 | code = "\"" + ffmpegPath + "\"" + " -i " + "\"" + fp + "\"" + " -strict -1 -f yuv4mpegpipe -an - | "
213 | + "\"" + x26xPath + "\"" + y4m + ts.encoderSetting + " -o " + "\"" + videoTempPath + "\"" + " -";
214 | break;
215 | case AVS:
216 | // Example:
217 | // "C:\Users\fdws\Downloads\avs4x265.exe" -L
218 | // "C:\Users\fdws\Desktop\Trans\EVT_alpha\tools\x26x\x264_64-10bit.exe"
219 | // --crf 24.5 -o "C:\Users\fdws\Desktop\Trans\01_batch.mp4" "C:\Users\fdws\Desktop\Trans\01.avs"
220 |
221 | code = "\"" + avsPath + "\"" + " -L " + "\"" + x26xPath + "\" " + ts.encoderSetting + " -o " + "\"" + videoTempPath + "\""
222 | + " \"" + fp + "\"";
223 | break;
224 | default:
225 | break;
226 | }
227 |
228 | break;
229 | case AUDIOCOPY:
230 | code = "\"" + ffmpegPath + "\"" + " -i " + "\"" + audioSource
231 | + "\"" + " -vn -sn -async 1 -c:a copy -y -map 0:a:0 " + "\"" + audioTempPath + "\"";
232 | break;
233 | case MUXER:
234 | if (String.Equals(ts.outputFormat, "mp4", StringComparison.CurrentCultureIgnoreCase))
235 | {
236 | if (this.taskType() == ONLYVIDEO)
237 | {
238 | code = "\"" + mp4BoxPath + "\"" + " -add " + "\"" + videoTempPath + "\"" +
239 | " " + "\"" + outputFilePath + "\"" + " -tmp " + "\"" + mp4BoxTempPath + "\"";
240 | }
241 | else
242 | {
243 | code = "\"" + mp4BoxPath + "\"" + " -add " + "\"" + videoTempPath + "\"" +
244 | " -add " + "\"" + audioTempPath + "\"" + " " + "\"" + outputFilePath + "\"" + " -tmp " + "\"" + mp4BoxTempPath + "\"";
245 | }
246 |
247 | // tmp文件夹设定在输出位置,不设置的话默认C盘,当C盘空间不足以存放一个视频压制后的.mp4文件时任务就会失败
248 | }
249 | else if (String.Equals(ts.outputFormat, "mkv", StringComparison.CurrentCultureIgnoreCase))
250 | {
251 | if (this.taskType() == ONLYVIDEO)
252 | {
253 | code += "\"" + mkvmergePath + "\"" + " -o " + "\"" + outputFilePath + "\"" + " " + "\"" + videoTempPath +
254 | "\"";
255 | }
256 | else
257 | {
258 | code += "\"" + mkvmergePath + "\"" + " -o " + "\"" + outputFilePath + "\"" + " " + "\"" + videoTempPath +
259 | "\"" + " " + "\"" + audioTempPath + "\"";
260 | }
261 | }
262 |
263 | break;
264 |
265 | case DELETEVIDEOTEMP:
266 | code = videoTempPath;
267 | break;
268 | case DELETEAUDIOTEMP:
269 | code = audioTempPath;
270 | break;
271 |
272 | case AUDIOENCODE:
273 | if (String.Equals(this.ts.audioEncoder, "qaac", StringComparison.CurrentCultureIgnoreCase)
274 | || String.Equals(this.ts.audioEncoder, "复制音频流", StringComparison.CurrentCultureIgnoreCase))
275 | {
276 | code = "\"" + ffmpegPath + "\"" + " -i " + "\"" + audioSource + "\"" + " -vn -sn -v 0 -async 1 -c:a pcm_s16le -f wav pipe:|" + "\"" + qaacPath + "\"" + " - --ignorelength";
277 | if (string.Equals(this.ts.audioProfile, "HE-AAC"))
278 | {
279 | code += " --he";
280 | }
281 |
282 | if (string.Equals(this.ts.audioProfile, "ALAC"))
283 | {
284 | code += " -A";
285 | break;
286 | }
287 |
288 | if (string.Equals(this.ts.audioCodecMode, "TVBR"))
289 | {
290 | code += " -V " + this.ts.audioQuality.ToString();
291 | }
292 | else if (string.Equals(this.ts.audioCodecMode, "CVBR"))
293 | {
294 | code += " -v " + this.ts.audioKbps.ToString();
295 | }
296 | else if (string.Equals(this.ts.audioCodecMode, "ABR"))
297 | {
298 | code += " -a " + this.ts.audioKbps.ToString();
299 | }
300 | else if (string.Equals(this.ts.audioCodecMode, "CBR"))
301 | {
302 | code += " -c " + this.ts.audioKbps.ToString();
303 | }
304 |
305 | code += " -o " + "\"" + audioTempPath + "\"";
306 | }
307 | break;
308 | default:
309 | break;
310 | }
311 |
312 | //code = "\"" + ffmpegPath + "\"" + " -i " + "\"" + fp + "\"" + " -vn -sn -v 0 -async 1 -c:a pcm_s16le -f wav pipe:|" + "\"" + qaacPath + "\"" + " - --ignorelength";
313 |
314 | //MessageBox.Show(code);
315 | return code;
316 | }
317 |
318 | private bool CheckBoxCompatibility(string audioFormat, string fileFormat)
319 | {
320 | if (String.Equals(fileFormat, "mkv", StringComparison.CurrentCultureIgnoreCase))
321 | {
322 | if (String.Equals(audioFormat, "AAC", StringComparison.CurrentCultureIgnoreCase)
323 | || String.Equals(audioFormat, "FLAC", StringComparison.CurrentCultureIgnoreCase)
324 | || String.Equals(audioFormat, "DTS", StringComparison.CurrentCultureIgnoreCase))
325 | {
326 | return true;
327 | }
328 | else
329 | {
330 | return false;
331 | }
332 | }
333 | else if (String.Equals(fileFormat, "mp4", StringComparison.CurrentCultureIgnoreCase))
334 | {
335 | if (String.Equals(audioFormat, "AAC", StringComparison.CurrentCultureIgnoreCase))
336 | {
337 | return true;
338 | }
339 | else
340 | {
341 | return false;
342 | }
343 | }
344 | return false;
345 | }
346 |
347 | private bool losslessCheckByExtension(string extension)
348 | {
349 | string[] losslessExt = { "wav", "flac", "ape" };
350 | return this.multiStringEqualCheck(losslessExt, extension);
351 | }
352 |
353 | private bool multiStringEqualCheck(string[] targets, string source)
354 | {
355 | int len = targets.Length;
356 | for (int i = 0; i < len; i++)
357 | {
358 | if (string.Equals(targets[i], source))
359 | {
360 | return true;
361 | }
362 | }
363 | return false;
364 | }
365 |
366 | private string changeFileExtName(string originFp, string ext = "")
367 | {
368 | string[] s = originFp.Split(new char[] { '.' });
369 | int length = s.Length;
370 | s[length - 1] = ext;
371 | string finalFileName = "";
372 | for (int i = 0; i < length; i++)
373 | {
374 | finalFileName += s[i];
375 | if (i != length - 1)
376 | {
377 | finalFileName += ".";
378 | }
379 | }
380 | if (string.IsNullOrWhiteSpace(ext)) // 当需要的扩展名为空时,去除字符串最后位置的一个点
381 | {
382 | finalFileName = finalFileName.Substring(0, finalFileName.Length - 1);
383 | }
384 | return finalFileName;
385 | }
386 |
387 | // 获得纯净的文件名,不含路径和扩展名和点
388 | private string getPureFileName(string fp)
389 | {
390 | string[] s = fp.Split(new char[] { '\\' });
391 | int length = s.Length;
392 | string fileNameWithExt = s[length - 1];
393 | return changeFileExtName(fileNameWithExt, "");
394 | }
395 |
396 | private string getPureFolderName(string fp)
397 | {
398 | string[] s = fp.Split(new char[] { '\\' });
399 | int length = s.Length;
400 | string dest = "";
401 | for (int i = 0; i < length - 1; i++)
402 | {
403 | dest += s[i];
404 | dest += "\\";
405 | }
406 | return dest;
407 | }
408 |
409 | private string getFileExtName(string originFp)
410 | {
411 | string[] s = originFp.Split(new char[] { '.' });
412 | int length = s.Length;
413 | return s[length - 1];
414 | }
415 | }
416 | }
417 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/RunningStatusForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ExpertVideoToolbox
2 | {
3 | partial class RunningStatusForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.stopBtn = new System.Windows.Forms.Button();
32 | this.statusStrip1 = new System.Windows.Forms.StatusStrip();
33 | this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
34 | this.filesCountLabel = new System.Windows.Forms.ToolStripStatusLabel();
35 | this.progress = new System.Windows.Forms.ProgressBar();
36 | this.estETADataTB = new System.Windows.Forms.TextBox();
37 | this.estETALabel = new System.Windows.Forms.Label();
38 | this.currentPositionLabel = new System.Windows.Forms.Label();
39 | this.fpsDataTB = new System.Windows.Forms.TextBox();
40 | this.fpsLabel = new System.Windows.Forms.Label();
41 | this.currentPostionDataTB = new System.Windows.Forms.TextBox();
42 | this.datagB = new System.Windows.Forms.GroupBox();
43 | this.estKbpsDataTB = new System.Windows.Forms.TextBox();
44 | this.estKbpsLabel = new System.Windows.Forms.Label();
45 | this.progressLabel = new System.Windows.Forms.Label();
46 | this.taskStepsLabel = new System.Windows.Forms.Label();
47 | this.fullSpeedBtn = new System.Windows.Forms.Button();
48 | this.lowSpeedBtn = new System.Windows.Forms.Button();
49 | this.encoderPriority = new System.Windows.Forms.Label();
50 | this.priorityCB = new System.Windows.Forms.ComboBox();
51 | this.statusStrip1.SuspendLayout();
52 | this.datagB.SuspendLayout();
53 | this.SuspendLayout();
54 | //
55 | // stopBtn
56 | //
57 | this.stopBtn.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
58 | this.stopBtn.Location = new System.Drawing.Point(12, 217);
59 | this.stopBtn.Name = "stopBtn";
60 | this.stopBtn.Size = new System.Drawing.Size(64, 23);
61 | this.stopBtn.TabIndex = 14;
62 | this.stopBtn.Text = "中止";
63 | this.stopBtn.UseVisualStyleBackColor = true;
64 | this.stopBtn.Click += new System.EventHandler(this.stopBtn_Click);
65 | //
66 | // statusStrip1
67 | //
68 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
69 | this.statusLabel,
70 | this.filesCountLabel});
71 | this.statusStrip1.Location = new System.Drawing.Point(0, 249);
72 | this.statusStrip1.Name = "statusStrip1";
73 | this.statusStrip1.Size = new System.Drawing.Size(407, 22);
74 | this.statusStrip1.SizingGrip = false;
75 | this.statusStrip1.TabIndex = 13;
76 | this.statusStrip1.Text = "statusStrip1";
77 | //
78 | // statusLabel
79 | //
80 | this.statusLabel.Name = "statusLabel";
81 | this.statusLabel.Size = new System.Drawing.Size(39, 17);
82 | this.statusLabel.Text = "状态: ";
83 | //
84 | // filesCountLabel
85 | //
86 | this.filesCountLabel.Name = "filesCountLabel";
87 | this.filesCountLabel.Size = new System.Drawing.Size(27, 17);
88 | this.filesCountLabel.Text = "0/1";
89 | //
90 | // progress
91 | //
92 | this.progress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
93 | | System.Windows.Forms.AnchorStyles.Right)));
94 | this.progress.Location = new System.Drawing.Point(12, 186);
95 | this.progress.Name = "progress";
96 | this.progress.Size = new System.Drawing.Size(377, 23);
97 | this.progress.TabIndex = 12;
98 | //
99 | // estETADataTB
100 | //
101 | this.estETADataTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
102 | | System.Windows.Forms.AnchorStyles.Right)));
103 | this.estETADataTB.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
104 | this.estETADataTB.Location = new System.Drawing.Point(94, 73);
105 | this.estETADataTB.Name = "estETADataTB";
106 | this.estETADataTB.ReadOnly = true;
107 | this.estETADataTB.Size = new System.Drawing.Size(283, 25);
108 | this.estETADataTB.TabIndex = 21;
109 | this.estETADataTB.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
110 | //
111 | // estETALabel
112 | //
113 | this.estETALabel.AutoSize = true;
114 | this.estETALabel.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
115 | this.estETALabel.Location = new System.Drawing.Point(8, 79);
116 | this.estETALabel.Name = "estETALabel";
117 | this.estETALabel.Size = new System.Drawing.Size(80, 17);
118 | this.estETALabel.TabIndex = 6;
119 | this.estETALabel.Text = "预计剩余时间";
120 | //
121 | // currentPositionLabel
122 | //
123 | this.currentPositionLabel.AutoSize = true;
124 | this.currentPositionLabel.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
125 | this.currentPositionLabel.Location = new System.Drawing.Point(8, 23);
126 | this.currentPositionLabel.Name = "currentPositionLabel";
127 | this.currentPositionLabel.Size = new System.Drawing.Size(73, 17);
128 | this.currentPositionLabel.TabIndex = 0;
129 | this.currentPositionLabel.Text = "已完成/总计";
130 | //
131 | // fpsDataTB
132 | //
133 | this.fpsDataTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
134 | | System.Windows.Forms.AnchorStyles.Right)));
135 | this.fpsDataTB.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
136 | this.fpsDataTB.Location = new System.Drawing.Point(94, 45);
137 | this.fpsDataTB.Name = "fpsDataTB";
138 | this.fpsDataTB.ReadOnly = true;
139 | this.fpsDataTB.Size = new System.Drawing.Size(283, 25);
140 | this.fpsDataTB.TabIndex = 17;
141 | this.fpsDataTB.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
142 | //
143 | // fpsLabel
144 | //
145 | this.fpsLabel.AutoSize = true;
146 | this.fpsLabel.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
147 | this.fpsLabel.Location = new System.Drawing.Point(8, 50);
148 | this.fpsLabel.Name = "fpsLabel";
149 | this.fpsLabel.Size = new System.Drawing.Size(56, 17);
150 | this.fpsLabel.TabIndex = 2;
151 | this.fpsLabel.Text = "编码速度";
152 | //
153 | // currentPostionDataTB
154 | //
155 | this.currentPostionDataTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
156 | | System.Windows.Forms.AnchorStyles.Right)));
157 | this.currentPostionDataTB.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
158 | this.currentPostionDataTB.ForeColor = System.Drawing.SystemColors.WindowText;
159 | this.currentPostionDataTB.Location = new System.Drawing.Point(94, 18);
160 | this.currentPostionDataTB.Name = "currentPostionDataTB";
161 | this.currentPostionDataTB.ReadOnly = true;
162 | this.currentPostionDataTB.Size = new System.Drawing.Size(283, 25);
163 | this.currentPostionDataTB.TabIndex = 15;
164 | this.currentPostionDataTB.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
165 | //
166 | // datagB
167 | //
168 | this.datagB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
169 | | System.Windows.Forms.AnchorStyles.Right)));
170 | this.datagB.Controls.Add(this.estKbpsDataTB);
171 | this.datagB.Controls.Add(this.estKbpsLabel);
172 | this.datagB.Controls.Add(this.estETADataTB);
173 | this.datagB.Controls.Add(this.estETALabel);
174 | this.datagB.Controls.Add(this.currentPositionLabel);
175 | this.datagB.Controls.Add(this.fpsDataTB);
176 | this.datagB.Controls.Add(this.fpsLabel);
177 | this.datagB.Controls.Add(this.currentPostionDataTB);
178 | this.datagB.Location = new System.Drawing.Point(12, 36);
179 | this.datagB.Name = "datagB";
180 | this.datagB.Size = new System.Drawing.Size(383, 138);
181 | this.datagB.TabIndex = 11;
182 | this.datagB.TabStop = false;
183 | //
184 | // estKbpsDataTB
185 | //
186 | this.estKbpsDataTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
187 | | System.Windows.Forms.AnchorStyles.Right)));
188 | this.estKbpsDataTB.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
189 | this.estKbpsDataTB.Location = new System.Drawing.Point(94, 102);
190 | this.estKbpsDataTB.Name = "estKbpsDataTB";
191 | this.estKbpsDataTB.ReadOnly = true;
192 | this.estKbpsDataTB.Size = new System.Drawing.Size(283, 25);
193 | this.estKbpsDataTB.TabIndex = 23;
194 | this.estKbpsDataTB.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
195 | //
196 | // estKbpsLabel
197 | //
198 | this.estKbpsLabel.AutoSize = true;
199 | this.estKbpsLabel.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
200 | this.estKbpsLabel.Location = new System.Drawing.Point(8, 107);
201 | this.estKbpsLabel.Name = "estKbpsLabel";
202 | this.estKbpsLabel.Size = new System.Drawing.Size(56, 17);
203 | this.estKbpsLabel.TabIndex = 22;
204 | this.estKbpsLabel.Text = "预计码率";
205 | //
206 | // progressLabel
207 | //
208 | this.progressLabel.Font = new System.Drawing.Font("Microsoft YaHei UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
209 | this.progressLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
210 | this.progressLabel.Location = new System.Drawing.Point(327, 218);
211 | this.progressLabel.Name = "progressLabel";
212 | this.progressLabel.Size = new System.Drawing.Size(62, 20);
213 | this.progressLabel.TabIndex = 15;
214 | this.progressLabel.Text = "0.00%";
215 | this.progressLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
216 | //
217 | // taskStepsLabel
218 | //
219 | this.taskStepsLabel.AutoSize = true;
220 | this.taskStepsLabel.Font = new System.Drawing.Font("微软雅黑", 11.25F);
221 | this.taskStepsLabel.Location = new System.Drawing.Point(12, 13);
222 | this.taskStepsLabel.Name = "taskStepsLabel";
223 | this.taskStepsLabel.Size = new System.Drawing.Size(216, 20);
224 | this.taskStepsLabel.TabIndex = 16;
225 | this.taskStepsLabel.Text = "正在进行:步骤 1/3 - 复制音频";
226 | //
227 | // fullSpeedBtn
228 | //
229 | this.fullSpeedBtn.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
230 | this.fullSpeedBtn.Location = new System.Drawing.Point(230, 217);
231 | this.fullSpeedBtn.Name = "fullSpeedBtn";
232 | this.fullSpeedBtn.Size = new System.Drawing.Size(46, 23);
233 | this.fullSpeedBtn.TabIndex = 17;
234 | this.fullSpeedBtn.Text = "正常";
235 | this.fullSpeedBtn.UseVisualStyleBackColor = true;
236 | this.fullSpeedBtn.VisibleChanged += new System.EventHandler(this.fullSpeedBtn_VisibleChanged);
237 | this.fullSpeedBtn.Click += new System.EventHandler(this.fullSpeedBtn_Click);
238 | //
239 | // lowSpeedBtn
240 | //
241 | this.lowSpeedBtn.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
242 | this.lowSpeedBtn.Location = new System.Drawing.Point(274, 217);
243 | this.lowSpeedBtn.Name = "lowSpeedBtn";
244 | this.lowSpeedBtn.Size = new System.Drawing.Size(45, 23);
245 | this.lowSpeedBtn.TabIndex = 18;
246 | this.lowSpeedBtn.Text = "低速";
247 | this.lowSpeedBtn.UseVisualStyleBackColor = true;
248 | this.lowSpeedBtn.Click += new System.EventHandler(this.lowSpeedBtn_Click);
249 | //
250 | // encoderPriority
251 | //
252 | this.encoderPriority.AutoSize = true;
253 | this.encoderPriority.Font = new System.Drawing.Font("微软雅黑", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
254 | this.encoderPriority.Location = new System.Drawing.Point(82, 218);
255 | this.encoderPriority.Name = "encoderPriority";
256 | this.encoderPriority.Size = new System.Drawing.Size(51, 20);
257 | this.encoderPriority.TabIndex = 19;
258 | this.encoderPriority.Text = "优先级";
259 | //
260 | // priorityCB
261 | //
262 | this.priorityCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
263 | this.priorityCB.FormattingEnabled = true;
264 | this.priorityCB.Items.AddRange(new object[] {
265 | "低",
266 | "低于正常",
267 | "正常",
268 | "高于正常",
269 | "高",
270 | "实时"});
271 | this.priorityCB.Location = new System.Drawing.Point(137, 218);
272 | this.priorityCB.Name = "priorityCB";
273 | this.priorityCB.Size = new System.Drawing.Size(79, 20);
274 | this.priorityCB.TabIndex = 20;
275 | this.priorityCB.SelectedIndexChanged += new System.EventHandler(this.priorityCB_SelectedIndexChanged);
276 | //
277 | // RunningStatusForm
278 | //
279 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
280 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
281 | this.ClientSize = new System.Drawing.Size(407, 271);
282 | this.Controls.Add(this.priorityCB);
283 | this.Controls.Add(this.encoderPriority);
284 | this.Controls.Add(this.lowSpeedBtn);
285 | this.Controls.Add(this.fullSpeedBtn);
286 | this.Controls.Add(this.taskStepsLabel);
287 | this.Controls.Add(this.progressLabel);
288 | this.Controls.Add(this.stopBtn);
289 | this.Controls.Add(this.statusStrip1);
290 | this.Controls.Add(this.progress);
291 | this.Controls.Add(this.datagB);
292 | this.Name = "RunningStatusForm";
293 | this.Text = "RunningStatusForm";
294 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.RunningStatusForm_FormClosing);
295 | this.Shown += new System.EventHandler(this.RunningStatusForm_Shown);
296 | this.statusStrip1.ResumeLayout(false);
297 | this.statusStrip1.PerformLayout();
298 | this.datagB.ResumeLayout(false);
299 | this.datagB.PerformLayout();
300 | this.ResumeLayout(false);
301 | this.PerformLayout();
302 |
303 | }
304 |
305 | #endregion
306 |
307 | private System.Windows.Forms.Button stopBtn;
308 | private System.Windows.Forms.StatusStrip statusStrip1;
309 | private System.Windows.Forms.ToolStripStatusLabel statusLabel;
310 | private System.Windows.Forms.ToolStripStatusLabel filesCountLabel;
311 | private System.Windows.Forms.ProgressBar progress;
312 | private System.Windows.Forms.TextBox estETADataTB;
313 | private System.Windows.Forms.Label estETALabel;
314 | private System.Windows.Forms.Label currentPositionLabel;
315 | private System.Windows.Forms.TextBox fpsDataTB;
316 | private System.Windows.Forms.Label fpsLabel;
317 | private System.Windows.Forms.TextBox currentPostionDataTB;
318 | private System.Windows.Forms.GroupBox datagB;
319 | private System.Windows.Forms.Label progressLabel;
320 | private System.Windows.Forms.Label taskStepsLabel;
321 | private System.Windows.Forms.Button fullSpeedBtn;
322 | private System.Windows.Forms.Button lowSpeedBtn;
323 | private System.Windows.Forms.Label encoderPriority;
324 | private System.Windows.Forms.ComboBox priorityCB;
325 | private System.Windows.Forms.TextBox estKbpsDataTB;
326 | private System.Windows.Forms.Label estKbpsLabel;
327 | }
328 | }
--------------------------------------------------------------------------------
/ExpertVideoToolbox/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ExpertVideoToolbox
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows 窗体设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.removeAllBtn = new System.Windows.Forms.Button();
32 | this.removeFileBtn = new System.Windows.Forms.Button();
33 | this.addFolderBtn = new System.Windows.Forms.Button();
34 | this.addFileBtn = new System.Windows.Forms.Button();
35 | this.videoSetgB = new System.Windows.Forms.GroupBox();
36 | this.cmdCodeTB = new System.Windows.Forms.TextBox();
37 | this.encoderCB = new System.Windows.Forms.ComboBox();
38 | this.encoderLabel = new System.Windows.Forms.Label();
39 | this.brORqLabel = new System.Windows.Forms.Label();
40 | this.fileFormatCB = new System.Windows.Forms.ComboBox();
41 | this.fileFormatLabel = new System.Windows.Forms.Label();
42 | this.removeSettingBtn = new System.Windows.Forms.Button();
43 | this.addSettingBtn = new System.Windows.Forms.Button();
44 | this.encodeSettinglabel = new System.Windows.Forms.Label();
45 | this.encodeSettingCB = new System.Windows.Forms.ComboBox();
46 | this.set2SelectedBtn = new System.Windows.Forms.Button();
47 | this.set2AllBtn = new System.Windows.Forms.Button();
48 | this.StartBtn = new System.Windows.Forms.Button();
49 | this.fileListView = new System.Windows.Forms.ListView();
50 | this.outputFilePathlabel = new System.Windows.Forms.Label();
51 | this.outputFilePathTB = new System.Windows.Forms.TextBox();
52 | this.chooseOutputPathBtn = new System.Windows.Forms.Button();
53 | this.audioSetgB = new System.Windows.Forms.GroupBox();
54 | this.profileCB = new System.Windows.Forms.ComboBox();
55 | this.profileLabel = new System.Windows.Forms.Label();
56 | this.bitrateOrQualityCB = new System.Windows.Forms.ComboBox();
57 | this.bitrateOrQualityLabel = new System.Windows.Forms.Label();
58 | this.codecModeCB = new System.Windows.Forms.ComboBox();
59 | this.codecModeLabel = new System.Windows.Forms.Label();
60 | this.audioEncoderCB = new System.Windows.Forms.ComboBox();
61 | this.audioEncoder = new System.Windows.Forms.Label();
62 | this.label3 = new System.Windows.Forms.Label();
63 | this.videoSetgB.SuspendLayout();
64 | this.audioSetgB.SuspendLayout();
65 | this.SuspendLayout();
66 | //
67 | // removeAllBtn
68 | //
69 | this.removeAllBtn.Location = new System.Drawing.Point(395, 178);
70 | this.removeAllBtn.Name = "removeAllBtn";
71 | this.removeAllBtn.Size = new System.Drawing.Size(75, 23);
72 | this.removeAllBtn.TabIndex = 8;
73 | this.removeAllBtn.Text = "移除所有";
74 | this.removeAllBtn.UseVisualStyleBackColor = true;
75 | this.removeAllBtn.Click += new System.EventHandler(this.removeAllBtn_Click);
76 | //
77 | // removeFileBtn
78 | //
79 | this.removeFileBtn.Location = new System.Drawing.Point(314, 178);
80 | this.removeFileBtn.Name = "removeFileBtn";
81 | this.removeFileBtn.Size = new System.Drawing.Size(75, 23);
82 | this.removeFileBtn.TabIndex = 7;
83 | this.removeFileBtn.Text = "移除文件";
84 | this.removeFileBtn.UseVisualStyleBackColor = true;
85 | this.removeFileBtn.Click += new System.EventHandler(this.removeFileBtn_Click);
86 | //
87 | // addFolderBtn
88 | //
89 | this.addFolderBtn.Location = new System.Drawing.Point(93, 178);
90 | this.addFolderBtn.Name = "addFolderBtn";
91 | this.addFolderBtn.Size = new System.Drawing.Size(75, 23);
92 | this.addFolderBtn.TabIndex = 6;
93 | this.addFolderBtn.Text = "添加文件夹";
94 | this.addFolderBtn.UseVisualStyleBackColor = true;
95 | this.addFolderBtn.Click += new System.EventHandler(this.addFolderBtn_Click);
96 | //
97 | // addFileBtn
98 | //
99 | this.addFileBtn.Location = new System.Drawing.Point(12, 178);
100 | this.addFileBtn.Name = "addFileBtn";
101 | this.addFileBtn.Size = new System.Drawing.Size(75, 23);
102 | this.addFileBtn.TabIndex = 5;
103 | this.addFileBtn.Text = "添加文件";
104 | this.addFileBtn.UseVisualStyleBackColor = true;
105 | this.addFileBtn.Click += new System.EventHandler(this.addFileBtn_Click);
106 | //
107 | // videoSetgB
108 | //
109 | this.videoSetgB.Controls.Add(this.cmdCodeTB);
110 | this.videoSetgB.Controls.Add(this.encoderCB);
111 | this.videoSetgB.Controls.Add(this.encoderLabel);
112 | this.videoSetgB.Controls.Add(this.brORqLabel);
113 | this.videoSetgB.Controls.Add(this.fileFormatCB);
114 | this.videoSetgB.Controls.Add(this.fileFormatLabel);
115 | this.videoSetgB.Location = new System.Drawing.Point(14, 279);
116 | this.videoSetgB.Name = "videoSetgB";
117 | this.videoSetgB.Size = new System.Drawing.Size(377, 143);
118 | this.videoSetgB.TabIndex = 9;
119 | this.videoSetgB.TabStop = false;
120 | this.videoSetgB.Text = "视频流设置";
121 | //
122 | // cmdCodeTB
123 | //
124 | this.cmdCodeTB.Font = new System.Drawing.Font("微软雅黑", 9F);
125 | this.cmdCodeTB.Location = new System.Drawing.Point(6, 46);
126 | this.cmdCodeTB.Multiline = true;
127 | this.cmdCodeTB.Name = "cmdCodeTB";
128 | this.cmdCodeTB.Size = new System.Drawing.Size(357, 91);
129 | this.cmdCodeTB.TabIndex = 11;
130 | this.cmdCodeTB.Text = "--crf 20 --level 4.1 --bframes 7 --b-adapt 2 --ref 4 --aq-mode 1 --aq-strength 0." +
131 | "7 --merange 32 --me umh --subme 10 --partitions all --trellis 2 --psy-rd 0.7:0 -" +
132 | "-deblock 0:0";
133 | //
134 | // encoderCB
135 | //
136 | this.encoderCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
137 | this.encoderCB.FormattingEnabled = true;
138 | this.encoderCB.Items.AddRange(new object[] {
139 | "x264_64-8bit.exe",
140 | "x264_64-10bit.exe",
141 | "x265-10bit.exe"});
142 | this.encoderCB.Location = new System.Drawing.Point(76, 20);
143 | this.encoderCB.Name = "encoderCB";
144 | this.encoderCB.Size = new System.Drawing.Size(152, 20);
145 | this.encoderCB.TabIndex = 6;
146 | //
147 | // encoderLabel
148 | //
149 | this.encoderLabel.AutoSize = true;
150 | this.encoderLabel.Location = new System.Drawing.Point(7, 23);
151 | this.encoderLabel.Name = "encoderLabel";
152 | this.encoderLabel.Size = new System.Drawing.Size(53, 12);
153 | this.encoderLabel.TabIndex = 5;
154 | this.encoderLabel.Text = "编码程序";
155 | //
156 | // brORqLabel
157 | //
158 | this.brORqLabel.AutoSize = true;
159 | this.brORqLabel.Location = new System.Drawing.Point(6, 55);
160 | this.brORqLabel.Name = "brORqLabel";
161 | this.brORqLabel.Size = new System.Drawing.Size(0, 12);
162 | this.brORqLabel.TabIndex = 3;
163 | //
164 | // fileFormatCB
165 | //
166 | this.fileFormatCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
167 | this.fileFormatCB.FormattingEnabled = true;
168 | this.fileFormatCB.Items.AddRange(new object[] {
169 | "mp4",
170 | "mkv"});
171 | this.fileFormatCB.Location = new System.Drawing.Point(289, 20);
172 | this.fileFormatCB.Name = "fileFormatCB";
173 | this.fileFormatCB.Size = new System.Drawing.Size(73, 20);
174 | this.fileFormatCB.TabIndex = 1;
175 | //
176 | // fileFormatLabel
177 | //
178 | this.fileFormatLabel.AutoSize = true;
179 | this.fileFormatLabel.Location = new System.Drawing.Point(231, 23);
180 | this.fileFormatLabel.Name = "fileFormatLabel";
181 | this.fileFormatLabel.Size = new System.Drawing.Size(53, 12);
182 | this.fileFormatLabel.TabIndex = 0;
183 | this.fileFormatLabel.Text = "文件格式";
184 | //
185 | // removeSettingBtn
186 | //
187 | this.removeSettingBtn.Location = new System.Drawing.Point(314, 250);
188 | this.removeSettingBtn.Name = "removeSettingBtn";
189 | this.removeSettingBtn.Size = new System.Drawing.Size(75, 23);
190 | this.removeSettingBtn.TabIndex = 10;
191 | this.removeSettingBtn.Text = "移除预设";
192 | this.removeSettingBtn.UseVisualStyleBackColor = true;
193 | this.removeSettingBtn.Click += new System.EventHandler(this.removeSettingBtn_Click);
194 | //
195 | // addSettingBtn
196 | //
197 | this.addSettingBtn.Location = new System.Drawing.Point(223, 250);
198 | this.addSettingBtn.Name = "addSettingBtn";
199 | this.addSettingBtn.Size = new System.Drawing.Size(85, 23);
200 | this.addSettingBtn.TabIndex = 9;
201 | this.addSettingBtn.Text = "添加预设";
202 | this.addSettingBtn.UseVisualStyleBackColor = true;
203 | this.addSettingBtn.Click += new System.EventHandler(this.addSettingBtn_Click);
204 | //
205 | // encodeSettinglabel
206 | //
207 | this.encodeSettinglabel.AutoSize = true;
208 | this.encodeSettinglabel.Location = new System.Drawing.Point(21, 255);
209 | this.encodeSettinglabel.Name = "encodeSettinglabel";
210 | this.encodeSettinglabel.Size = new System.Drawing.Size(53, 12);
211 | this.encodeSettinglabel.TabIndex = 8;
212 | this.encodeSettinglabel.Text = "编码预设";
213 | //
214 | // encodeSettingCB
215 | //
216 | this.encodeSettingCB.FormattingEnabled = true;
217 | this.encodeSettingCB.Location = new System.Drawing.Point(90, 252);
218 | this.encodeSettingCB.Name = "encodeSettingCB";
219 | this.encodeSettingCB.Size = new System.Drawing.Size(122, 20);
220 | this.encodeSettingCB.TabIndex = 7;
221 | this.encodeSettingCB.SelectedIndexChanged += new System.EventHandler(this.encodeSettingCB_SelectedIndexChanged);
222 | //
223 | // set2SelectedBtn
224 | //
225 | this.set2SelectedBtn.Location = new System.Drawing.Point(395, 250);
226 | this.set2SelectedBtn.Name = "set2SelectedBtn";
227 | this.set2SelectedBtn.Size = new System.Drawing.Size(74, 23);
228 | this.set2SelectedBtn.TabIndex = 10;
229 | this.set2SelectedBtn.Text = "应用到选中";
230 | this.set2SelectedBtn.UseVisualStyleBackColor = true;
231 | this.set2SelectedBtn.Click += new System.EventHandler(this.set2SelectedBtn_Click);
232 | //
233 | // set2AllBtn
234 | //
235 | this.set2AllBtn.Location = new System.Drawing.Point(394, 281);
236 | this.set2AllBtn.Name = "set2AllBtn";
237 | this.set2AllBtn.Size = new System.Drawing.Size(75, 23);
238 | this.set2AllBtn.TabIndex = 11;
239 | this.set2AllBtn.Text = "全部应用";
240 | this.set2AllBtn.UseVisualStyleBackColor = true;
241 | this.set2AllBtn.Click += new System.EventHandler(this.set2AllBtn_Click);
242 | //
243 | // StartBtn
244 | //
245 | this.StartBtn.Location = new System.Drawing.Point(397, 457);
246 | this.StartBtn.Name = "StartBtn";
247 | this.StartBtn.Size = new System.Drawing.Size(74, 53);
248 | this.StartBtn.TabIndex = 12;
249 | this.StartBtn.Text = "开始任务";
250 | this.StartBtn.UseVisualStyleBackColor = true;
251 | this.StartBtn.Click += new System.EventHandler(this.StartBtn_Click);
252 | //
253 | // fileListView
254 | //
255 | this.fileListView.AllowDrop = true;
256 | this.fileListView.Font = new System.Drawing.Font("微软雅黑", 8F);
257 | this.fileListView.Location = new System.Drawing.Point(12, 12);
258 | this.fileListView.Name = "fileListView";
259 | this.fileListView.Size = new System.Drawing.Size(457, 160);
260 | this.fileListView.TabIndex = 13;
261 | this.fileListView.UseCompatibleStateImageBehavior = false;
262 | this.fileListView.DragDrop += new System.Windows.Forms.DragEventHandler(this.fileListView_DragDrop);
263 | this.fileListView.DragEnter += new System.Windows.Forms.DragEventHandler(this.fileListView_DragEnter);
264 | //
265 | // outputFilePathlabel
266 | //
267 | this.outputFilePathlabel.AutoSize = true;
268 | this.outputFilePathlabel.Location = new System.Drawing.Point(21, 225);
269 | this.outputFilePathlabel.Name = "outputFilePathlabel";
270 | this.outputFilePathlabel.Size = new System.Drawing.Size(53, 12);
271 | this.outputFilePathlabel.TabIndex = 14;
272 | this.outputFilePathlabel.Text = "输出路径";
273 | //
274 | // outputFilePathTB
275 | //
276 | this.outputFilePathTB.Location = new System.Drawing.Point(90, 222);
277 | this.outputFilePathTB.Name = "outputFilePathTB";
278 | this.outputFilePathTB.Size = new System.Drawing.Size(299, 21);
279 | this.outputFilePathTB.TabIndex = 15;
280 | //
281 | // chooseOutputPathBtn
282 | //
283 | this.chooseOutputPathBtn.Location = new System.Drawing.Point(395, 222);
284 | this.chooseOutputPathBtn.Name = "chooseOutputPathBtn";
285 | this.chooseOutputPathBtn.Size = new System.Drawing.Size(75, 23);
286 | this.chooseOutputPathBtn.TabIndex = 16;
287 | this.chooseOutputPathBtn.Text = "浏览";
288 | this.chooseOutputPathBtn.UseVisualStyleBackColor = true;
289 | this.chooseOutputPathBtn.Click += new System.EventHandler(this.chooseOutputPathBtn_Click);
290 | //
291 | // audioSetgB
292 | //
293 | this.audioSetgB.Controls.Add(this.profileCB);
294 | this.audioSetgB.Controls.Add(this.profileLabel);
295 | this.audioSetgB.Controls.Add(this.bitrateOrQualityCB);
296 | this.audioSetgB.Controls.Add(this.bitrateOrQualityLabel);
297 | this.audioSetgB.Controls.Add(this.codecModeCB);
298 | this.audioSetgB.Controls.Add(this.codecModeLabel);
299 | this.audioSetgB.Controls.Add(this.audioEncoderCB);
300 | this.audioSetgB.Controls.Add(this.audioEncoder);
301 | this.audioSetgB.Controls.Add(this.label3);
302 | this.audioSetgB.Location = new System.Drawing.Point(14, 428);
303 | this.audioSetgB.Name = "audioSetgB";
304 | this.audioSetgB.Size = new System.Drawing.Size(377, 82);
305 | this.audioSetgB.TabIndex = 17;
306 | this.audioSetgB.TabStop = false;
307 | this.audioSetgB.Text = "音频流设置";
308 | //
309 | // profileCB
310 | //
311 | this.profileCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
312 | this.profileCB.FormattingEnabled = true;
313 | this.profileCB.Location = new System.Drawing.Point(289, 24);
314 | this.profileCB.Name = "profileCB";
315 | this.profileCB.Size = new System.Drawing.Size(75, 20);
316 | this.profileCB.TabIndex = 12;
317 | this.profileCB.SelectedIndexChanged += new System.EventHandler(this.profileCB_SelectedIndexChanged);
318 | //
319 | // profileLabel
320 | //
321 | this.profileLabel.AutoSize = true;
322 | this.profileLabel.Location = new System.Drawing.Point(236, 27);
323 | this.profileLabel.Name = "profileLabel";
324 | this.profileLabel.Size = new System.Drawing.Size(47, 12);
325 | this.profileLabel.TabIndex = 11;
326 | this.profileLabel.Text = "Profile";
327 | //
328 | // bitrateOrQualityCB
329 | //
330 | this.bitrateOrQualityCB.FormattingEnabled = true;
331 | this.bitrateOrQualityCB.Items.AddRange(new object[] {
332 | "0",
333 | "9",
334 | "18",
335 | "27",
336 | "36",
337 | "45",
338 | "54",
339 | "63",
340 | "73",
341 | "82",
342 | "91",
343 | "100",
344 | "109",
345 | "118",
346 | "127"});
347 | this.bitrateOrQualityCB.Location = new System.Drawing.Point(255, 52);
348 | this.bitrateOrQualityCB.Name = "bitrateOrQualityCB";
349 | this.bitrateOrQualityCB.Size = new System.Drawing.Size(110, 20);
350 | this.bitrateOrQualityCB.TabIndex = 10;
351 | //
352 | // bitrateOrQualityLabel
353 | //
354 | this.bitrateOrQualityLabel.AutoSize = true;
355 | this.bitrateOrQualityLabel.Location = new System.Drawing.Point(220, 55);
356 | this.bitrateOrQualityLabel.Name = "bitrateOrQualityLabel";
357 | this.bitrateOrQualityLabel.Size = new System.Drawing.Size(29, 12);
358 | this.bitrateOrQualityLabel.TabIndex = 9;
359 | this.bitrateOrQualityLabel.Text = "质量";
360 | //
361 | // codecModeCB
362 | //
363 | this.codecModeCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
364 | this.codecModeCB.FormattingEnabled = true;
365 | this.codecModeCB.Location = new System.Drawing.Point(75, 52);
366 | this.codecModeCB.Name = "codecModeCB";
367 | this.codecModeCB.Size = new System.Drawing.Size(121, 20);
368 | this.codecModeCB.TabIndex = 8;
369 | this.codecModeCB.SelectedIndexChanged += new System.EventHandler(this.codecModeCB_SelectedIndexChanged);
370 | //
371 | // codecModeLabel
372 | //
373 | this.codecModeLabel.AutoSize = true;
374 | this.codecModeLabel.Location = new System.Drawing.Point(5, 55);
375 | this.codecModeLabel.Name = "codecModeLabel";
376 | this.codecModeLabel.Size = new System.Drawing.Size(53, 12);
377 | this.codecModeLabel.TabIndex = 7;
378 | this.codecModeLabel.Text = "编码模式";
379 | //
380 | // audioEncoderCB
381 | //
382 | this.audioEncoderCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
383 | this.audioEncoderCB.FormattingEnabled = true;
384 | this.audioEncoderCB.Items.AddRange(new object[] {
385 | "复制音频流",
386 | "无音频流",
387 | "qaac"});
388 | this.audioEncoderCB.Location = new System.Drawing.Point(75, 24);
389 | this.audioEncoderCB.Name = "audioEncoderCB";
390 | this.audioEncoderCB.Size = new System.Drawing.Size(151, 20);
391 | this.audioEncoderCB.TabIndex = 6;
392 | this.audioEncoderCB.SelectedIndexChanged += new System.EventHandler(this.audioEncoderCB_SelectedIndexChanged);
393 | //
394 | // audioEncoder
395 | //
396 | this.audioEncoder.AutoSize = true;
397 | this.audioEncoder.Location = new System.Drawing.Point(6, 27);
398 | this.audioEncoder.Name = "audioEncoder";
399 | this.audioEncoder.Size = new System.Drawing.Size(53, 12);
400 | this.audioEncoder.TabIndex = 5;
401 | this.audioEncoder.Text = "编码程序";
402 | //
403 | // label3
404 | //
405 | this.label3.AutoSize = true;
406 | this.label3.Location = new System.Drawing.Point(6, 55);
407 | this.label3.Name = "label3";
408 | this.label3.Size = new System.Drawing.Size(0, 12);
409 | this.label3.TabIndex = 3;
410 | //
411 | // MainForm
412 | //
413 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
414 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
415 | this.ClientSize = new System.Drawing.Size(482, 521);
416 | this.Controls.Add(this.audioSetgB);
417 | this.Controls.Add(this.removeSettingBtn);
418 | this.Controls.Add(this.chooseOutputPathBtn);
419 | this.Controls.Add(this.addSettingBtn);
420 | this.Controls.Add(this.outputFilePathTB);
421 | this.Controls.Add(this.encodeSettinglabel);
422 | this.Controls.Add(this.encodeSettingCB);
423 | this.Controls.Add(this.outputFilePathlabel);
424 | this.Controls.Add(this.fileListView);
425 | this.Controls.Add(this.StartBtn);
426 | this.Controls.Add(this.set2AllBtn);
427 | this.Controls.Add(this.set2SelectedBtn);
428 | this.Controls.Add(this.videoSetgB);
429 | this.Controls.Add(this.removeAllBtn);
430 | this.Controls.Add(this.removeFileBtn);
431 | this.Controls.Add(this.addFolderBtn);
432 | this.Controls.Add(this.addFileBtn);
433 | this.Name = "MainForm";
434 | this.Text = "Expert Video Toolbox";
435 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
436 | this.videoSetgB.ResumeLayout(false);
437 | this.videoSetgB.PerformLayout();
438 | this.audioSetgB.ResumeLayout(false);
439 | this.audioSetgB.PerformLayout();
440 | this.ResumeLayout(false);
441 | this.PerformLayout();
442 |
443 | }
444 |
445 | #endregion
446 |
447 | private System.Windows.Forms.Button removeAllBtn;
448 | private System.Windows.Forms.Button removeFileBtn;
449 | private System.Windows.Forms.Button addFolderBtn;
450 | private System.Windows.Forms.Button addFileBtn;
451 | private System.Windows.Forms.GroupBox videoSetgB;
452 | private System.Windows.Forms.ComboBox encoderCB;
453 | private System.Windows.Forms.Label encoderLabel;
454 | private System.Windows.Forms.Label brORqLabel;
455 | private System.Windows.Forms.ComboBox fileFormatCB;
456 | private System.Windows.Forms.Label fileFormatLabel;
457 | private System.Windows.Forms.ComboBox encodeSettingCB;
458 | private System.Windows.Forms.TextBox cmdCodeTB;
459 | private System.Windows.Forms.Button removeSettingBtn;
460 | private System.Windows.Forms.Button addSettingBtn;
461 | private System.Windows.Forms.Label encodeSettinglabel;
462 | private System.Windows.Forms.Button set2SelectedBtn;
463 | private System.Windows.Forms.Button set2AllBtn;
464 | private System.Windows.Forms.Button StartBtn;
465 | private System.Windows.Forms.ListView fileListView;
466 | private System.Windows.Forms.Label outputFilePathlabel;
467 | private System.Windows.Forms.TextBox outputFilePathTB;
468 | private System.Windows.Forms.Button chooseOutputPathBtn;
469 | private System.Windows.Forms.GroupBox audioSetgB;
470 | private System.Windows.Forms.ComboBox profileCB;
471 | private System.Windows.Forms.Label profileLabel;
472 | private System.Windows.Forms.ComboBox bitrateOrQualityCB;
473 | private System.Windows.Forms.Label bitrateOrQualityLabel;
474 | private System.Windows.Forms.ComboBox codecModeCB;
475 | private System.Windows.Forms.Label codecModeLabel;
476 | private System.Windows.Forms.ComboBox audioEncoderCB;
477 | private System.Windows.Forms.Label audioEncoder;
478 | private System.Windows.Forms.Label label3;
479 | }
480 | }
481 |
482 |
--------------------------------------------------------------------------------
/ExpertVideoToolbox/MainForm.cs:
--------------------------------------------------------------------------------
1 | using ExpertVideoToolbox.cmdCodeGenerator;
2 | using ExpertVideoToolbox.taskManager;
3 | using ExpertVideoToolbox.TaskManager;
4 | using Newtonsoft.Json;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.ComponentModel;
8 | using System.Data;
9 | using System.Diagnostics;
10 | using System.Drawing;
11 | using System.IO;
12 | using System.Linq;
13 | using System.Text;
14 | using System.Threading.Tasks;
15 | using System.Windows.Forms;
16 |
17 | namespace ExpertVideoToolbox
18 | {
19 | public partial class MainForm : Form
20 | {
21 | taskSetting[] settings;
22 | Job j;
23 |
24 | public MainForm()
25 | {
26 | InitializeComponent();
27 |
28 | CheckForIllegalCrossThreadCalls = false;
29 |
30 | string fileNameColumnText = "文件名";
31 | string settingColumnText = "编码预设";
32 |
33 | this.fileListView.View = View.Details;
34 |
35 | int settingColumnWidth = 100;
36 | int reservedWidth = 5;
37 |
38 | // 显示的文件名列,优化了省略号的位置
39 | ColumnHeader visualFileNameCH = new ColumnHeader();
40 | visualFileNameCH.Text = fileNameColumnText;
41 | visualFileNameCH.Width = this.fileListView.Width - settingColumnWidth - reservedWidth;
42 |
43 | ColumnHeader settingCH = new ColumnHeader();
44 | settingCH.Text = settingColumnText;
45 | settingCH.Width = settingColumnWidth;
46 |
47 | // 真实文件名列,不显示在UI上,宽度为0
48 | ColumnHeader realFileNameCH = new ColumnHeader();
49 | realFileNameCH.Text = "";
50 | realFileNameCH.Width = 0;
51 |
52 | this.fileListView.Columns.Add(visualFileNameCH);
53 | this.fileListView.Columns.Add(settingCH);
54 | this.fileListView.Columns.Add(realFileNameCH);
55 |
56 | //this.outputFilePathTB.Text = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\trans";
57 |
58 | // 从文件中读取已存储的预设
59 | int i = readAllSettingsFromFiles();
60 |
61 | // 将读到的预设加载到combobox中
62 | for (int j = 0; j < i; j++)
63 | {
64 | this.encodeSettingCB.Items.Add(settings[j].name);
65 | }
66 |
67 | this.encodeSettingCB.SelectedIndex = 0;
68 |
69 | //ListViewItem gg = new ListViewItem(new string[] { "test01", "test" }); //这是至关重要的一点。
70 | //this.fileListView.Items.Add(gg);
71 | }
72 |
73 | // !!点击开始转换
74 | private void StartBtn_Click(object sender, EventArgs e)
75 | {
76 | if (this.fileListView.Items.Count == 0)
77 | {
78 | string noFileMsg = "未添加任何文件";
79 | MessageBox.Show(noFileMsg);
80 | }
81 | else
82 | {
83 | if (checkSettingChange() == -1)
84 | {
85 | MessageBox.Show("一个或多个任务的预设已被删除,请重新添加预设!");
86 | return;
87 | }
88 |
89 | if (checkSettingChange() == 1) // 1为真,表示有变化
90 | {
91 | string note = "检测到预设已修改,是否覆盖当前选中的预设?\n点击“确定”将覆盖并应用该预设到全部任务。点击“取消”将中止任务且不做改动。";
92 | DialogResult dr = MessageBox.Show(note, "检测到预设修改", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
93 | if (dr == DialogResult.OK)
94 | {
95 | //点确定的代码
96 | saveSetting2File(this.encodeSettingCB.Text);
97 | readAllSettingsFromFiles();
98 |
99 | for (int i = 0; i < this.fileListView.Items.Count; i++)
100 | {
101 | fileListView.Items[i].SubItems[1].Text = this.encodeSettingCB.Text;
102 | }
103 | }
104 | else
105 | {
106 | //点取消的代码
107 | return;
108 | }
109 | }
110 |
111 | int count = fileListView.Items.Count;
112 | filePathStorage q = new filePathStorage(count);
113 | for (int i = 0; i < count; i++)
114 | {
115 | if (!CheckSettingExist(fileListView.Items[i].SubItems[1].Text))
116 | {
117 | MessageBox.Show("一个或多个任务的预设已被删除,请检查编码设置!");
118 | return;
119 | }
120 |
121 | // subitems[2]中保存着完整文件名
122 | videoTask t = new videoTask(fileListView.Items[i].SubItems[2].Text, fileListView.Items[i].SubItems[1].Text);
123 | q.add(t);
124 | }
125 |
126 | this.j = new Job(q);
127 | //this.j.ErrorEvent += DisposeJob;
128 | this.j.runJob(this.outputFilePathTB.Text);
129 | }
130 | }
131 |
132 | private void fileListView_DragDrop(object sender, DragEventArgs e)
133 | {
134 | Array files = ((System.Array)e.Data.GetData(DataFormats.FileDrop));
135 | int count = files.Length;
136 | for (int i = 0; i < count; i++)
137 | {
138 | string fp = files.GetValue(i).ToString();
139 | string setting = this.encodeSettingCB.Text;
140 |
141 | addItem2FileListView(fp, setting);
142 | }
143 | }
144 |
145 | // 必须添加这一事件才可以拖动进来
146 | private void fileListView_DragEnter(object sender, DragEventArgs e)
147 | {
148 | e.Effect = DragDropEffects.Copy;
149 | }
150 |
151 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
152 | {
153 | Application.Exit();
154 | Process p = Process.GetCurrentProcess();
155 | p.Kill();
156 | }
157 |
158 | private void addFileBtn_Click(object sender, EventArgs e)
159 | {
160 | Stream myStream = null;
161 | OpenFileDialog openFileDialog1 = new OpenFileDialog();
162 |
163 | openFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // 默认打开显示我的文档
164 | openFileDialog1.Filter = "mp4视频文件 (*.mp4)|*.mp4|All files (*.*)|*.*";
165 | openFileDialog1.FilterIndex = 2;
166 | openFileDialog1.RestoreDirectory = false;
167 |
168 | if (openFileDialog1.ShowDialog() == DialogResult.OK)
169 | {
170 | try
171 | {
172 | if ((myStream = openFileDialog1.OpenFile()) != null)
173 | {
174 | using (myStream)
175 | {
176 | // Insert code to read the stream here.
177 | string fp = openFileDialog1.FileName;
178 | string setting = this.encodeSettingCB.Text;
179 | addItem2FileListView(fp, setting);
180 | }
181 | }
182 | }
183 | catch (Exception ex)
184 | {
185 | MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
186 | }
187 | }
188 | }
189 |
190 | private void addFolderBtn_Click(object sender, EventArgs e)
191 | {
192 | FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
193 | if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
194 | {
195 | string folderPath = folderBrowserDialog1.SelectedPath;
196 |
197 | string[] files = System.IO.Directory.GetFiles(folderPath);
198 | int filesCount = files.Length;
199 | int videoFilesCount = 0;
200 | for (int i = 0; i < filesCount; i++)
201 | {
202 | string fp = files[i];
203 | string[] s = fp.Split(new char[] { '.' });
204 | string ext = s[s.Length - 1];
205 | if (videoFileCheckByExtension(ext))
206 | {
207 | videoFilesCount++;
208 |
209 | string setting = this.encodeSettingCB.Text;
210 |
211 | addItem2FileListView(fp, setting);
212 | }
213 |
214 | }
215 | string msg = "目录搜索完成,找到" + videoFilesCount.ToString() + "个支持的文件";
216 | MessageBox.Show(msg);
217 | }
218 | }
219 |
220 | private bool videoFileCheckByExtension(string extension)
221 | {
222 | string[] videoExt = { "mp4", "wmv", "avi", "mkv", "rm", "rmvb", "vob", "dat", "asf", "mpg", "ts", "mpeg", "mpe", "mov", "flv", "f4v", "3gp" };
223 | return this.multiStringEqualCheck(videoExt, extension);
224 | }
225 |
226 | private bool multiStringEqualCheck(string[] targets, string source)
227 | {
228 | int len = targets.Length;
229 | for (int i = 0; i < len; i++)
230 | {
231 | if (string.Equals(targets[i], source))
232 | {
233 | return true;
234 | }
235 | }
236 | return false;
237 | }
238 |
239 | private void removeFileBtn_Click(object sender, EventArgs e)
240 | {
241 | ListView.SelectedIndexCollection indexesREADONLY = fileListView.SelectedIndices;
242 |
243 | int count = indexesREADONLY.Count;
244 | int[] indexes = new int[count];
245 | for (int i = 0; i < count; i++)
246 | {
247 | indexes[i] = indexesREADONLY[i];
248 | }
249 |
250 | if (count == 0)
251 | {
252 | MessageBox.Show("未选择任何任务!");
253 | return;
254 | }
255 | for (int i = 0; i < count; )
256 | {
257 | int removeIndex = indexes[i++];
258 | fileListView.Items.RemoveAt(removeIndex);
259 |
260 | // 此时i是刚刚处理的indexes数组元素索引值 +1 ,遍历还未处理的indexes数组
261 | for (int j = i; j < count; j++)
262 | {
263 | // 如果此索引值大于刚刚删除的item的索引值,说明该位置的元素要前移一位
264 | // 如果不大于就不用管,对其位置没有影响
265 | if (indexes[j] > removeIndex)
266 | {
267 | indexes[j]--;
268 | }
269 | }
270 | }
271 | }
272 |
273 | // 编码预设改变时更新所有信息
274 | private void encodeSettingCB_SelectedIndexChanged(object sender, EventArgs e)
275 | {
276 | foreach (taskSetting ts in settings)
277 | {
278 | if (ts != null && String.Equals(this.encodeSettingCB.Text, ts.name))
279 | {
280 | // Items集合中有此项值才能通过这种方法添加(DropList模式)
281 | this.encoderCB.Text = ts.encoder;
282 | this.audioEncoderCB.Text = ts.audioEncoder;
283 | this.fileFormatCB.Text = ts.outputFormat;
284 | this.cmdCodeTB.Text = ts.encoderSetting;
285 |
286 | this.profileCB.Text = ts.audioProfile;
287 | this.codecModeCB.Text = ts.audioCodecMode;
288 | if (String.Equals(this.bitrateOrQualityLabel, "质量"))
289 | {
290 | this.bitrateOrQualityCB.Text = ts.audioQuality;
291 | }
292 | else
293 | {
294 | this.bitrateOrQualityCB.Text = ts.audioKbps;
295 | }
296 |
297 | break;
298 | }
299 | }
300 | }
301 |
302 | // 点击添加预设按钮
303 | private void addSettingBtn_Click(object sender, EventArgs e)
304 | {
305 | for (int i = 0; i < this.encodeSettingCB.Items.Count; i++)
306 | {
307 | // 如果要添加的预设名称和已有的任意一个相同
308 | if (String.Equals(this.encodeSettingCB.Text, this.encodeSettingCB.Items[i].ToString()))
309 | {
310 | DialogResult dr = MessageBox.Show("确定要覆盖预设" + this.encodeSettingCB.Text + "吗?", "确认覆盖", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
311 | if (dr == DialogResult.OK)
312 | {
313 | //点确定的代码
314 | saveSetting2File(this.encodeSettingCB.Text);
315 | readAllSettingsFromFiles();
316 | return;
317 | }
318 | else
319 | {
320 | //点取消的代码
321 | return;
322 | }
323 | }
324 | }
325 |
326 | // 如果没有重复不仅要存储预设,还要更新UI
327 | saveSetting2File(this.encodeSettingCB.Text);
328 | this.encodeSettingCB.Items.Add(this.encodeSettingCB.Text);
329 | readAllSettingsFromFiles();
330 | }
331 |
332 | private void saveSetting2File(string name)
333 | {
334 | taskSetting ts = new taskSetting(name, this.encoderCB.Text, this.fileFormatCB.Text, this.cmdCodeTB.Text,
335 | this.audioEncoderCB.Text, this.profileCB.Text, this.codecModeCB.Text, this.bitrateOrQualityCB.Text,
336 | this.bitrateOrQualityCB.Text);
337 | string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + name + ".json";
338 | File.WriteAllText(fp, JsonConvert.SerializeObject(ts));
339 | }
340 |
341 | private int readAllSettingsFromFiles()
342 | {
343 | DirectoryInfo folder = new DirectoryInfo(System.Windows.Forms.Application.StartupPath + "\\taskSettings");
344 | FileInfo[] fis = folder.GetFiles();
345 |
346 | settings = new taskSetting[fis.Length];
347 | int i = 0;
348 | foreach (FileInfo fi in fis)
349 | {
350 | if (String.Equals(fi.Extension, ".json")) // 文件的扩展名要包括.(点)
351 | {
352 | settings[i++] = JsonConvert.DeserializeObject(File.ReadAllText(fi.FullName));
353 | }
354 | }
355 | return i;
356 | }
357 |
358 | // 音频编码器选项变化时
359 | private void audioEncoderCB_SelectedIndexChanged(object sender, EventArgs e)
360 | {
361 | if (this.audioEncoderCB.SelectedIndex == 0 || this.audioEncoderCB.SelectedIndex == 1)
362 | {
363 | this.profileCB.Enabled = false;
364 | this.codecModeCB.Enabled = false;
365 | this.bitrateOrQualityCB.Enabled = false;
366 | }
367 | else
368 | {
369 | this.profileCB.Enabled = true;
370 | this.addProfileItems();
371 | this.codecModeCB.Enabled = true;
372 | this.bitrateOrQualityCB.Enabled = true;
373 | }
374 | }
375 |
376 | // 点击移除预设按钮
377 | private void removeSettingBtn_Click(object sender, EventArgs e)
378 | {
379 | // 需要做的事:
380 | // 1.删除保存的json文件(必须先删除,不然文件名就会错误)
381 | // 2.从combobox中删除,并显示另一个预设的参数
382 | // 不需要从setting数组中删除对应的元素,因为不可能选到被删除的预设了,如果再次添加同名的预设,会重新读取到setting数组(详见添加预设按钮的代码)
383 | DialogResult dr = MessageBox.Show("确定要删除预设" + this.encodeSettingCB.Text + "吗?", "确认删除", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
384 | if (dr == DialogResult.OK)
385 | {
386 | //点确定的代码
387 | string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + this.encodeSettingCB.Text + ".json";
388 | File.Delete(fp);
389 | this.encodeSettingCB.Items.Remove(this.encodeSettingCB.Text);
390 | this.encodeSettingCB.SelectedIndex = 0;
391 | }
392 | else
393 | {
394 | //点取消的代码
395 | }
396 | }
397 |
398 | // 点击移除所有按钮
399 | private void removeAllBtn_Click(object sender, EventArgs e)
400 | {
401 | fileListView.Items.Clear();
402 | }
403 |
404 | // 选择输出文件夹
405 | private void chooseOutputPathBtn_Click(object sender, EventArgs e)
406 | {
407 | FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
408 | if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
409 | {
410 | string folderPath = folderBrowserDialog1.SelectedPath;
411 | this.outputFilePathTB.Text = folderPath;
412 | }
413 | }
414 |
415 | // 点击应用到选中
416 | private void set2SelectedBtn_Click(object sender, EventArgs e)
417 | {
418 | ListView.SelectedIndexCollection indexes = fileListView.SelectedIndices;
419 | int count = indexes.Count;
420 | if (count == 0)
421 | {
422 | MessageBox.Show("未选择任何任务!");
423 | return;
424 | }
425 | for (int i = 0; i < count; i++)
426 | {
427 | fileListView.Items[indexes[i]].SubItems[1].Text = this.encodeSettingCB.Text;
428 | }
429 | }
430 |
431 | // 点击全部应用
432 | private void set2AllBtn_Click(object sender, EventArgs e)
433 | {
434 | for (int i = 0; i < this.fileListView.Items.Count; i++)
435 | {
436 | fileListView.Items[i].SubItems[1].Text = this.encodeSettingCB.Text;
437 | }
438 | }
439 |
440 | // 检查预设与UI显示的有无不同, 结果1和0分别表示真和假,-1表示预设不存在
441 | private int checkSettingChange()
442 | {
443 | string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + this.encodeSettingCB.Text + ".json";
444 | try
445 | {
446 | taskSetting ts = JsonConvert.DeserializeObject(File.ReadAllText(fp));
447 | if (String.Equals(this.encoderCB.Text, ts.encoder)
448 | && String.Equals(this.fileFormatCB.Text, ts.outputFormat)
449 | && String.Equals(this.cmdCodeTB.Text, ts.encoderSetting)
450 | && String.Equals(this.audioEncoderCB.Text, ts.audioEncoder)
451 | && (String.Equals(this.profileCB.Text, ts.audioProfile) || this.profileCB.Enabled == false)
452 | && (String.Equals(this.codecModeCB.Text, ts.audioCodecMode) || this.codecModeCB.Enabled == false)
453 | && (String.Equals(this.bitrateOrQualityCB.Text, ts.audioQuality) || this.bitrateOrQualityCB.Enabled == false))
454 | {
455 | return 0; // false表示没有变化
456 | }
457 | return 1;
458 | }
459 | catch (System.IO.IOException)
460 | {
461 | return -1;
462 | }
463 | }
464 |
465 | // 检查预设是否存在
466 | private bool CheckSettingExist(string s)
467 | {
468 | string fp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + s + ".json";
469 | return File.Exists(fp);
470 | }
471 |
472 | private void DisposeJob()
473 | {
474 | this.j = null;
475 | GC.Collect();
476 | }
477 |
478 | private void profileCB_SelectedIndexChanged(object sender, EventArgs e)
479 | {
480 | ComboBox comboBox = (ComboBox)sender;
481 | if (string.Equals(comboBox.Text, "HE-AAC"))
482 | {
483 | //this.bitrateOrQualityCB.Enabled = true;
484 | //this.codecModeCB.Enabled = true;
485 | this.addCodecModeItems();
486 | this.codecModeCB.SelectedIndex = 0;
487 | this.brORqLabel.Text = "码率";
488 | this.addBitrateItems();
489 | this.bitrateOrQualityCB.Text = "48"; // 设置默认值
490 | }
491 | else if (string.Equals(comboBox.Text, "LC-AAC"))
492 | {
493 | //this.bitrateOrQualityCB.Enabled = true;
494 | //this.codecModeCB.Enabled = true;
495 | this.addCodecModeItems();
496 | this.codecModeCB.SelectedIndex = 3;
497 | this.brORqLabel.Text = "质量";
498 | this.addQualityItems();
499 | this.bitrateOrQualityCB.Text = "91"; // 设置默认值
500 | } else
501 | {
502 | this.bitrateOrQualityCB.Enabled = false;
503 | this.codecModeCB.Enabled = false;
504 | }
505 | }
506 |
507 | private void addQualityItems()
508 | {
509 | this.bitrateOrQualityCB.Items.Clear();
510 | this.bitrateOrQualityCB.Items.Add("0");
511 | this.bitrateOrQualityCB.Items.Add("9");
512 | this.bitrateOrQualityCB.Items.Add("18");
513 | this.bitrateOrQualityCB.Items.Add("27");
514 | this.bitrateOrQualityCB.Items.Add("36");
515 | this.bitrateOrQualityCB.Items.Add("45");
516 | this.bitrateOrQualityCB.Items.Add("54");
517 | this.bitrateOrQualityCB.Items.Add("63");
518 | this.bitrateOrQualityCB.Items.Add("73");
519 | this.bitrateOrQualityCB.Items.Add("82");
520 | this.bitrateOrQualityCB.Items.Add("91");
521 | this.bitrateOrQualityCB.Items.Add("100");
522 | this.bitrateOrQualityCB.Items.Add("109");
523 | this.bitrateOrQualityCB.Items.Add("118");
524 | this.bitrateOrQualityCB.Items.Add("127");
525 | }
526 |
527 | private void addBitrateItems()
528 | {
529 | this.bitrateOrQualityCB.Items.Clear();
530 | this.bitrateOrQualityCB.Items.Add("32");
531 | this.bitrateOrQualityCB.Items.Add("64");
532 | this.bitrateOrQualityCB.Items.Add("96");
533 | this.bitrateOrQualityCB.Items.Add("128");
534 | this.bitrateOrQualityCB.Items.Add("192");
535 | this.bitrateOrQualityCB.Items.Add("256");
536 | this.bitrateOrQualityCB.Items.Add("320");
537 | }
538 |
539 | private void addCodecModeItems()
540 | {
541 | this.codecModeCB.Items.Clear();
542 | this.codecModeCB.Items.Add("CBR");
543 | this.codecModeCB.Items.Add("ABR");
544 | this.codecModeCB.Items.Add("CVBR");
545 | if (this.profileCB.SelectedIndex == 0)
546 | {
547 | this.codecModeCB.Items.Add("TVBR");
548 | }
549 | }
550 |
551 | private void addProfileItems()
552 | {
553 | if (this.audioEncoderCB.SelectedIndex == 2)
554 | {
555 | this.profileCB.Items.Clear();
556 | this.profileCB.Items.Add("LC-AAC");
557 | this.profileCB.Items.Add("HE-AAC");
558 | this.profileCB.Items.Add("ALAC");
559 | this.profileCB.SelectedIndex = 0;
560 | }
561 | }
562 |
563 | private void codecModeCB_SelectedIndexChanged(object sender, EventArgs e)
564 | {
565 | ComboBox comboBox = (ComboBox)sender;
566 | if (string.Equals(comboBox.Text, "TVBR"))
567 | {
568 | this.brORqLabel.Text = "质量";
569 | this.addQualityItems();
570 | this.bitrateOrQualityCB.Text = "91"; // 设置默认值
571 | }
572 | else
573 | {
574 | if (string.Equals(this.brORqLabel.Text, "质量"))
575 | {
576 | this.brORqLabel.Text = "码率";
577 | this.addBitrateItems();
578 |
579 | this.bitrateOrQualityCB.Text = "256"; // 设置默认值
580 | }
581 | }
582 | }
583 |
584 | // 将文件名和预设数据添加到UI,并优化显示模式
585 | private void addItem2FileListView(string fp, string setting)
586 | {
587 | // 生成显示在UI上的字符串
588 | string dot = ".";
589 |
590 | var fpFullWidth = this.CreateGraphics().MeasureString(fp, this.fileListView.Font).Width; // 获取文本的显示宽度
591 | var dotWidth = this.CreateGraphics().MeasureString(dot, this.fileListView.Font).Width;
592 |
593 | var columnWidth = this.fileListView.Columns[0].Width - (int)dotWidth;
594 |
595 | string visualfp = "";
596 | if (fpFullWidth <= columnWidth) // 文本不大于列宽度,则全部显示,不做处理
597 | {
598 | visualfp = fp;
599 | }
600 | else
601 | {
602 | int length = fp.Length; // 文字字符长度
603 | double averageWidth = fpFullWidth / length; // 平均每个字符的显示宽度
604 |
605 | double frontRatio = 0.2; // 文本前部占有效信息的比例,0.5表示前后各一半
606 | int dotCount = 6;
607 | double frontTextWidth = (columnWidth - dotWidth * dotCount) * frontRatio;
608 | int frontTextLength = (int)Math.Round(frontTextWidth / averageWidth);
609 | frontTextLength = frontTextLength >= 3 ? frontTextLength : 3; // 文本前部长度最小为3,至少要能显示盘符
610 | int rearTextLength = (int)Math.Round(frontTextLength * (1 - frontRatio) / frontRatio);
611 |
612 | int rearStartIndex = length - rearTextLength;
613 | visualfp = fp.Substring(0, frontTextLength) + ("").PadLeft(dotCount, '0').Replace("0", dot) + fp.Substring(rearStartIndex, rearTextLength);
614 |
615 | // 以上为初步生成,如果不符合要求,则继续修剪
616 | var tempWidth = this.CreateGraphics().MeasureString(visualfp, this.fileListView.Font).Width;
617 | bool trimTooMuch = false;
618 |
619 | // 两种情况下要修剪,1.超出宽度 2.宽度少一个点以上
620 | while( tempWidth > columnWidth || (trimTooMuch = (columnWidth - tempWidth > dotWidth)) )
621 | {
622 | if (trimTooMuch == false) // 第一种情况
623 | {
624 | if (frontTextLength <= 3) // 文本前部即将小于最小宽度,只能修建文本后部
625 | {
626 | // 已知问题:遇到超长字符串时,修剪完前部文本再修剪后部文本时,函数直接从这里跳出,没有异常,界面上也显示不了这个文件。
627 | // 准备先加异常处理看看。20180531 1320
628 | try
629 | {
630 | visualfp = fp.Substring(0, frontTextLength) + ("").PadLeft(dotCount, '0').Replace("0", dot) + fp.Substring(++rearStartIndex, rearTextLength);
631 | }
632 | catch (Exception e)
633 | {
634 | //MessageBox.Show(e.ToString());
635 | break;
636 | }
637 |
638 | }
639 | else // 否则修剪文本前部
640 | {
641 | visualfp = fp.Substring(0, --frontTextLength) + ("").PadLeft(dotCount, '0').Replace("0", dot) + fp.Substring(rearStartIndex, rearTextLength);
642 | }
643 | }
644 | else // 第二种情况,直接前移文本后部的起始索引
645 | {
646 | visualfp = fp.Substring(0, frontTextLength) + ("").PadLeft(dotCount, '0').Replace("0", dot) + fp.Substring(--rearStartIndex, ++rearTextLength);
647 | trimTooMuch = false; // 重置判断状态
648 | }
649 | tempWidth = this.CreateGraphics().MeasureString(visualfp, this.fileListView.Font).Width;
650 | }
651 | }
652 | ListViewItem item = new ListViewItem(new string[] { visualfp, setting, fp });
653 | this.fileListView.Items.Add(item);
654 | }
655 | }
656 | }
--------------------------------------------------------------------------------
/ExpertVideoToolbox/TaskManager/Job.cs:
--------------------------------------------------------------------------------
1 | using MediaInfoLib;
2 | using ExpertVideoToolbox.cmdCodeGenerator;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 | using System.Windows.Forms;
12 | using ExpertVideoToolbox.TaskManager;
13 | using Newtonsoft.Json;
14 |
15 | namespace ExpertVideoToolbox.taskManager
16 | {
17 | class Job
18 | {
19 | public delegate void ErrorHandler(); //声明委托
20 | public event ErrorHandler ErrorEvent; //声明事件
21 |
22 | delegate void InnerMethodDelagate();
23 |
24 | const int AUDIOENCODE = 0;
25 | const int VIDEOENCODE = 1;
26 | const int MUXER = 2;
27 | const int AUDIOCOPY = 3;
28 | const int DELETEVIDEOTEMP = 4;
29 | const int DELETEAUDIOTEMP = 5;
30 |
31 | const int ONLYVIDEO = 0;
32 | const int SUPPRESSAUDIO = 1;
33 | const int COPYAUDIO = 2;
34 |
35 | const int NORMAL = 0;
36 | const int AVS = 1;
37 | const int VPY = 2;
38 |
39 | long outPutCmdCount = 0;
40 | long outPutCmdCheckCount = 0;
41 |
42 | private runningPool rp;
43 | public videoTask[] tasks;
44 | public int num;
45 | public int finishedNum;
46 | public int threadsNum;
47 | private bool[] isfinished;
48 | private string outputFolderPath;
49 | private int videoType;
50 |
51 | private RunningStatusForm rsForm;
52 |
53 | private int[] PIDs;
54 | private int subTaskPID;
55 |
56 | private int startTime = 0;
57 | private int endTime;
58 |
59 | private int checkPattern;
60 | private int[] checkTime;
61 | private int[] checkFrame;
62 | private double[] fps;
63 |
64 | private bool audioProcessing;
65 | private bool encoding;
66 | private bool postProcessing;
67 | private bool muxing;
68 | private bool isfailed;
69 |
70 | private StringBuilder log;
71 | private string miniLog;
72 | private int reportCount;
73 |
74 | private Thread ctrlThread;
75 | Thread[] threads;
76 |
77 | //private Process process = null;
78 |
79 | public Job(filePathStorage tempQueue)
80 | {
81 | // 从storage读取num
82 | this.num = tempQueue.Count();
83 | this.threadsNum = 1;
84 |
85 | this.finishedNum = 0;
86 |
87 | encoding = false;
88 | audioProcessing = false;
89 | muxing = false;
90 |
91 | // 初始化task数组来feed下面的queue
92 | this.tasks = new videoTask[num];
93 | this.PIDs = new int[threadsNum];
94 | this.subTaskPID = Int32.MaxValue;
95 | this.isfinished = new bool[threadsNum];
96 |
97 | reportCount = 0;
98 | checkPattern = 80;
99 | int cpx2 = checkPattern + checkPattern;
100 | checkTime = new int[cpx2];
101 | checkFrame = new int[cpx2];
102 | this.fps = new double[cpx2];
103 | for (int i = 0; i < cpx2; i++)
104 | {
105 | this.fps[i] = 0;
106 | }
107 |
108 | for (int i = 0; i < num; i++ )
109 | {
110 | this.tasks[i] = tempQueue.get(i);
111 | }
112 |
113 | // 初始化运行池pool
114 | this.rp = new runningPool(this.num, this.tasks); // 运行池持有队列,需传递队列的相关参数
115 |
116 | // 初始化运行状态窗口
117 | this.rsForm = new RunningStatusForm();
118 |
119 | log = new StringBuilder("");
120 | this.rsForm.AbortEvent += saveLog2File;
121 | this.rsForm.ClosingEvent += AllThreadKill;
122 |
123 | }
124 |
125 | public void runJob(string ofp)
126 | {
127 | this.rsForm.Show();
128 | this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
129 |
130 | this.outputFolderPath = ofp;
131 |
132 | this.threads = new Thread[this.threadsNum];
133 | for (int i = 0; i < threadsNum; i++)
134 | {
135 | int p = i;
136 | Thread th = new Thread(()=>
137 | {
138 | this.isfinished[p] = false;
139 | this.threadRun(p);
140 | });
141 | threads[p] = th;
142 | }
143 | for (int i = 0; i < threadsNum; i++)
144 | {
145 | threads[i].Start();
146 | }
147 |
148 | }
149 |
150 | public int getPID()
151 | {
152 | return this.PIDs[0];
153 | }
154 |
155 | private void threadRun(int threadIndex)
156 | {
157 | videoTask t = rp.getTask();
158 | videoTask next;
159 |
160 | for (int i = 0; i < this.num; i++)
161 | {
162 | this.isfailed = false; // 将任务失败状态设为否
163 | if (i != 0)
164 | {
165 | rp.removeTask(t, false); // false表示成功完成编码没有失败
166 | }
167 |
168 | this.runTask(t, this.rsForm.process);
169 |
170 | next = rp.getTask(); // get之后任务已从运行池的等待队列中pop出了,无需再次get
171 | //MessageBox.Show(next.printTask());
172 | if (next == null)
173 | {
174 | rp.removeTask(t, false);
175 | break;
176 | }
177 | t = next;
178 | }
179 | }
180 |
181 | private void runTask(videoTask t, Process process)
182 | {
183 | this.rsForm.setPercent("0.0");
184 | this.rsForm.setTime("");
185 | this.rsForm.setFps("");
186 | this.rsForm.setEta("");
187 |
188 | string fp = t.getFP();
189 |
190 | process = new System.Diagnostics.Process();
191 |
192 | process.StartInfo.FileName = "cmd";
193 |
194 | // 必须禁用操作系统外壳程序
195 | process.StartInfo.UseShellExecute = false;
196 | process.StartInfo.CreateNoWindow = true;
197 | process.StartInfo.RedirectStandardError = true;
198 | process.StartInfo.RedirectStandardOutput = true;
199 | process.StartInfo.RedirectStandardInput = true;
200 |
201 | process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
202 | process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
203 |
204 | process.Start();
205 |
206 | this.PIDs[0] = process.Id;
207 | this.rsForm.PID = process.Id;
208 | this.rsForm.setStopBtnState(true);
209 |
210 | // 找到预设存储的文件并提取到taskSetting中
211 | string tsfp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + t.getSetting() + ".json";
212 | taskSetting ts = JsonConvert.DeserializeObject(File.ReadAllText(tsfp));
213 |
214 | // 将encoder信息传给信息显示界面
215 | this.rsForm.encodingProgram = ts.encoder;
216 | this.rsForm.HideVideoEncoderSetting();
217 |
218 | cmdCode c = new cmdCode(fp, ts, this.outputFolderPath);
219 | string cmd;
220 |
221 | int type = c.taskType();
222 | int checkNum = 0;
223 |
224 | int beforeProcessCheckTime = 3500;
225 | int processCheckInterval = 1000;
226 | const int checkF = 20;
227 |
228 | // 定义一个内部(匿名)方法
229 | // 整个视频转换过程结束时
230 | InnerMethodDelagate afterSuccess = delegate()
231 | {
232 | this.finishedNum++;
233 | this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
234 |
235 | try
236 | {
237 | process.CancelErrorRead();
238 | process.CancelOutputRead();
239 | }
240 | catch (Exception e)
241 | {
242 | //saveLog2File();
243 | }
244 |
245 | this.rsForm.setEta("");
246 | this.rsForm.setFps("");
247 | this.rsForm.setTime("");
248 | this.rsForm.setEstKbps("");
249 | this.rsForm.SetTaskStepsLabel(true);
250 |
251 | Process p = Process.GetProcessById(this.PIDs[0]);
252 | p.Kill();
253 | this.rsForm.setStopBtnState(false);
254 | this.rsForm.setPercent("-3");
255 | this.isfinished[0] = true;
256 | this.reportCount = 0;
257 | this.log.Clear();
258 |
259 | miniLog += t.getFP() + Environment.NewLine + Environment.NewLine + Environment.NewLine;
260 | saveMiniLog2File();
261 | };
262 |
263 | // 运行失败时调用
264 | InnerMethodDelagate afterFailed = delegate()
265 | {
266 | this.isfailed = true;
267 |
268 | saveLog2File();
269 |
270 | this.rsForm.setPercent("-1");
271 | this.rsForm.setTime("发生错误");
272 | this.rsForm.setFps("日志保存在程序目录");
273 |
274 | int sleepTime = 5; // 设置失败后继续下一个任务的时间
275 | this.rsForm.setEta(sleepTime.ToString() + "秒后继续运行");
276 |
277 | this.rsForm.setStatusBarLabelTextColorRED();
278 | this.finishedNum++;
279 | this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
280 | this.rsForm.HideVideoEncoderSetting();
281 |
282 | try
283 | {
284 | process.CancelErrorRead();
285 | process.CancelOutputRead();
286 | }
287 | catch (Exception e)
288 | {
289 | //saveLog2File();
290 | }
291 |
292 | Thread.Sleep(sleepTime * 1000);
293 |
294 | Process p = Process.GetProcessById(this.PIDs[0]);
295 | p.Kill();
296 | this.rsForm.setStopBtnState(false);
297 | this.rsForm.setPercent("-3");
298 | this.isfinished[0] = true;
299 | this.reportCount = 0;
300 | this.log.Clear();
301 | };
302 |
303 | // 视频编码前更新UI(显示视频总帧数)
304 | InnerMethodDelagate DispVideoFrames = delegate()
305 | {
306 | // MediaInfo读取视频帧数
307 | MediaInfo MI = new MediaInfo();
308 | string duration;
309 | string frameRate;
310 | string frames;
311 | MI.Open(t.getFP());
312 | duration = MI.Get(StreamKind.Video, 0, "Duration");
313 | try
314 | {
315 | double totalTime = Double.Parse(duration) / 1000.0;
316 | frameRate = MI.Get(StreamKind.Video, 0, "FrameRate");
317 | frames = ((int)(totalTime * Double.Parse(frameRate))).ToString();
318 |
319 | if (!String.IsNullOrWhiteSpace(frames))
320 | {
321 | this.rsForm.setTime("0/" + frames);
322 | }
323 | }
324 | catch (Exception e)
325 | {
326 | //saveLog2File();
327 | }
328 | };
329 |
330 | InnerMethodDelagate VideoEncode = delegate()
331 | {
332 | // 视频编码
333 | this.encoding = true;
334 | this.rsForm.setPercent("0.0");
335 |
336 | string ext = this.getFileExtName(t.getFP());
337 | if (String.Equals(ext, "avs", StringComparison.CurrentCultureIgnoreCase))
338 | {
339 | this.videoType = AVS;
340 | }
341 | else
342 | {
343 | this.videoType = NORMAL;
344 | DispVideoFrames();
345 | }
346 |
347 | cmd = c.cmdCodeGenerate(VIDEOENCODE, this.videoType);
348 | process.StandardInput.WriteLine(cmd);
349 |
350 | try
351 | {
352 | process.BeginErrorReadLine();
353 | process.BeginOutputReadLine();
354 | }
355 | catch (Exception e)
356 | {
357 | //saveLog2File();
358 | }
359 |
360 | checkNum = 0;
361 | this.reportCount = 0;
362 | int cpx2 = this.checkPattern + this.checkPattern;
363 | for (int i = 0; i < cpx2; i++)
364 | {
365 | checkFrame[i] = 0;
366 | }
367 | for (int i = 0; i < cpx2; i++)
368 | {
369 | this.fps[i] = 0;
370 | }
371 |
372 | Thread.Sleep(beforeProcessCheckTime);
373 |
374 | Process p;
375 | switch (videoType)
376 | {
377 | case NORMAL:
378 | p = GetSubTaskProcess(ts.encoder);
379 | if (p != null)
380 | {
381 | this.subTaskPID = p.Id;
382 | }
383 | else
384 | {
385 | this.subTaskPID = -1;
386 | }
387 | break;
388 | case AVS:
389 | Process avsP = GetSubTaskProcess("avs4x265.exe");
390 | int avsId = avsP.Id;
391 | if (avsP != null)
392 | {
393 | bool hasFound = false;
394 |
395 | // 等待视频编码进程启动,最长等待1小时
396 | for (int i = 0; i < 7200; i++)
397 | {
398 | // 确认avs进程仍在运行
399 | try
400 | {
401 | Process.GetProcessById(avsId);
402 | }
403 | catch (Exception e)
404 | {
405 | if (this.encoding == true || ConfirmFailed())
406 | {
407 | afterFailed();
408 | }
409 | return;
410 | }
411 |
412 | // 每隔500ms寻找视频编码进程
413 | p = GetSubTaskProcess(ts.encoder, avsId);
414 | if (p != null)
415 | {
416 | this.subTaskPID = p.Id;
417 | hasFound = true;
418 | break;
419 | }
420 | else
421 | {
422 | Thread.Sleep(500);
423 | }
424 | }
425 |
426 | if (!hasFound)
427 | {
428 | this.subTaskPID = -1;
429 | }
430 | }
431 | else
432 | {
433 | this.subTaskPID = -1;
434 | }
435 | break;
436 | default:
437 | break;
438 | }
439 |
440 | this.rsForm.ShowVideoEncoderSetting();
441 |
442 | while (this.encoding == true || this.postProcessing == true)
443 | {
444 | try
445 | {
446 | Process.GetProcessById(this.subTaskPID);
447 | }
448 | catch (Exception e)
449 | {
450 | if (this.encoding == true || ConfirmFailed())
451 | {
452 | afterFailed();
453 | }
454 | return;
455 | }
456 |
457 | Thread.Sleep(processCheckInterval);
458 | }
459 | try
460 | {
461 | process.CancelErrorRead();
462 | process.CancelOutputRead();
463 | }
464 | catch (Exception e)
465 | {
466 | //saveLog2File();
467 | }
468 |
469 | this.rsForm.HideVideoEncoderSetting();
470 | };
471 |
472 | InnerMethodDelagate Mux = delegate()
473 | {
474 | // muxer
475 | this.muxing = true;
476 | int stepIdx = type == ONLYVIDEO ? 2 : 3;
477 | this.rsForm.SetTaskStepsLabel(false, stepIdx, stepIdx, MUXER);
478 |
479 | cmd = c.cmdCodeGenerate(MUXER);
480 | process.StandardInput.WriteLine(cmd);
481 |
482 | try
483 | {
484 | process.BeginErrorReadLine();
485 | process.BeginOutputReadLine();
486 | }
487 | catch (Exception e)
488 | {
489 | //saveLog2File();
490 | }
491 |
492 | checkNum = 0;
493 |
494 | Thread.Sleep(beforeProcessCheckTime); // 有些超短的视频(1-2M),如果不加这句就会直接判定为任务已失败,疑似原因:没等判断完进程就已经结束
495 |
496 | string muxerProcessName = "";
497 | if (String.Equals("mp4", ts.outputFormat))
498 | {
499 | muxerProcessName = "mp4Box";
500 | }
501 | else if (String.Equals("mkv", ts.outputFormat))
502 | {
503 | muxerProcessName = "mkvmerge";
504 | }
505 |
506 | Process p = GetSubTaskProcess(muxerProcessName);
507 | if (p != null)
508 | {
509 | this.subTaskPID = p.Id;
510 | }
511 | else
512 | {
513 | this.subTaskPID = -1;
514 | }
515 |
516 | while (this.muxing == true)
517 | {
518 | try
519 | {
520 | Process.GetProcessById(this.subTaskPID);
521 | }
522 | catch (Exception e)
523 | {
524 | Thread.Sleep(1000);
525 | if (this.muxing == true)
526 | {
527 | afterFailed();
528 | }
529 | return;
530 | }
531 |
532 | Thread.Sleep(processCheckInterval);
533 | //checkNum = checkCmdRunning(checkNum, checkF);
534 | //if (checkNum == -1)
535 | //{
536 | // return;
537 | //}
538 | }
539 |
540 | afterSuccess();
541 |
542 | string tempVideoFp = c.cmdCodeGenerate(DELETEVIDEOTEMP);
543 | string tempAudioFp = c.cmdCodeGenerate(DELETEAUDIOTEMP);
544 | try
545 | {
546 | File.Delete(tempVideoFp);
547 | File.Delete(tempAudioFp);
548 | }
549 | catch (System.IO.IOException ex)
550 | {
551 | this.log.AppendLine("出现异常:" + ex);
552 | saveLog2File();
553 | }
554 | };
555 |
556 | // 音频编码或复制开始前更新UI(显示音频总时长)
557 | InnerMethodDelagate DispAudioDuration = delegate()
558 | {
559 | // MediaInfo读取音频时长
560 | MediaInfo MI = new MediaInfo();
561 | string duration;
562 | MI.Open(c.getAudioSource());
563 | duration = MI.Get(StreamKind.Audio, 0, 69);
564 |
565 | if (!String.IsNullOrWhiteSpace(duration))
566 | {
567 | this.rsForm.setTime("0/" + duration);
568 | }
569 |
570 | this.rsForm.setPercent("0.0", AUDIOENCODE);
571 | };
572 |
573 | InnerMethodDelagate ClearUIAfterAudioProcessing = delegate()
574 | {
575 | this.rsForm.setPercent("0.0");
576 | this.rsForm.setTime("");
577 | this.rsForm.setFps("");
578 | };
579 |
580 | switch (type)
581 | {
582 | case ONLYVIDEO:
583 |
584 | this.rsForm.SetTaskStepsLabel(false, 1, 2, VIDEOENCODE);
585 |
586 | VideoEncode();
587 |
588 | // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
589 | if (isfailed)
590 | {
591 | return;
592 | }
593 | //afterSuccess();
594 |
595 | Mux();
596 |
597 | break;
598 | case COPYAUDIO:
599 | // 复制音频
600 | cmd = c.cmdCodeGenerate(AUDIOCOPY);
601 | process.StandardInput.WriteLine(cmd);
602 | process.BeginErrorReadLine();
603 | process.BeginOutputReadLine();
604 | this.audioProcessing = true;
605 | this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOCOPY);
606 | DispAudioDuration();
607 |
608 | checkNum = 0;
609 |
610 | Thread.Sleep(beforeProcessCheckTime);
611 |
612 | Process p = GetSubTaskProcess("ffmpeg");
613 | if (p != null)
614 | {
615 | this.subTaskPID = p.Id;
616 | }
617 | else
618 | {
619 | this.subTaskPID = -1;
620 | }
621 |
622 | while (this.audioProcessing == true)
623 | {
624 | try
625 | {
626 | Process.GetProcessById(this.subTaskPID);
627 | }
628 | catch (Exception e)
629 | {
630 | Thread.Sleep(1000);
631 | if (this.audioProcessing == true)
632 | {
633 | afterFailed();
634 | }
635 | return;
636 | }
637 |
638 | Thread.Sleep(processCheckInterval);
639 | //checkNum = checkCmdRunning(checkNum, checkF);
640 | //if (checkNum == -1)
641 | //{
642 | // return;
643 | //}
644 | }
645 | ClearUIAfterAudioProcessing();
646 |
647 | process.CancelErrorRead();
648 | process.CancelOutputRead();
649 |
650 | this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);
651 |
652 | // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
653 | if (isfailed)
654 | {
655 | return;
656 | }
657 | VideoEncode();
658 |
659 | // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
660 | if (isfailed)
661 | {
662 | return;
663 | }
664 | Mux();
665 |
666 | break;
667 | case SUPPRESSAUDIO:
668 | // 音频编码
669 | cmd = c.cmdCodeGenerate(AUDIOENCODE);
670 | process.StandardInput.WriteLine(cmd);
671 | process.BeginErrorReadLine();
672 | process.BeginOutputReadLine();
673 | this.audioProcessing = true;
674 | this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOENCODE);
675 | DispAudioDuration();
676 |
677 | checkNum = 0;
678 |
679 | Thread.Sleep(beforeProcessCheckTime);
680 |
681 | Process p2 = GetSubTaskProcess(ts.audioEncoder);
682 | if (p2 != null)
683 | {
684 | this.subTaskPID = p2.Id;
685 | }
686 | else
687 | {
688 | this.subTaskPID = -1;
689 | }
690 |
691 | while (this.audioProcessing == true)
692 | {
693 | try
694 | {
695 | Process.GetProcessById(this.subTaskPID);
696 | }
697 | catch (Exception e)
698 | {
699 | Thread.Sleep(1000);
700 | if (this.audioProcessing == true)
701 | {
702 | afterFailed();
703 | }
704 | return;
705 | }
706 |
707 | Thread.Sleep(processCheckInterval);
708 | //checkNum = checkCmdRunning(checkNum, checkF);
709 | //if (checkNum == -1)
710 | //{
711 | // return;
712 | //}
713 | }
714 | ClearUIAfterAudioProcessing();
715 |
716 | process.CancelErrorRead();
717 | process.CancelOutputRead();
718 |
719 | this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);
720 |
721 | // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
722 | if (isfailed)
723 | {
724 | return;
725 | }
726 | VideoEncode();
727 |
728 | // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
729 | if (isfailed)
730 | {
731 | return;
732 | }
733 | Mux();
734 |
735 | break;
736 | default:
737 | cmd = "";
738 | break;
739 | }
740 |
741 | //MessageBox.Show(cmd);
742 | }
743 |
744 | private void ResetRsForm()
745 | {
746 | this.rsForm.setEta("");
747 | this.rsForm.setFps("");
748 | this.rsForm.setTime("");
749 |
750 | this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
751 | }
752 |
753 | public void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
754 | {
755 | this.outPutCmdCount++;
756 | if (!String.IsNullOrEmpty(outLine.Data) && this.num != this.finishedNum)
757 | {
758 | string o = outLine.Data.ToString();
759 | log.AppendLine(o);
760 |
761 | // 音频编码解析
762 | if (this.audioProcessing == true)
763 | {
764 | string audioCopyFinishFlag = "video:0kB audio:";
765 | string audioEncodeFinishFlag = "Optimizing...done";
766 | this.rsForm.setPercent("-1");
767 |
768 | string time = "";
769 | string totalTime = "";
770 |
771 | InnerMethodDelagate CalculateAndDispProgress = delegate()
772 | {
773 | string[] splitTemp = totalTime.Split(new char[] { ':' });
774 |
775 | string HH = "0";
776 | string MM = "0";
777 | string SSMMM = "0";
778 |
779 | if (splitTemp.Length == 3)
780 | {
781 | HH = splitTemp[0];
782 | MM = splitTemp[1];
783 | SSMMM = splitTemp[2];
784 | } else if (splitTemp.Length == 3)
785 | {
786 | HH = "00";
787 | MM = splitTemp[0];
788 | SSMMM = splitTemp[1];
789 | }
790 |
791 | int hr = Convert.ToInt32(HH);
792 | int min = Convert.ToInt32(MM);
793 | double sec = Convert.ToDouble(SSMMM);
794 | double totalTimeValue = hr * 3600 + min * 60 + sec;
795 |
796 | splitTemp = time.Split(new char[] { ':' });
797 | if (splitTemp.Length == 2)
798 | {
799 | HH = "00";
800 | MM = splitTemp[0];
801 | SSMMM = splitTemp[1];
802 | }
803 | else if (splitTemp.Length == 3)
804 | {
805 | HH = splitTemp[0];
806 | MM = splitTemp[1];
807 | SSMMM = splitTemp[2];
808 | }
809 | hr = Convert.ToInt32(HH);
810 | min = Convert.ToInt32(MM);
811 | sec = Convert.ToDouble(SSMMM);
812 | double currentTimeValue = hr * 3600 + min * 60 + sec;
813 | double percent = currentTimeValue / totalTimeValue;
814 | this.rsForm.setPercent(percent.ToString("0.0"), AUDIOENCODE); //这一模式需要保留一位小数
815 | };
816 |
817 | if (o.Contains(audioCopyFinishFlag) || o.Contains(audioEncodeFinishFlag))
818 | {
819 | this.audioProcessing = false;
820 | }
821 | else
822 | {
823 | if (o.Contains("time=")) // 表示是音频复制模式
824 | {
825 | int timeIndex = o.IndexOf("time=") + 5;
826 | int timeLength = 11;
827 | time = o.Substring(timeIndex, timeLength);
828 |
829 | string currentTimeText = this.rsForm.getCurrentTimeText();
830 | int splitIndex = currentTimeText.IndexOf("/");
831 | totalTime = currentTimeText.Substring(splitIndex + 1, currentTimeText.Length - splitIndex - 1);
832 | if (String.IsNullOrWhiteSpace(totalTime))
833 | {
834 | totalTime = time;
835 | }
836 | this.rsForm.setTime(time + "/" + totalTime);
837 | CalculateAndDispProgress();
838 | }
839 | else // 音频编码模式
840 | {
841 | // 通过ffmpeg读取送到qaac转码
842 | // o 的格式 = 时间(速度x) 特征是x)
843 | int endIndex = o.IndexOf("x)");
844 | int startIndex = o.IndexOf("(");
845 | // 速度 xxx.x 最多5位字符,间隔不应大于5
846 | if (startIndex != -1 && endIndex != -1 && endIndex - startIndex < 6 && endIndex - startIndex > 0)
847 | {
848 | string speed = o.Substring(startIndex + 1, endIndex - startIndex - 1); // 第二个参数是子串的长度
849 | this.rsForm.setFps(speed + "x");
850 |
851 | // 从UI获取音频时长
852 | string lastCurrentTimeText = this.rsForm.getCurrentTimeText();
853 | int totalTimeStartIndex = lastCurrentTimeText.IndexOf("/") + 1;
854 | int totalTimeLength = lastCurrentTimeText.Length - totalTimeStartIndex;
855 | totalTime = lastCurrentTimeText.Substring(totalTimeStartIndex, totalTimeLength);
856 |
857 | time = o.Substring(0, startIndex - 1);
858 |
859 | if (String.IsNullOrWhiteSpace(totalTime))
860 | {
861 | totalTime = time;
862 | }
863 | this.rsForm.setTime(time + "/" + totalTime);
864 |
865 | CalculateAndDispProgress();
866 | }
867 | }
868 | }
869 | return;
870 | }
871 |
872 | // postProcessing解析
873 | if (this.postProcessing == true)
874 | {
875 | string ppfinishFlag01 = "encoded ";
876 | string ppfinishFlag02 = " frames";
877 | this.rsForm.setPercent("-2");
878 | if (o.Contains(ppfinishFlag01) && o.Contains(ppfinishFlag02))
879 | {
880 | this.postProcessing = false;
881 | miniLog += o + Environment.NewLine;
882 | }
883 | }
884 |
885 | // muxer解析
886 | if (this.muxing == true)
887 | {
888 | string muxingFinishFlag_mp401 = "ISO File Writing: ";
889 | string muxingFinishFlag_mp402 = "| (99/100)";
890 | string muxingFinishFlag_mkv = "Muxing took ";
891 | this.rsForm.setPercent("-2");
892 | if ((o.Contains(muxingFinishFlag_mp401) && o.Contains(muxingFinishFlag_mp402))
893 | || o.Contains(muxingFinishFlag_mkv))
894 | {
895 | this.muxing = false;
896 | }
897 | return;
898 | }
899 |
900 | // 视频编码解析
901 | string finishFlag01 = "x264 [info]: kb/s:";
902 | string finishFlag02 = "x265 [info]: consecutive B-frames:";
903 | //string finishFlag02 = " frames";
904 |
905 | if (this.encoding)
906 | {
907 | if (this.startTime == 0) // 仅在开始时运行,编码结束后要重置为0
908 | {
909 | this.startTime = System.Environment.TickCount;
910 | }
911 |
912 | if (o.Contains(finishFlag01) || o.Contains(finishFlag02)) // 视频编码结束了
913 | {
914 | miniLog += o + Environment.NewLine;
915 |
916 | this.endTime = System.Environment.TickCount;
917 |
918 | int timeElapsed = this.endTime - this.startTime;
919 |
920 | this.startTime = 0;
921 |
922 | this.rsForm.setPercent("100");
923 | this.rsForm.setFps("");
924 | this.rsForm.setEta("");
925 | this.rsForm.setTime("");
926 |
927 | // 视频编码结束后,x264可能先对视频流单独混流一次
928 | this.postProcessing = true;
929 | this.encoding = false;
930 | }
931 | else // 编码未结束更新进度
932 | {
933 | if (!o.Contains("[info]") && !o.Contains("q=-0.0 size="))
934 | {
935 | int checkIndex = this.reportCount % (checkPattern + checkPattern);
936 | checkTime[checkIndex] = System.Environment.TickCount;
937 | string encodedFrames = "";
938 | string totalFrames = "";
939 | int kbpsStartIndex, kbpsEndIndex;
940 |
941 | switch (this.videoType)
942 | {
943 | case NORMAL:
944 | // o 的格式 = xx frames: xx.xx fps, xxxx kb/s
945 |
946 | kbpsStartIndex = o.IndexOf("fps, ") + 5;
947 | kbpsEndIndex = o.IndexOf("kb/s") + 4;
948 |
949 | if (kbpsStartIndex != -1 && kbpsEndIndex != -1 && kbpsEndIndex - kbpsStartIndex > 6 && kbpsEndIndex - kbpsStartIndex < 14)
950 | {
951 | string estKbps = o.Substring(kbpsStartIndex, kbpsEndIndex - kbpsStartIndex);
952 | this.rsForm.setEstKbps(estKbps);
953 | }
954 |
955 | // 从UI获取视频总帧数
956 | string lastCurrentTimeText = this.rsForm.getCurrentTimeText();
957 | int totalTimeStartIndex = lastCurrentTimeText.IndexOf("/") + 1;
958 | int totalTimeLength = lastCurrentTimeText.Length - totalTimeStartIndex;
959 | totalFrames = lastCurrentTimeText.Substring(totalTimeStartIndex, totalTimeLength);
960 |
961 | // 从cmd中读取已经编码的帧数
962 | int framesIndex = o.IndexOf("frames:");
963 |
964 | // 帧数小于7位数
965 | if (framesIndex != -1 && framesIndex <= 8)
966 | {
967 | string frames = "";
968 | try
969 | {
970 | frames = o.Substring(0, framesIndex - 1);
971 | }
972 | catch (Exception e)
973 | {
974 | saveLog2File();
975 | }
976 | // endIndex = -1
977 | this.rsForm.setTime(frames + "/" + totalFrames);
978 |
979 | //string[] splitTemp = frames.Split(new char[] { '/' });
980 | encodedFrames = frames;
981 | //totalFrames = splitTemp[1];
982 |
983 | checkFrame[checkIndex] = Convert.ToInt32(encodedFrames);
984 |
985 | this.reportCount++;
986 |
987 | try
988 | {
989 | double percent = (double)(checkFrame[checkIndex]) / (Double.Parse(totalFrames)) * 100.0;
990 |
991 | this.rsForm.setPercent(percent.ToString());
992 |
993 | if (percent >= 99.9)
994 | {
995 | miniLog += o + Environment.NewLine;
996 | }
997 | }
998 | catch (Exception e)
999 | {
1000 | //saveLog2File();
1001 | }
1002 | }
1003 | break;
1004 |
1005 | case AVS:
1006 | // o 的格式 = [xx.x%] 已完成帧数/总帧数, ...
1007 |
1008 | int endIndex = o.IndexOf("%]");
1009 | int startIndex = o.IndexOf("[");
1010 | // 进度 xx.x 最多4位字符,间隔不应大于4 (index之间差值不得大于5)
1011 | if (startIndex != -1 && endIndex != -1 && endIndex - startIndex < 6 && endIndex - startIndex > 0)
1012 | {
1013 | string progress = o.Substring(startIndex + 1, endIndex - startIndex - 1); // 第二个参数是子串的长度
1014 | this.rsForm.setPercent(progress);
1015 | if (Convert.ToDouble(progress) >= 99.9)
1016 | {
1017 | miniLog += o + Environment.NewLine;
1018 | }
1019 | }
1020 |
1021 | // 从cmd中读取已经编码的帧数
1022 |
1023 | int framesIndexCaseAVS = o.IndexOf(" frames");
1024 |
1025 | if (framesIndexCaseAVS != -1)
1026 | {
1027 | // frames 格式: xxx/xxxxx (a/b, a的位数小于等于b的位数)
1028 | string frames = o.Substring(endIndex + 3, framesIndexCaseAVS - endIndex - 3);
1029 | this.rsForm.setTime(frames);
1030 |
1031 | string[] splitTemp = frames.Split(new char[] { '/' });
1032 | encodedFrames = splitTemp[0];
1033 | totalFrames = splitTemp[1];
1034 |
1035 | checkFrame[checkIndex] = Convert.ToInt32(encodedFrames);
1036 |
1037 | this.reportCount++;
1038 | }
1039 |
1040 | kbpsStartIndex = o.IndexOf("fps, ") + 5;
1041 | kbpsEndIndex = o.IndexOf("kb/s") + 4;
1042 |
1043 | if (kbpsStartIndex != -1 && kbpsEndIndex != -1 && kbpsEndIndex - kbpsStartIndex > 6 && kbpsEndIndex - kbpsStartIndex < 14)
1044 | {
1045 | string estKbps = o.Substring(kbpsStartIndex, kbpsEndIndex - kbpsStartIndex);
1046 | this.rsForm.setEstKbps(estKbps);
1047 | }
1048 |
1049 | break;
1050 |
1051 | default:
1052 | break;
1053 | }
1054 |
1055 | if (this.reportCount >= checkPattern)
1056 | {
1057 | // 定义一个内部(匿名)方法
1058 | // 分析并计算fps和ETA
1059 | InnerMethodDelagate processFpsAndETA = delegate()
1060 | {
1061 | // 取两位小数的方法
1062 | System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
1063 | nfi.NumberDecimalDigits = 2;
1064 | this.rsForm.setFps(fps[checkIndex].ToString("N", nfi) + " fps");
1065 |
1066 | // 计算优化后的ETA
1067 | double avgFps = NonZeroAverage(this.fps);
1068 | double eta = (double)(Convert.ToInt32(totalFrames) - checkFrame[checkIndex]) / avgFps / 60.0;
1069 |
1070 | double i = Math.Floor(eta); // 去除小数部分
1071 | double d = eta - i;
1072 |
1073 | double sec = d * 60.0;
1074 |
1075 | d = i / 60.0;
1076 | double h = Math.Floor(d);
1077 | double min = i - h * 60;
1078 |
1079 | string etaStr = ((int)h).ToString("00") + ":" + ((int)min).ToString("00") + ":" + ((int)sec).ToString("00");
1080 |
1081 | this.rsForm.setEta(etaStr);
1082 | };
1083 |
1084 | if (checkIndex >= checkPattern)
1085 | {
1086 | // 注意:下两句和另一部分是不一样的,不能复制
1087 | int timeIntetval = checkTime[checkIndex] - checkTime[checkIndex - checkPattern];
1088 | int framesInteval = checkFrame[checkIndex] - checkFrame[checkIndex - checkPattern];
1089 | fps[checkIndex] = (double)framesInteval / (double)timeIntetval * 1000;
1090 |
1091 | if (fps[checkIndex] > 0)
1092 | {
1093 | processFpsAndETA();
1094 | }
1095 | }
1096 | else
1097 | {
1098 | // 注意:下两句和另一部分是不一样的,不能复制
1099 | int timeIntetval = checkTime[checkIndex] - checkTime[checkIndex + checkPattern];
1100 | int framesInteval = checkFrame[checkIndex] - checkFrame[checkIndex + checkPattern];
1101 | fps[checkIndex] = (double)framesInteval / (double)timeIntetval * 1000;
1102 |
1103 | if (fps[checkIndex] > 0)
1104 | {
1105 | processFpsAndETA();
1106 | }
1107 | }
1108 | }
1109 | else
1110 | {
1111 | this.rsForm.setEta("正在计算...");
1112 | this.rsForm.setFps("正在统计...");
1113 | }
1114 | }
1115 | else
1116 | {
1117 | //miniLog += o + Environment.NewLine;
1118 | //this.rsForm.setPercent("0.0");
1119 | //this.rsForm.setTime("索引中");
1120 | }
1121 | }
1122 | }
1123 | }
1124 | }
1125 |
1126 | private string convertToTimerFormat(string s)
1127 | {
1128 | if (s.Length == 1)
1129 | {
1130 | return "0" + s;
1131 | } else
1132 | {
1133 | return s;
1134 | }
1135 | }
1136 |
1137 | private void AllThreadKill()
1138 | {
1139 | for (int i = 0; i < threadsNum; i++)
1140 | {
1141 | threads[i].Abort();
1142 | }
1143 | }
1144 |
1145 | private void saveLog2File()
1146 | {
1147 | string dateAndTime = DateTime.Now.ToString("yyyyMMdd_HHmmss");
1148 | string fp = System.Windows.Forms.Application.StartupPath + "\\" + "EVTLog_"
1149 | + dateAndTime + ".log";
1150 | System.IO.File.WriteAllText(fp, this.log.ToString(), Encoding.UTF8);
1151 | }
1152 |
1153 | private void saveMiniLog2File()
1154 | {
1155 | string fp = System.Windows.Forms.Application.StartupPath + "\\" + "EVTminiLog" + ".log";
1156 | System.IO.File.AppendAllText(fp, this.miniLog, Encoding.UTF8);
1157 | }
1158 |
1159 | // 成功完成一个任务时才会调用的debug方法
1160 | private void debugLog2File()
1161 | {
1162 | string dateAndTime = DateTime.Now.ToString("yyyyMMdd_HHmmss");
1163 | string fp = System.Windows.Forms.Application.StartupPath + "\\" + "EVTLog_"
1164 | + dateAndTime + ".log";
1165 | System.IO.File.WriteAllText(fp, this.log.ToString(), Encoding.UTF8);
1166 | }
1167 |
1168 | private int checkCmdRunning(int t, int _t)
1169 | {
1170 | // 判断_t次循环内有没有新的命令行信息输出
1171 | t = (++t == _t) ? t - _t : t;
1172 | if (t == 0 && this.outPutCmdCount == this.outPutCmdCheckCount) // && (this.encoding || this.muxing || this.audioProcessing)
1173 | {
1174 | saveLog2File();
1175 |
1176 | this.rsForm.setPercent("-1");
1177 | this.rsForm.setTime("发生错误");
1178 | this.rsForm.setFps("日志保存在程序目录");
1179 |
1180 | int sleepTime = 5; // 设置失败后继续下一个任务的时间
1181 | this.rsForm.setEta(sleepTime.ToString() + "秒后继续运行");
1182 |
1183 | t = -1;
1184 | this.rsForm.setStatusBarLabelTextColorRED();
1185 | this.finishedNum++;
1186 | this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
1187 |
1188 | Thread.Sleep(sleepTime * 1000);
1189 |
1190 | Process p = Process.GetProcessById(this.PIDs[0]);
1191 | p.Kill();
1192 | this.rsForm.setStopBtnState(false);
1193 | this.rsForm.setPercent("-3");
1194 | this.isfinished[0] = true;
1195 | this.reportCount = 0;
1196 | this.log.Clear();
1197 | }
1198 | else if (t == 0)
1199 | {
1200 | this.outPutCmdCheckCount = this.outPutCmdCount;
1201 | }
1202 | return t;
1203 | }
1204 |
1205 | // 新版的检查子任务是否正常运行的方法(Not used)
1206 | private bool checkCmdRunning(string processName)
1207 | {
1208 | Process[] ps = Process.GetProcessesByName(changeFileExtName(processName)); // 必须输入不含.exe的进程名
1209 |
1210 | Process p = null;
1211 |
1212 | for (int i = 0; i < ps.Length; i++)
1213 | {
1214 | Process parent = ExpertVideoToolbox.ProcessControl.ParentProcessUtilities.GetParentProcess(ps[i].Id);
1215 | if (parent != null && parent.Id == this.getPID())
1216 | {
1217 | p = ps[i];
1218 | break;
1219 | }
1220 | }
1221 |
1222 | if (p == null) // p为null表示要么没进入上述循环,要么ps为空
1223 | {
1224 | return false;
1225 | }
1226 | return true;
1227 | }
1228 |
1229 | private bool ConfirmFailed()
1230 | {
1231 | Thread.Sleep(1000);
1232 | if (this.postProcessing == false)
1233 | {
1234 | return false;
1235 | }
1236 | else
1237 | {
1238 | return true;
1239 | }
1240 | }
1241 |
1242 | // 得到指定进程的子进程(默认为返回本程序创建的cmd进程的子进程)
1243 | private Process GetSubTaskProcess(string processName, int parentId = -1)
1244 | {
1245 | Process[] ps = Process.GetProcessesByName(changeFileExtName(processName)); // 必须输入不含.exe的进程名
1246 |
1247 | Process p = null;
1248 |
1249 | int targetParentId = parentId == -1 ? this.getPID() : parentId;
1250 |
1251 | for (int i = 0; i < ps.Length; i++)
1252 | {
1253 | Process parent = ExpertVideoToolbox.ProcessControl.ParentProcessUtilities.GetParentProcess(ps[i].Id);
1254 | if (parent != null && parent.Id == targetParentId)
1255 | {
1256 | p = ps[i];
1257 | break;
1258 | }
1259 | }
1260 | return p;
1261 | }
1262 |
1263 | // 求剔除零之后数组的平均值
1264 | private double NonZeroAverage(double[] d)
1265 | {
1266 | int count = d.Length;
1267 | int nonZeroCount = 0;
1268 | double sum = 0.0;
1269 | for (int i = 0; i < count; i++)
1270 | {
1271 | if (d[i] != 0)
1272 | {
1273 | nonZeroCount++;
1274 | sum += d[i];
1275 | }
1276 | }
1277 | return sum / (double)nonZeroCount;
1278 | }
1279 |
1280 | // 已知问题:如果输入为无扩展名的文件名而且其路径中含有.,就会替换最后一个点后所有字符
1281 | private string changeFileExtName(string originFp, string ext = "")
1282 | {
1283 | if (!originFp.Contains('.'))
1284 | {
1285 | if (!String.IsNullOrWhiteSpace(ext))
1286 | {
1287 | return originFp + "." + ext;
1288 | }
1289 | else
1290 | {
1291 | return originFp;
1292 | }
1293 | }
1294 |
1295 | string[] s = originFp.Split(new char[] { '.' });
1296 | int length = s.Length;
1297 | s[length - 1] = ext;
1298 | string finalFileName = "";
1299 | for (int i = 0; i < length; i++)
1300 | {
1301 | finalFileName += s[i];
1302 | if (i != length - 1)
1303 | {
1304 | finalFileName += ".";
1305 | }
1306 | }
1307 | if (string.IsNullOrWhiteSpace(ext)) // 当需要的扩展名为空时,去除字符串最后位置的一个点
1308 | {
1309 | finalFileName = finalFileName.Substring(0, finalFileName.Length - 1);
1310 | }
1311 | return finalFileName;
1312 | }
1313 |
1314 | private string getFileExtName(string originFp)
1315 | {
1316 | string[] s = originFp.Split(new char[] { '.' });
1317 | int length = s.Length;
1318 | return s[length - 1];
1319 | }
1320 | }
1321 | }
1322 |
--------------------------------------------------------------------------------