├── dist
└── windows
│ ├── upx.exe
│ ├── OKEGui.ico
│ ├── nsis plugins
│ └── UAC.zip
│ ├── examples
│ ├── 00001.m2ts.json
│ ├── launch.cmd
│ ├── demo_720p.json
│ ├── vfr.vpy
│ ├── demo.vpy
│ ├── vfr.json
│ ├── demo_720p.vpy
│ └── demo.json
│ ├── okegui.nsi
│ ├── translations.nsi
│ ├── README.md
│ ├── uninstaller.nsi
│ ├── installer-translations
│ ├── simpchinese.nsi
│ └── english.nsi
│ ├── options.nsi
│ └── installer.nsi
├── OKEGui
├── OKEGui
│ ├── Gui
│ │ ├── App.ico
│ │ ├── ConfigPanel.xaml.cs
│ │ ├── ConfigPanel.xaml
│ │ └── WizardWindow.xaml
│ ├── App.config
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── Utils
│ │ ├── PathUtils.cs
│ │ ├── TChapterExtension.cs
│ │ ├── WmiUtils.cs
│ │ ├── RegistryStorage.cs
│ │ ├── SafeProxy.cs
│ │ ├── Cleaner.cs
│ │ ├── Constants.cs
│ │ ├── SystemMenu.cs
│ │ ├── CRC32.cs
│ │ ├── Initializer.cs
│ │ └── EnvironmentChecker.cs
│ ├── App.xaml
│ ├── Model
│ │ ├── Track
│ │ │ ├── AudioTrack.cs
│ │ │ ├── ChapterTrack.cs
│ │ │ ├── VideoTrack.cs
│ │ │ ├── SubtitleTrack.cs
│ │ │ └── Track.cs
│ │ ├── Info
│ │ │ ├── AudioInfo.cs
│ │ │ ├── VideoInfo.cs
│ │ │ └── Info.cs
│ │ ├── MediaFile.cs
│ │ └── OKEFile.cs
│ ├── Job
│ │ ├── AudioJob
│ │ │ └── AudioJob.cs
│ │ ├── VideoJob
│ │ │ ├── VideoInfoJob.cs
│ │ │ └── VideoJob.cs
│ │ ├── RpcJob
│ │ │ └── RpcJob.cs
│ │ └── Job.cs
│ ├── packages.config
│ ├── Task
│ │ ├── EpisodeProfile.cs
│ │ ├── TaskDetail.cs
│ │ ├── TaskProfile.cs
│ │ ├── SubProcessService.cs
│ │ ├── TaskStatus.cs
│ │ └── ChapterService.cs
│ ├── JobProcessor
│ │ ├── IJobProcessor.cs
│ │ ├── Audio
│ │ │ ├── FFmpegVolumeChecker.cs
│ │ │ └── QAACEncoder.cs
│ │ ├── Demuxer
│ │ │ └── TrackInfo.cs
│ │ ├── Video
│ │ │ ├── X264Encoder.cs
│ │ │ ├── svtav1Encoder.cs
│ │ │ ├── x265Encoder.cs
│ │ │ ├── VSPipeProcessor.cs
│ │ │ └── CommandlineVideoEncoder.cs
│ │ ├── ExceptionParser.cs
│ │ └── RpChecker
│ │ │ └── RpChecker.cs
│ ├── App.xaml.cs
│ └── Worker
│ │ ├── NumaNode.cs
│ │ └── WorkerManager.cs
├── .editorconfig
└── OKEGui.sln
├── .gitmodules
├── README.md
├── .github
└── workflows
│ ├── dotnet-ci.yml
│ └── release.yaml
├── .gitattributes
├── RELNOTES.md
└── .gitignore
/dist/windows/upx.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmusementClub/OKEGui/mod/dist/windows/upx.exe
--------------------------------------------------------------------------------
/dist/windows/OKEGui.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmusementClub/OKEGui/mod/dist/windows/OKEGui.ico
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Gui/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmusementClub/OKEGui/mod/OKEGui/OKEGui/Gui/App.ico
--------------------------------------------------------------------------------
/dist/windows/nsis plugins/UAC.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmusementClub/OKEGui/mod/dist/windows/nsis plugins/UAC.zip
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "TChapter"]
2 | path = TChapter
3 | url = https://github.com/vcb-s/TChapter.git
4 | branch = net-45
5 |
--------------------------------------------------------------------------------
/dist/windows/examples/00001.m2ts.json:
--------------------------------------------------------------------------------
1 | {
2 | "VspipeArgs" : [
3 | "op_start=8000",
4 | "op_end=16000"
5 | ]
6 | }
--------------------------------------------------------------------------------
/dist/windows/okegui.nsi:
--------------------------------------------------------------------------------
1 | !include options.nsi
2 | !include translations.nsi
3 | !include installer.nsi
4 | !include uninstaller.nsi
5 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dist/windows/translations.nsi:
--------------------------------------------------------------------------------
1 | ;Nsis translations
2 |
3 | !insertmacro MUI_LANGUAGE "English"
4 | !insertmacro MUI_LANGUAGE "SimpChinese"
5 |
6 | ;Installer/Uninstaller translations
7 | !addincludedir installer-translations
8 |
9 | ;The languages should be in alphabetical order
10 | !include english.nsi
11 | !include simpchinese.nsi
12 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Utils/PathUtils.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace OKEGui
4 | {
5 | class PathUtils
6 | {
7 | public static string GetFullPath(string rel, string baseDir)
8 | {
9 | if (Path.IsPathRooted(rel))
10 | return rel;
11 | return Path.Combine(baseDir, rel);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OKEGui/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # CA1712: Do not prefix enum values with type name
4 | dotnet_diagnostic.CA1712.severity = none
5 |
6 | # CS0649: Field 'field' is never assigned to, and will always have its default value 'value'
7 | dotnet_diagnostic.CS0649.severity = suggestion
8 |
9 | # CA2235: Mark all non-serializable fields
10 | dotnet_diagnostic.CA2235.severity = suggestion
11 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Track/AudioTrack.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 OKEGui.Model
8 | {
9 | public class AudioTrack : Track
10 | {
11 | public AudioTrack(OKEFile file, AudioInfo info) : base(file, info)
12 | {
13 | TrackType = TrackType.Audio;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Track/ChapterTrack.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 OKEGui.Model
8 | {
9 | public class ChapterTrack : Track
10 | {
11 | public ChapterTrack(OKEFile file) : base(file, new Info())
12 | {
13 | TrackType = TrackType.Chapter;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Track/VideoTrack.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 OKEGui.Model
8 | {
9 | public class VideoTrack : Track
10 | {
11 | public VideoTrack(OKEFile file, VideoInfo info) : base(file, info)
12 | {
13 | TrackType = TrackType.Video;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Job/AudioJob/AudioJob.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Model;
2 |
3 | namespace OKEGui
4 | {
5 | class AudioJob : Job
6 | {
7 | public readonly AudioInfo Info;
8 |
9 | public AudioJob(AudioInfo info) : base(info.OutputCodec)
10 | {
11 | Info = info;
12 | }
13 |
14 | public override JobType GetJobType()
15 | {
16 | return JobType.Audio;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Info/AudioInfo.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Utils;
2 |
3 | namespace OKEGui.Model
4 | {
5 | public class AudioInfo : Info
6 | {
7 | public string OutputCodec;
8 | public int Bitrate = Constants.QAACBitrate;
9 | public bool Lossy = false;
10 | public int Quality = 0;
11 |
12 | public AudioInfo() : base()
13 | {
14 | InfoType = InfoType.Audio;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Utils/TChapterExtension.cs:
--------------------------------------------------------------------------------
1 | using TChapter.Chapters;
2 |
3 | namespace OKEGui.Utils
4 | {
5 | static class TChapterExtension
6 | {
7 | public static void Save(this ChapterInfo info, ChapterTypeEnum chapterType, string savePath, int index = 0,
8 | bool removeName = false, string language = "", string sourceFileName = "")
9 | {
10 | new MultiChapterData(ChapterTypeEnum.UNKNOWN) {info}
11 | .Save(chapterType, savePath, index, removeName, language, sourceFileName);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Job/VideoJob/VideoInfoJob.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace OKEGui
4 | {
5 | public class VideoInfoJob : Job
6 | {
7 | public List Args = new List();
8 | public VideoJob vJob;
9 | public VideoInfoJob(VideoJob job) : base()
10 | {
11 | vJob = job;
12 | Input = job.Input;
13 | Args.AddRange(job.VspipeArgs);
14 | }
15 |
16 | public override JobType GetJobType()
17 | {
18 | return JobType.VideoInfo;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Track/SubtitleTrack.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 OKEGui.Model
8 | {
9 | public class SubtitleTrack : Track
10 | {
11 | public SubtitleTrack(OKEFile file, Info info) : base(file, info)
12 | {
13 | if (info.InfoType != InfoType.Default)
14 | {
15 | throw new ArgumentException("Invalid media info for subtitle track");
16 | }
17 | TrackType = TrackType.Subtitle;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Job/VideoJob/VideoJob.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace OKEGui
4 | {
5 | public class VideoJob : Job
6 | {
7 | public string EncoderPath;
8 | public string EncodeParam;
9 | public List VspipeArgs = new List();
10 | public bool Vfr;
11 | public double Fps;
12 | public uint FpsNum;
13 | public uint FpsDen;
14 | public int NumaNode;
15 | public ulong NumberOfFrames;
16 |
17 | public VideoJob(string codec) : base(codec)
18 | {
19 | }
20 |
21 | public override JobType GetJobType()
22 | {
23 | return JobType.Video;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Info/VideoInfo.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 OKEGui.Model
8 | {
9 | public class VideoInfo : Info
10 | {
11 | public uint FpsNum;
12 | public uint FpsDen = 1;
13 | public string TimeCodeFile;
14 |
15 | public VideoInfo() : base()
16 | {
17 | InfoType = InfoType.Video;
18 | }
19 | public VideoInfo(uint fpsNum, uint fpsDen, string timeCodeFile) : this()
20 | {
21 | TimeCodeFile = timeCodeFile;
22 | FpsNum = fpsNum;
23 | FpsDen = fpsDen;
24 | }
25 |
26 | public double GetFps()
27 | {
28 | return (double)FpsNum / FpsDen;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/dist/windows/examples/launch.cmd:
--------------------------------------------------------------------------------
1 | :: This script launches OKEGui.exe and then elevates privilege to
2 | :: disable power throattling of bundled vspipe.exe and x265.exe.
3 | ::
4 | :: Use this to launch OKEGui when you're using Intel hybrid cores
5 | :: and don't want Windows to put those processes into the efficient
6 | :: cores when the OKEGui window is in the background.
7 | ::
8 | :: Also note this scripts requires that you're not running it as
9 | :: Administrator.
10 |
11 | cd %~dp0
12 | net file 1>NUL 2>NUL
13 | if not '%errorlevel%' == '0' (
14 | start "" OKEGui.exe
15 | powershell Start-Process -FilePath "%0" -verb runas >NUL 2>&1
16 | exit /b
17 | )
18 | powercfg /powerthrottling disable /PATH %~dp0\tools\x26x\x265.exe
19 | powercfg /powerthrottling disable /PATH %~dp0\tools\x26x\x264.exe
20 | powercfg /powerthrottling disable /PATH %~dp0\tools\vapoursynth\vspipe.exe
21 |
--------------------------------------------------------------------------------
/dist/windows/examples/demo_720p.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version" : 2,
3 | "ProjectName" : "Demo - 720p",
4 | "EncoderType" : "x264",
5 | "Encoder" : "x264_64_tMod-8bit-420.exe",
6 | "EncoderParam" : "--preset veryslow --tune animation --crf 19.0 --deblock 0:0 --keyint 360 --min-keyint 1 --bframes 8 --ref 9 --pbratio 1.25 --qcomp 0.7 --rc-lookahead 70 --aq-strength 0.9 --merange 24 --psy-rd 0.00:0.20 --no-dct-decimate --no-fast-pskip --colormatrix bt709 --fgo 1",
7 | "ContainerFormat" : "mp4",
8 | "AudioTracks" : [{
9 | "TrackId" : 0,
10 | "OutputCodec" : "aac",
11 | "Bitrate" : 128
12 | },{
13 | "TrackId" : 1,
14 | "OutputCodec" : "flac",
15 | "MuxOption" : "Skip"
16 | }],
17 | "InputScript" : "demo_720p.vpy",
18 | "Fps" : 23.976,
19 | "SubtitleTracks" : [{
20 | "MuxOption" : "Skip"
21 | }],
22 | "InputFiles" : [
23 | "00000.m2ts",
24 | "00001.m2ts",
25 | "00002.m2ts",
26 | ],
27 | "Rpc" : true
28 | }
29 |
--------------------------------------------------------------------------------
/dist/windows/examples/vfr.vpy:
--------------------------------------------------------------------------------
1 | import vapoursynth as vs
2 | from vapoursynth import core
3 | import pathlib
4 | import mvsfunc as mvf
5 |
6 | #OKE:INPUTFILE
7 | A="00000.m2ts"
8 |
9 | if 'a' not in globals(): a = A
10 |
11 | src8 = core.lsmas.LWLibavSource(a)
12 | src16 = core.fmtc.bitdepth(src8,bits=16)
13 |
14 | # preprocess
15 | res = core.grain.Add(src16, 1)
16 |
17 | # generate cfr clips
18 | res_a = core.std.AssumeFPS(res, fpsnum=24000,fpsden=1001)[:res.num_frames//2]
19 | res_b = core.std.AssumeFPS(res, fpsnum=30000,fpsden=1001)[res.num_frames//2:]
20 |
21 | # VFR splice
22 | path = pathlib.Path(a)
23 | res = mvf.VFRSplice([res_a, res_b], tcfile=str(path.with_suffix('.tcfile')), v2=False) # v2=True also ok
24 | # x265 only support CFR input, so use an approximate FPS here.
25 | res = core.std.AssumeFPS(res, fpsnum=27000, fpsden=1001)
26 |
27 | #OKE:DEBUG
28 | Debug = 0
29 | if Debug:
30 | res=core.std.Interleave([src16, res])
31 | res=mvf.ToRGB(res,full=False,depth=8)
32 | else: res = mvf.Depth(res, 10)
33 |
34 | res.set_output()
35 | src16.set_output(1)
36 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OKEGui.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/dist/windows/examples/demo.vpy:
--------------------------------------------------------------------------------
1 | import vapoursynth as vs
2 | import sys
3 | import os.path
4 | import math
5 | from vapoursynth import core
6 | import havsfunc as haf
7 | import mvsfunc as mvf
8 |
9 | core.num_threads = 8
10 |
11 | #OKE:PROJECTDIR
12 | projDir = '.'
13 | sys.path.insert(1, projDir) # some packages rely on having '' as sys.path[0]
14 | #import custom # import python modules under the project directory
15 | #core.std.LoadPlugin(os.path.join(projDir, 'libcustom.dll')) # or load custom plugins
16 |
17 | #OKE:MEMORY
18 | core.max_cache_size = 8000
19 |
20 | #OKE:INPUTFILE
21 | a="00000.m2ts"
22 | src8 = core.lsmas.LWLibavSource(a)
23 | src16 = core.fmtc.bitdepth(src8,bits=16)
24 |
25 | op = core.rgvs.RemoveGrain(src16, 20)
26 |
27 | res = core.std.Trim(src16, 0, int(op_start) - 1) + core.std.Trim(op, int(op_start), int(op_end)) + core.std.Trim(src16, int(op_end) + 1, src16.num_frames - 1)
28 |
29 | #OKE:DEBUG
30 | Debug = 1
31 | if Debug:
32 | res=core.std.Interleave([src16, res])
33 | res=mvf.ToRGB(res,full=False,depth=8)
34 | else: res = mvf.Depth(res, 10)
35 |
36 | res.set_output()
37 | src16.set_output(1)
38 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Track/Track.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 OKEGui.Model
8 | {
9 | public enum TrackType
10 | {
11 | Default,
12 | Audio,
13 | Subtitle,
14 | Video,
15 | Chapter,
16 | }
17 |
18 | public class Track : ICloneable
19 | {
20 | public OKEFile File;
21 | public Info Info;
22 | public TrackType TrackType { get; protected set; } = TrackType.Default;
23 |
24 | public Track(OKEFile file, Info info)
25 | {
26 | File = file;
27 | Info = info;
28 | }
29 |
30 | public virtual Object Clone()
31 | {
32 | Track clone = this.MemberwiseClone() as Track;
33 | HandleCloned(clone);
34 | return clone;
35 | }
36 |
37 |
38 | protected virtual void HandleCloned(Track clone)
39 | {
40 | if (Info != null)
41 | {
42 | Info = Info.Clone() as Info;
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Task/EpisodeProfile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace OKEGui.Task
5 | {
6 | public class EpisodeConfig : ICloneable
7 | {
8 | public List VspipeArgs = new List();
9 |
10 | public object Clone()
11 | {
12 | EpisodeConfig clone = MemberwiseClone() as EpisodeConfig;
13 | if (VspipeArgs != null)
14 | {
15 | clone.VspipeArgs = new List();
16 | foreach (string arg in VspipeArgs)
17 | {
18 | clone.VspipeArgs.Add(arg);
19 | }
20 | }
21 | return clone;
22 | }
23 |
24 | public override string ToString()
25 | {
26 | string str = "EpisodeConfig{";
27 | str += "VspipeArgs: ";
28 | if (VspipeArgs == null)
29 | {
30 | str += "null";
31 | }
32 | else
33 | {
34 | str += "[" + string.Join(",", VspipeArgs) + "]";
35 | }
36 | str += "]";
37 | return str;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/JobProcessor/IJobProcessor.cs:
--------------------------------------------------------------------------------
1 | namespace OKEGui
2 | {
3 | public delegate void JobProcessingStatusUpdateCallback(StatusUpdate su);
4 |
5 | ///
6 | /// 任务处理。可执行单元
7 | ///
8 | public interface IJobProcessor
9 | {
10 | ///
11 | /// starts the encoding process
12 | ///
13 | void start();
14 |
15 | ///
16 | /// stops the encoding process
17 | ///
18 | void stop();
19 |
20 | ///
21 | /// pauses the encoding process
22 | ///
23 | void pause();
24 |
25 | ///
26 | /// resumes the encoding process
27 | ///
28 | void resume();
29 |
30 | ///
31 | /// wait until job is finished
32 | ///
33 | void waitForFinish();
34 |
35 | ///
36 | /// changes the priority of the encoding process/thread
37 | ///
38 | void changePriority(ProcessPriority priority);
39 |
40 | event JobProcessingStatusUpdateCallback StatusUpdate;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/dist/windows/examples/vfr.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version" : 3,
3 | "VSVersion" : "2023H1b1",
4 | "ProjectName" : "VFR Demo - 1080p",
5 | "EncoderType" : "x265",
6 | "EncoderParam" : "-D 10 --deblock -1:-1 --preset slower --limit-tu 4 --no-strong-intra-smoothing --ctu 32 --crf 16 --qg-size 8 --pbratio 1.2 --cbqpoffs -2 --crqpoffs -2 --no-sao --me 3 --subme 5 --merange 38 --b-intra --no-amp --ref 4 --weightb --keyint 360 --min-keyint 1 --bframes 6 --aq-mode 1 --aq-strength 0.7 --rd 5 --psy-rd 1.5 --psy-rdoq 0.8 --rdoq-level 2 --no-open-gop --rc-lookahead 80 --scenecut 40 --qcomp 0.65 --vbv-bufsize 40000 --vbv-maxrate 30000 --colormatrix bt709 --range limited",
7 | "ContainerFormat" : "mkv",
8 | "AudioTracks" : [{
9 | "OutputCodec" : "flac"
10 | },{
11 | "OutputCodec" : "aac",
12 | "Bitrate" : 192,
13 | "Name": "Commentary",
14 | "Language" : "eng",
15 | "Optional": true
16 | }],
17 | "InputScript" : "vfr.vpy",
18 | "InputFiles" : [
19 | "Main_Disc\\BDMV\\STREAM\\00000.m2ts",
20 | "Main_Disc\\BDMV\\STREAM\\00001.m2ts",
21 | "Main_Disc\\BDMV\\STREAM\\00002.m2ts"
22 | ],
23 | "TimeCode": true,
24 | "Rpc" : true
25 | }
26 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Task/TaskDetail.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using OKEGui.Model;
4 | using OKEGui.Worker;
5 |
6 | namespace OKEGui
7 | {
8 | ///
9 | /// 在TaskStatus基础上,继续定义无需显示的域,来整体构成一个Task所需的所有数据和函数。
10 | ///
11 | public class TaskDetail : TaskStatus
12 | {
13 | // Task信息。从Json中读入。(见WizardWindow)
14 | public TaskProfile Taskfile;
15 | // Task所分解成的Job队列。
16 | public Queue JobQueue = new Queue();
17 |
18 | public string ChapterFileName;
19 | public string ChapterLanguage;
20 |
21 | // 输出文件轨道。MediaOutFile是主文件(mp4/mkv), MkaOutFile是外挂mka
22 | public MediaFile MediaOutFile;
23 | public MediaFile MkaOutFile;
24 |
25 | public string Tid;
26 | public long LengthInMiliSec;
27 |
28 | // 自动生成输出文件名
29 | public void UpdateOutputFileName()
30 | {
31 | var finfo = new System.IO.FileInfo(InputFile);
32 | if (Taskfile.ContainerFormat != "")
33 | {
34 | OutputFile = finfo.Name + "." + Taskfile.ContainerFormat.ToLower();
35 | }
36 | else
37 | {
38 | OutputFile = finfo.Name + "." + Taskfile.VideoFormat.ToLower();
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/dist/windows/examples/demo_720p.vpy:
--------------------------------------------------------------------------------
1 | import vapoursynth as vs
2 | import sys
3 | from vapoursynth import core
4 | import havsfunc as haf
5 | import mvsfunc as mvf
6 |
7 | core.num_threads = 12
8 |
9 | #OKE:MEMORY
10 | core.max_cache_size = 9000
11 |
12 | #OKE:INPUTFILE
13 | a="00001.m2ts"
14 | src8 = core.lsmas.LWLibavSource(a)
15 | src16 = core.fmtc.bitdepth(src8,bits=16)
16 |
17 | gray = core.std.ShufflePlanes(src16, 0, colorfamily=vs.GRAY)
18 | gray = core.fmtc.transfer(gray,transs="709",transd="linear")
19 | gray = core.fmtc.resample(gray,1280,720)
20 | gray = core.fmtc.transfer(gray,transs="linear",transd="709")
21 | UV = core.fmtc.resample(src16,1280,720)
22 | down = core.std.ShufflePlanes([gray,UV],[0,1,2], vs.YUV)
23 |
24 | nr16 = core.knlm.KNLMeansCL(down,device_type="GPU",h=0.6,s=3,d=1,a=2,channels="Y")
25 | noise16 = core.std.MakeDiff(down,nr16,0)
26 | dbed = core.f3kdb.Deband(nr16, 8,48,48,48,0,0,output_depth=16)
27 | dbed = core.f3kdb.Deband(dbed,16,32,32,32,0,0,output_depth=16)
28 | dbed = mvf.LimitFilter(dbed,nr16,thr=0.5,thrc=0.4,elast=1.5)
29 | dbed = core.std.MergeDiff(dbed,noise16,0)
30 |
31 |
32 | bright = mvf.Depth(dbed,8,dither=1)
33 | dark = mvf.Depth(dbed,8,dither=0,ampo=1.5)
34 | res = core.std.MaskedMerge(dark, bright, core.std.Binarize(bright, 128, planes=0), first_plane=True)
35 |
36 | res.set_output(0)
37 | src8.set_output(1)
38 |
--------------------------------------------------------------------------------
/dist/windows/README.md:
--------------------------------------------------------------------------------
1 | PACKAGERS:
2 |
3 | You will need NSIS and upx to make the installer. You need a unicode version of NSIS.
4 | Make sure you install the NSIS with full installation mode, otherwise you would miss the built-in plugins required.
5 |
6 | 1. Open the options.nsi file in an editor and change line that contains
7 | "!define PROG_VERSION "6.5"" to the version of OKEGui you just built.
8 | 2. Extract the plugins found in the folder "nsis plugins" into your
9 | NSIS's unicode Plugin directory(usually C:\Program Files\NSIS\Plugins\x86-unicode).
10 | Only the *.dll files are needed. Use the unicode version of the dlls if there are multiple versions.
11 | 3. The script you need to compile is "okegui.nsi". It includes all other necessary scripts.
12 | 4. The script expects the following file tree:
13 |
14 | The installer script expects the following file tree:
15 |
16 | ```
17 | Root:
18 | installer-translations\
19 | english.nsi
20 | simpchinese.nsi
21 | ...
22 | (all the .nsi files found here in every source release)
23 | samples\
24 | (all sample sciprt or config files found here)
25 | tools\
26 | (all required tools found here)
27 | installer.nsi
28 | options.nsi
29 | okegui.nsi
30 | translations.nsi
31 | UAC.nsh
32 | uninstaller.nsi
33 | ```
34 |
35 | 5. Make sure a relese build has been performed.
36 | 6. "`OKEGui_{VERSION}_setup.exe`" is the compiled binary file.
37 |
--------------------------------------------------------------------------------
/dist/windows/examples/demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version" : 3,
3 | "VSVersion" : "20210901",
4 | "ProjectName" : "Demo - 1080p",
5 | "EncoderType" : "x265",
6 | "Encoder" : "x265-10b.exe",
7 | "EncoderParam" : "-D 10 --deblock -1:-1 --preset slower --limit-tu 4 --no-strong-intra-smoothing --ctu 32 --crf 16 --qg-size 8 --pbratio 1.2 --cbqpoffs -2 --crqpoffs -2 --no-sao --me 3 --subme 5 --merange 38 --b-intra --no-amp --ref 4 --weightb --keyint 360 --min-keyint 1 --bframes 6 --aq-mode 1 --aq-strength 0.7 --rd 5 --psy-rd 1.5 --psy-rdoq 0.8 --rdoq-level 2 --no-open-gop --rc-lookahead 80 --scenecut 40 --qcomp 0.65 --vbv-bufsize 40000 --vbv-maxrate 30000 --colormatrix bt709 --range limited",
8 | "ContainerFormat" : "mkv",
9 | "AudioTracks" : [{
10 | "OutputCodec" : "flac"
11 | },{
12 | "OutputCodec" : "aac",
13 | "Bitrate" : 192,
14 | "Name": "Commentary",
15 | "Language" : "eng",
16 | "Optional": true
17 | }],
18 | "InputScript" : "demo.vpy",
19 | "Fps" : 23.976,
20 | "SubtitleTracks" : [{
21 | "Language" : "jpn"
22 | }],
23 | "InputFiles" : [
24 | "Main_Disc\\BDMV\\STREAM\\00000.m2ts",
25 | "Main_Disc\\BDMV\\STREAM\\00001.m2ts",
26 | "Main_Disc\\BDMV\\STREAM\\00002.m2ts",
27 | ],
28 | "Config" : {
29 | "VspipeArgs" : [
30 | "op_start=10000",
31 | "op_end=15000"
32 | ]
33 | },
34 | "Rpc" : true
35 | }
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [OKEGui](https://github.com/vcb-s/OKEGui/) · [](https://github.com/vcb-s/OKEGui/blob/master/LICENSE) [](https://ci.appveyor.com/project/vcb-s/okegui)
2 |
3 |
4 | 
5 |
6 | ## 安装
7 |
8 | 1. OKEGui 需要.NET 4.5。Windows 8/Windows Server 2012及以上自带;Windows 7和Windows Server 2008需要自行安装: https://www.microsoft.com/zh-cn/download/details.aspx?id=30653
9 |
10 | 2. OKEGui 自带的 qaac 工具依赖 Apple Quicktime. 这点请确保你的机器按照压制组需要正确安装了64bit iTunes 组件或者 AppleApplicationSupport: https://github.com/vcb-s/OKEGui/releases/download/4.0/AppleApplicationSupport64.msi
11 |
12 | 3. 下载最新 Release 的 zip 压缩包,解压到一个纯英文目录下。双击其中 OKEGui.exe,如果能正确运行显示出窗口,即安装成功。
13 |
14 | ## 代码中相关概念解释:
15 |
16 | Task: 从单个源(例如m2ts)到成品(例如mkv)的整个过程。task会在主程序界面的列表里显示。
17 |
18 | Job: 每个Task会被分解成不同的Job,并依次执行。例如抽流,压制,封装等。Job是可以独立运行的最低单位。
19 |
20 | JobProcessror: 负责执行每个Job的命令行Warpper。比如X265Encoder调用x265压制HEVC,FFMpegVolumeChecker调用ffmpeg检查音轨音量
21 |
22 | Model: 储存媒体文件相关的信息。Info只带例如语言、封装选项等信息,Track则是File+Info的组合,MediaFile则是多条Track的合集
23 |
24 | Worker: 每一个Task只会在一个Worker里进行,因此有几个Worker就允许几个Task同时进行。多开相关的选项。每个Task具体的实现流程由Worker负责执行。
25 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Utils/WmiUtils.cs:
--------------------------------------------------------------------------------
1 | using NLog;
2 | using System;
3 | using System.Management;
4 |
5 | namespace OKEGui.Utils
6 | {
7 | static class WmiUtils
8 | {
9 | private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
10 | public static int GetTotalPhysicalMemory()
11 | {
12 | long capacity = 0;
13 | try
14 | {
15 | foreach (ManagementObject mo1 in new ManagementClass("Win32_PhysicalMemory").GetInstances())
16 | capacity += long.Parse(mo1.Properties["Capacity"].Value.ToString());
17 | }
18 | catch (Exception ex)
19 | {
20 | capacity = -1;
21 | Logger.Error(ex, "Failed to get total physical memory");
22 | }
23 | return (int)(capacity / 1024.0 / 1024);
24 | }
25 |
26 | public static int GetAvailablePhysicalMemory()
27 | {
28 | int capacity = 0;
29 | try
30 | {
31 | foreach (ManagementObject mo1 in new ManagementClass("Win32_OperatingSystem").GetInstances())
32 | capacity += int.Parse(mo1.Properties["FreePhysicalMemory"].Value.ToString()) / 1024;
33 | }
34 | catch (Exception ex)
35 | {
36 | capacity = -1;
37 | Logger.Error(ex, "Failed to get available physical memory");
38 | }
39 | return capacity;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Job/RpcJob/RpcJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using static OKEGui.RpChecker;
8 |
9 | namespace OKEGui
10 | {
11 | public class RpcJob : Job
12 | {
13 | public readonly string RippedFile;
14 | public readonly ulong TotalFrame;
15 | public readonly Dictionary Args = new Dictionary();
16 | public readonly string FailedRPCOutputFile;
17 | public RpcStatus RpcStatus
18 | {
19 | set
20 | {
21 | if (ts != null)
22 | {
23 | ts.RpcStatus = value.ToString();
24 | }
25 | }
26 | }
27 | public RpcJob(string sourceFile, VideoJob videoJob, string outputPath)
28 | {
29 | Input = sourceFile;
30 | Output = Path.ChangeExtension(sourceFile, "rpc");
31 | RippedFile = videoJob.Output;
32 | FailedRPCOutputFile = outputPath + ".rpc";
33 | TotalFrame = videoJob.NumberOfFrames;
34 | foreach (string arg in videoJob.VspipeArgs)
35 | {
36 | int pos = arg.IndexOf('=');
37 | string variable = arg.Substring(0, pos);
38 | string value = arg.Substring(pos + 1);
39 | Args[variable] = value;
40 | }
41 | }
42 | public override JobType GetJobType()
43 | {
44 | return JobType.RpCheck;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Utils/RegistryStorage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.Win32;
7 |
8 | namespace OKEGui.Utils
9 | {
10 | class RegistryStorage
11 | {
12 | public static string DefaultSubKey => $@"Software\OKEGui";
13 |
14 | public static string Load(string subKey = null, string name = "")
15 | {
16 | if (subKey == null) subKey = DefaultSubKey;
17 | var path = string.Empty;
18 | // HKCU_CURRENT_USER\Software\
19 | var registryKey = Registry.CurrentUser.OpenSubKey(subKey);
20 | if (registryKey == null) return path;
21 | path = (string)registryKey.GetValue(name);
22 | registryKey.Close();
23 | return path;
24 | }
25 |
26 | public static void Save(string value, string subKey = null, string name = "")
27 | {
28 | if (subKey == null) subKey = DefaultSubKey;
29 | // HKCU_CURRENT_USER\Software\
30 | var registryKey = Registry.CurrentUser.CreateSubKey(subKey);
31 | registryKey?.SetValue(name, value);
32 | registryKey?.Close();
33 | }
34 |
35 | public static int RegistryAddCount(string subKey, string name, int delta = 1)
36 | {
37 | var countS = Load(subKey, name);
38 | var count = string.IsNullOrEmpty(countS) ? 0 : int.Parse(countS);
39 | count += delta;
40 | Save(count.ToString(), subKey, name);
41 | return count - delta;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("OKEGui")]
9 | [assembly: AssemblyDescription("The Protagonist Returns")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("OKEGui")]
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 | //若要开始生成可本地化的应用程序,请
23 | // 中的 .csproj 文件中
24 | //例如,如果您在源文件中使用的是美国英语,
25 | //使用的是美国英语,请将 设置为 en-US。 然后取消
26 | //对以下 NeutralResourceLanguage 特性的注释。 更新
27 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
28 |
29 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
30 |
31 | [assembly: ThemeInfo(
32 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置
33 | //(当资源未在页面
34 | //或应用程序资源字典中找到时使用)
35 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
36 | //(当资源未在页面
37 | //、应用程序或任何主题专用资源字典中找到时使用)
38 | )]
39 |
40 | // 程序集的版本信息由下列四个值组成:
41 | //
42 | // 主版本
43 | // 次版本
44 | // 生成号
45 | // 修订号
46 | //
47 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
48 | // 方法是按如下所示使用“*”: :
49 | // [assembly: AssemblyVersion("1.0.*")]
50 | [assembly: AssemblyVersion("8.6.1.*")]
51 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Utils;
2 | using System;
3 | using System.Reflection;
4 | using System.Windows;
5 |
6 | namespace OKEGui
7 | {
8 | ///
9 | /// 程序接入点。使用静态构造器来执行程序开始前的检查和其他任务。
10 | /// 主界面的设计和逻辑请见 Gui/MainWindow
11 | ///
12 | public partial class App : Application
13 | {
14 | private static readonly NLog.Logger Logger = NLog.LogManager.GetLogger("App");
15 |
16 | private void AppStartup(object sender, StartupEventArgs e)
17 | {
18 | AppDomain.CurrentDomain.AssemblyResolve += (sender_, args) =>
19 | {
20 | AssemblyName assemblyName = new AssemblyName(args.Name);
21 | var path = assemblyName.Name + ".dll";
22 |
23 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
24 | {
25 | if (stream == null) return null;
26 |
27 | var assemblyRawBytes = new byte[stream.Length];
28 | stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
29 | return Assembly.Load(assemblyRawBytes);
30 | }
31 | };
32 | if (EnvironmentChecker.CheckEnviornment())
33 | {
34 | System.Windows.Media.RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
35 | Initializer.ConfigLogger();
36 | Initializer.WriteConfig();
37 | Initializer.ClearOldLogs();
38 | Logger.Info("程序正常启动");
39 | }
40 | else
41 | {
42 | Environment.Exit(0);
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Worker/NumaNode.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Utils;
2 | using System;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace OKEGui.Worker
7 | {
8 | static class NumaNode
9 | {
10 | [DllImport("Kernel32.dll")]
11 | [return: MarshalAsAttribute(UnmanagedType.Bool)]
12 | public static extern bool GetNumaHighestNodeNumber([Out] out uint HighestNodeNumber);
13 |
14 | public static readonly int NumaCount;
15 | public static readonly int UsableCoreCount;
16 | static int CurrentNuma;
17 |
18 | static NumaNode()
19 | {
20 | if (Initializer.Config.singleNuma)
21 | {
22 | CurrentNuma = 0;
23 | NumaCount = 1;
24 | }
25 | else
26 | {
27 | GetNumaHighestNodeNumber(out uint temp);
28 | CurrentNuma = (int)temp;
29 | NumaCount = CurrentNuma + 1;
30 | }
31 | UsableCoreCount = Environment.ProcessorCount;
32 | }
33 |
34 | public static int NextNuma()
35 | {
36 | int res = CurrentNuma;
37 | CurrentNuma = (CurrentNuma - 1 + NumaCount) % NumaCount;
38 | return res;
39 | }
40 |
41 | public static int PrevNuma()
42 | {
43 | int res = CurrentNuma;
44 | CurrentNuma = (CurrentNuma + 1) % NumaCount;
45 | return res;
46 | }
47 |
48 | public static string X265PoolsParam(int currentNuma)
49 | {
50 | string[] res = Enumerable.Repeat("-", NumaCount).ToArray();
51 | res[currentNuma] = "+";
52 | return string.Join(",", res);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/JobProcessor/Audio/FFmpegVolumeChecker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using System.Threading.Tasks;
7 | using OKEGui.Utils;
8 |
9 | namespace OKEGui
10 | {
11 | class FFmpegVolumeChecker : CommandlineJobProcessor
12 | {
13 | public double MeanVolume { get; private set; }
14 | public double MaxVolume { get; private set; }
15 |
16 | private Regex rmsLevelRegex = new Regex(@"RMS level dB: (-?(?:\d+\.\d+|inf))");
17 | private Regex peakLevelRegex = new Regex(@"Peak level dB: (-?(?:\d+\.\d+|inf))");
18 |
19 | public FFmpegVolumeChecker(string inputFile)
20 | {
21 | executable = Constants.ffmpegPath;
22 | commandLine = $"-i \"{inputFile}\" -af astats=measure_perchannel=none -f null /dev/null";
23 | }
24 |
25 | public override void ProcessLine(string line, StreamType stream)
26 | {
27 | base.ProcessLine(line, stream);
28 |
29 | var rmsLevel = rmsLevelRegex.Match(line);
30 | if (rmsLevel.Success)
31 | {
32 | var success = double.TryParse(rmsLevel.Groups[1].Value, out double meanVolume);
33 | MeanVolume = success ? meanVolume : double.NegativeInfinity;
34 | return;
35 | }
36 |
37 | var peakLevel = peakLevelRegex.Match(line);
38 | if (peakLevel.Success)
39 | {
40 | var success = double.TryParse(peakLevel.Groups[1].Value, out double maxVolume);
41 | MaxVolume = success ? maxVolume : double.NegativeInfinity;
42 | SetFinish();
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/dist/windows/uninstaller.nsi:
--------------------------------------------------------------------------------
1 | Section "un.$(remove_files_str)" ;"un.Remove files"
2 | SectionIn RO
3 |
4 | ; Remove files and uninstaller
5 | Delete "$INSTDIR\*.dll"
6 | Delete "$INSTDIR\*.xml"
7 | Delete "$INSTDIR\OKEGui.exe"
8 | Delete "$INSTDIR\LICENSE"
9 | Delete "$INSTDIR\uninst.exe"
10 | RMDIr /r "$INSTDIR\examples"
11 | RMDIr /r "$INSTDIR\x86"
12 | RMDIr /r "$INSTDIR\x64"
13 |
14 | ; Remove directories used
15 | RMDir "$INSTDIR"
16 | SectionEnd
17 |
18 |
19 | Section /o "un.$(remove_config_str)" ;"un.Remove config file"
20 | Delete "$INSTDIR\OKEGuiConfig.json"
21 | RMDir "$INSTDIR"
22 | SectionEnd
23 |
24 |
25 | Section /o "un.$(remove_logs_str)" ;"un.Remove log files"
26 | RMDIr /r "$INSTDIR\log"
27 | RMDir "$INSTDIR"
28 | SectionEnd
29 |
30 |
31 | Section /o "un.$(remove_tools_str)" ;"un.Remove external tools"
32 | RMDIr /r "$INSTDIR\tools"
33 | RMDir "$INSTDIR"
34 | SectionEnd
35 |
36 |
37 | Section "un.$(remove_shortcuts_str)" ;"un.Remove shortcuts"
38 | SectionIn RO
39 | ; Remove shortcuts, if any
40 | RMDir /r "$SMPROGRAMS\OKEGui"
41 | Delete "$DESKTOP\OKEGui.lnk"
42 | SectionEnd
43 |
44 |
45 | Section "un.$(remove_registry_str)" ;"un.Remove registry keys"
46 | SectionIn RO
47 | ; Remove registry keys
48 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OKEGui"
49 | DeleteRegKey HKLM "Software\OKEGui"
50 | DeleteRegKey HKLM "Software\Classes\OKEGui"
51 |
52 | System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)'
53 | SectionEnd
54 |
55 |
56 | ;--------------------------------
57 | ;Uninstaller Functions
58 |
59 | Function un.onInit
60 |
61 | !insertmacro Init "uninstaller"
62 | !insertmacro MUI_UNGETLANGUAGE
63 |
64 | FunctionEnd
65 |
66 | Function un.onUninstSuccess
67 | SetErrorLevel 0
68 | FunctionEnd
69 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/Info/Info.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Utils;
2 | using System;
3 |
4 | namespace OKEGui.Model
5 | {
6 | public enum MuxOption
7 | {
8 | Default,
9 | Mka,
10 | External,
11 | ExtractOnly,
12 | Skip
13 | }
14 |
15 | public enum InfoType
16 | {
17 | Default,
18 | Video,
19 | Audio
20 | }
21 |
22 | public class Info : ICloneable
23 | {
24 | // base class of all info object
25 | public InfoType InfoType { get; protected set; } = InfoType.Default;
26 | public MuxOption MuxOption = MuxOption.Default;
27 | public string Language = Constants.language;
28 | public string Name = "";
29 | public bool Optional = false;
30 | public int Order = Int32.MaxValue;
31 | private bool _dupOrEmpty;
32 | public bool DupOrEmpty
33 | {
34 | get { return _dupOrEmpty; }
35 | set
36 | {
37 | _dupOrEmpty = value;
38 | if (value)
39 | {
40 | switch (MuxOption)
41 | {
42 | case MuxOption.Default:
43 | case MuxOption.Mka:
44 | case MuxOption.External:
45 | MuxOption = MuxOption.ExtractOnly;
46 | break;
47 | default:
48 | break;
49 | }
50 | }
51 | }
52 | }
53 |
54 | public virtual Object Clone()
55 | {
56 | Info clone = this.MemberwiseClone() as Info;
57 | HandleCloned(clone);
58 | return clone;
59 | }
60 |
61 |
62 | protected virtual void HandleCloned(Info clone)
63 | {
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/dist/windows/installer-translations/simpchinese.nsi:
--------------------------------------------------------------------------------
1 | ;Installer strings
2 |
3 | ;LangString inst_req_str ${LANG_ENGLISH} "OKEGui (required)"
4 | LangString inst_req_str ${LANG_SIMPCHINESE} "OKEGui (必要)"
5 | ;LangString inst_tools_str ${LANG_ENGLISH} "External tools (recommend)"
6 | LangString inst_tools_str ${LANG_SIMPCHINESE} "外部工具 (推荐)"
7 | ;LangString inst_samples_str ${LANG_ENGLISH} "Example files (optional)"
8 | LangString inst_samples_str ${LANG_SIMPCHINESE} "示例文件 (可选)"
9 | ;LangString inst_dekstop_str ${LANG_ENGLISH} "Create Desktop Shortcut"
10 | LangString inst_dekstop_str ${LANG_SIMPCHINESE} "创建桌面快捷方式"
11 | ;LangString inst_startmenu_str ${LANG_ENGLISH} "Create Start Menu Shortcut"
12 | LangString inst_startmenu_str ${LANG_SIMPCHINESE} "创建开始菜单快捷方式"
13 | ;LangString inst_uninstall_question_str ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
14 | LangString inst_uninstall_question_str ${LANG_SIMPCHINESE} "检测到以前的安装。 它将被卸载但不删除用户设置。"
15 | ;LangString inst_unist_str ${LANG_ENGLISH} "Uninstalling previous version."
16 | LangString inst_unist_str ${LANG_SIMPCHINESE} "卸载以前的版本。"
17 | ;LangString launch_str ${LANG_ENGLISH} "Launch OKEGui."
18 | LangString launch_str ${LANG_SIMPCHINESE} "启动 OKEGui."
19 |
20 |
21 | ;------------------------------------
22 | ;Uninstaller strings
23 |
24 | ;LangString remove_files_str ${LANG_ENGLISH} "Remove files"
25 | LangString remove_files_str ${LANG_SIMPCHINESE} "删除文件"
26 | ;LangString remove_shortcuts_str ${LANG_ENGLISH} "Remove shortcuts"
27 | LangString remove_shortcuts_str ${LANG_SIMPCHINESE} "删除快捷方式"
28 | ;LangString remove_registry_str ${LANG_ENGLISH} "Remove registry keys"
29 | LangString remove_registry_str ${LANG_SIMPCHINESE} "删除注册表键"
30 | ;LangString remove_config_str ${LANG_ENGLISH} "Remove config file"
31 | LangString remove_config_str ${LANG_SIMPCHINESE} "移除配置文件"
32 | ;LangString remove_tools_str ${LANG_ENGLISH} "Remove external tools"
33 | LangString remove_tools_str ${LANG_SIMPCHINESE} "移除外部工具"
34 | ;LangString remove_logs_str ${LANG_ENGLISH} "Remove log files"
35 | LangString remove_logs_str ${LANG_SIMPCHINESE} "删除日志"
36 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Gui/ConfigPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 | using OKEGui.Utils;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Data;
11 | using System.Windows.Documents;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Media.Imaging;
15 | using System.Windows.Shapes;
16 |
17 | namespace OKEGui
18 | {
19 | ///
20 | /// Config.xaml 的交互逻辑
21 | ///
22 | public partial class ConfigPanel : Window
23 | {
24 | public OKEGuiConfig Config { get; }
25 |
26 | private void Vspipe_Click(object sender, RoutedEventArgs e)
27 | {
28 | OpenFileDialog ofd = new OpenFileDialog
29 | {
30 | Multiselect = false,
31 | Filter = "vspipe.exe (vspipe.exe)|vspipe.exe",
32 | InitialDirectory = Config.vspipePath
33 | };
34 | bool result = ofd.ShowDialog().GetValueOrDefault(false);
35 | if (result)
36 | {
37 | Config.vspipePath = ofd.FileName;
38 | }
39 | }
40 |
41 | private void RPChecker_Click(object sender, RoutedEventArgs e)
42 | {
43 | OpenFileDialog ofd = new OpenFileDialog
44 | {
45 | Multiselect = false,
46 | Filter = "RPChecker.exe (RPChecker*.exe)|RPChecker*.exe",
47 | InitialDirectory = Config.rpCheckerPath
48 | };
49 | bool result = ofd.ShowDialog().GetValueOrDefault(false);
50 | if (result)
51 | {
52 | Config.rpCheckerPath = ofd.FileName;
53 | }
54 | }
55 |
56 | private void Save_Click(object sender, RoutedEventArgs e)
57 | {
58 | Initializer.Config = Config;
59 | Initializer.WriteConfig();
60 | Close();
61 | }
62 |
63 | public ConfigPanel()
64 | {
65 | Config = Initializer.Config.Clone() as OKEGuiConfig;
66 | InitializeComponent();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/dist/windows/installer-translations/english.nsi:
--------------------------------------------------------------------------------
1 | ;Installer strings
2 |
3 | ;LangString inst_req_str ${LANG_ENGLISH} "OKEGui (required)"
4 | LangString inst_req_str ${LANG_ENGLISH} "OKEGui (required)"
5 | ;LangString inst_tools_str ${LANG_ENGLISH} "External tools (recommend)"
6 | LangString inst_tools_str ${LANG_ENGLISH} "External tools (recommend)"
7 | ;LangString inst_samples_str ${LANG_ENGLISH} "Example files (optional)"
8 | LangString inst_samples_str ${LANG_ENGLISH} "Example files (optional)"
9 | ;LangString inst_dekstop_str ${LANG_ENGLISH} "Create Desktop Shortcut"
10 | LangString inst_dekstop_str ${LANG_ENGLISH} "Create Desktop Shortcut"
11 | ;LangString inst_startmenu_str ${LANG_ENGLISH} "Create Start Menu Shortcut"
12 | LangString inst_startmenu_str ${LANG_ENGLISH} "Create Start Menu Shortcut"
13 | ;LangString inst_uninstall_question_str ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
14 | LangString inst_uninstall_question_str ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
15 | ;LangString inst_unist_str ${LANG_ENGLISH} "Uninstalling previous version."
16 | LangString inst_unist_str ${LANG_ENGLISH} "Uninstalling previous version."
17 | ;LangString launch_str ${LANG_ENGLISH} "Launch OKEGui."
18 | LangString launch_str ${LANG_ENGLISH} "Launch OKEGui."
19 |
20 |
21 | ;------------------------------------
22 | ;Uninstaller strings
23 |
24 | ;LangString remove_files_str ${LANG_ENGLISH} "Remove files"
25 | LangString remove_files_str ${LANG_ENGLISH} "Remove files"
26 | ;LangString remove_shortcuts_str ${LANG_ENGLISH} "Remove shortcuts"
27 | LangString remove_shortcuts_str ${LANG_ENGLISH} "Remove shortcuts"
28 | ;LangString remove_registry_str ${LANG_ENGLISH} "Remove registry keys"
29 | LangString remove_registry_str ${LANG_ENGLISH} "Remove registry keys"
30 | ;LangString remove_config_str ${LANG_ENGLISH} "Remove config file"
31 | LangString remove_config_str ${LANG_ENGLISH} "Remove config file"
32 | ;LangString remove_tools_str ${LANG_ENGLISH} "Remove external tools"
33 | LangString remove_tools_str ${LANG_ENGLISH} "Remove external tools"
34 | ;LangString remove_logs_str ${LANG_ENGLISH} "Remove log files"
35 | LangString remove_logs_str ${LANG_ENGLISH} "Remove log files"
36 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/JobProcessor/Audio/QAACEncoder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Text.RegularExpressions;
5 | using System.Threading;
6 | using OKEGui.Utils;
7 | using OKEGui.JobProcessor;
8 |
9 | namespace OKEGui
10 | {
11 | internal class QAACEncoder : CommandlineJobProcessor
12 | {
13 | private ManualResetEvent retrieved = new ManualResetEvent(false);
14 | private Action _progressCallback;
15 | private static readonly NLog.Logger Logger = NLog.LogManager.GetLogger("QAACEncoder");
16 |
17 | // TODO: 变更编码参数
18 | public QAACEncoder(AudioJob j, Action progressCallback, int bitrate = Constants.QAACBitrate, int quality = 0) : base()
19 | {
20 | _progressCallback = progressCallback;
21 | if (j.Input != "-")
22 | { //not from stdin, but an actual file
23 | j.Input = $"\"{j.Input}\"";
24 | }
25 |
26 | executable = Constants.QAACPath;
27 | if (quality > 0)
28 | {
29 | commandLine = $"-V {quality}";
30 | }
31 | else
32 | {
33 | commandLine = $"-v {bitrate}";
34 | }
35 | commandLine += $" -i -q 2 --no-delay -o \"{j.Output}\" {j.Input}";
36 | }
37 |
38 | public QAACEncoder(string commandLine)
39 | {
40 | this.executable = Constants.QAACPath;
41 | this.commandLine = commandLine;
42 | }
43 |
44 | public override void ProcessLine(string line, StreamType stream)
45 | {
46 | Regex rAnalyze = new Regex("\\[([0-9.]+)%\\]");
47 | double p = 0;
48 | if (rAnalyze.IsMatch(line))
49 | {
50 | double.TryParse(rAnalyze.Split(line)[1], out p);
51 | if (p > 1)
52 | {
53 | _progressCallback(p);
54 | }
55 | }
56 | else
57 | {
58 | Logger.Debug(line);
59 | if (line.Contains(".done"))
60 | {
61 | SetFinish();
62 | }
63 | if (line.Contains("ERROR"))
64 | {
65 | throw new OKETaskException(Constants.qaacErrorSmr);
66 | }
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet-ci.yml:
--------------------------------------------------------------------------------
1 | # For more information on GitHub Actions, refer to https://github.com/features/actions
2 | # For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
3 | # refer to https://github.com/microsoft/github-actions-for-desktop-apps
4 |
5 | name: .NET Desktop
6 |
7 | on:
8 | push:
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 |
14 | build:
15 |
16 | strategy:
17 | matrix:
18 | configuration: [Release]
19 | targetplatform: [x64]
20 |
21 | runs-on: windows-2019 # For a list of available runner types, refer to
22 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
23 |
24 | env:
25 | Solution_Name: OKEGui\OKEGui.sln # Replace with your solution name, i.e. MyWpfApp.sln.
26 |
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v3
30 | with:
31 | submodules: true
32 |
33 | # Install the .NET workload
34 | - name: Install .NET
35 | uses: actions/setup-dotnet@v3
36 | with:
37 | dotnet-version: 5.0.x
38 |
39 | # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
40 | - name: Setup MSBuild.exe
41 | uses: microsoft/setup-msbuild@v1.1
42 |
43 | - uses: nuget/setup-nuget@v1
44 | with:
45 | nuget-version: '5.x'
46 |
47 | - name: Restore Nuget packages
48 | run: nuget restore $env:Solution_Name
49 |
50 | # Restore the application to populate the obj folder with RuntimeIdentifiers
51 | - name: Restore the application
52 | run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
53 | env:
54 | Configuration: ${{ matrix.configuration }}
55 |
56 | # Build the Application project
57 | - name: Build the Application Project
58 | run: msbuild $env:Solution_Name /p:Platform=$env:TargetPlatform /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:BuildMode /p:AppxBundle=$env:AppxBundle
59 | env:
60 | AppxBundle: Never
61 | BuildMode: SideloadOnly
62 | Configuration: ${{ matrix.configuration }}
63 | TargetPlatform: ${{ matrix.targetplatform }}
64 |
65 | # Upload the package: https://github.com/actions/upload-artifact
66 | - name: Upload build artifacts
67 | uses: actions/upload-artifact@v3
68 | with:
69 | name: Package-${{ matrix.configuration }}
70 | path: |
71 | OKEGui\OKEGui\bin\${{ matrix.configuration }}\
72 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OKEGui.Properties {
12 | using System;
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", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// 返回此类使用的缓存的 ResourceManager 实例。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OKEGui.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 重写当前线程的 CurrentUICulture 属性
51 | /// 重写当前线程的 CurrentUICulture 属性。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Utils/SafeProxy.cs:
--------------------------------------------------------------------------------
1 | /* This is .NET safe implementation of Crc32 algorithm.
2 | * This implementation has been found fastest from some variants, based on Robert Vazan native implementations of Crc32C
3 | * Also, it is good for x64 and for x86, so, it seems, there is no sense to do 2 different realizations.
4 | *
5 | * This algorithm is fast fork of Crc32C algorithm
6 | *
7 | * Max Vysokikh, 2016
8 | */
9 |
10 | namespace OKEGui.Utils
11 | {
12 | internal class SafeProxy
13 | {
14 | private const uint Poly = 0xedb88320u;
15 |
16 | private static readonly uint[] Table = new uint[16 * 256];
17 |
18 | static SafeProxy()
19 | {
20 | for (uint i = 0; i < 256; i++)
21 | {
22 | var res = i;
23 | for (uint t = 0; t < 16; t++)
24 | {
25 | for (uint k = 0; k < 8; k++) res = (res & 1) == 1 ? Poly ^ (res >> 1) : (res >> 1);
26 | Table[(t * 256) + i] = res;
27 | }
28 | }
29 | }
30 |
31 | public static uint Append(uint crc, byte[] input, int offset, int length)
32 | {
33 | var crcLocal = uint.MaxValue ^ crc;
34 |
35 | var table = Table;
36 | while (length >= 16)
37 | {
38 | crcLocal =
39 | table[(15 * 256) + ((crcLocal ^ input[offset + 0]) & 0xff)]
40 | ^ table[(14 * 256) + (((crcLocal >> 8) ^ input[offset + 1]) & 0xff)]
41 | ^ table[(13 * 256) + (((crcLocal >> 16) ^ input[offset + 2]) & 0xff)]
42 | ^ table[(12 * 256) + (((crcLocal >> 24) ^ input[offset + 3]) & 0xff)]
43 | ^ table[(11 * 256) + input[offset + 4]]
44 | ^ table[(10 * 256) + input[offset + 5]]
45 | ^ table[(9 * 256) + input[offset + 6]]
46 | ^ table[(8 * 256) + input[offset + 7]]
47 | ^ table[(7 * 256) + input[offset + 8]]
48 | ^ table[(6 * 256) + input[offset + 9]]
49 | ^ table[(5 * 256) + input[offset + 10]]
50 | ^ table[(4 * 256) + input[offset + 11]]
51 | ^ table[(3 * 256) + input[offset + 12]]
52 | ^ table[(2 * 256) + input[offset + 13]]
53 | ^ table[(1 * 256) + input[offset + 14]]
54 | ^ table[(0 * 256) + input[offset + 15]];
55 | offset += 16;
56 | length -= 16;
57 | }
58 |
59 | while (--length >= 0)
60 | crcLocal = table[(crcLocal ^ input[offset++]) & 0xff] ^ crcLocal >> 8;
61 | return crcLocal ^ uint.MaxValue;
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Task/TaskProfile.cs:
--------------------------------------------------------------------------------
1 | using OKEGui.Task;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | ///
6 | /// 记录一个Task所需要的所有信息。跟Json文件挂钩。
7 | ///
8 | namespace OKEGui.Model
9 | {
10 | public class TaskProfile : ICloneable
11 | {
12 | // 在json里会使用的参数
13 | public int Version;
14 | public string VSVersion; // v3+
15 | public string ProjectName;
16 | public string EncoderType;
17 | public string Encoder;
18 | public string EncoderParam;
19 | public string ContainerFormat;
20 | public double Fps;
21 | public uint FpsNum;
22 | public uint FpsDen;
23 | public List AudioTracks;
24 | public string InputScript;
25 | public List SubtitleTracks;
26 | public List InputFiles;
27 | public EpisodeConfig Config;
28 | public bool Rpc;
29 | public bool TimeCode;
30 | public bool RenumberChapters;
31 |
32 | //后续任务中填写的参数
33 | public string VideoFormat;
34 | public string AudioFormat;
35 |
36 | public string WorkingPathPrefix;
37 | public string OutputPathPrefix;
38 |
39 | public Object Clone()
40 | {
41 | TaskProfile clone = MemberwiseClone() as TaskProfile;
42 | if (AudioTracks != null)
43 | {
44 | clone.AudioTracks = new List();
45 | foreach (AudioInfo info in AudioTracks)
46 | {
47 | clone.AudioTracks.Add(info.Clone() as AudioInfo);
48 | }
49 | }
50 | if (SubtitleTracks != null)
51 | {
52 | clone.SubtitleTracks = new List();
53 | foreach (Info info in SubtitleTracks)
54 | {
55 | clone.SubtitleTracks.Add(info.Clone() as Info);
56 | }
57 | }
58 | return clone;
59 | }
60 |
61 | public override string ToString()
62 | {
63 | string str = "项目名字: " + ProjectName;
64 | str += "\n\n编码器类型: " + EncoderType;
65 | str += "\n编码器路径: " + Encoder;
66 | str += "\n编码参数: " + EncoderParam.Substring(0, Math.Min(30, EncoderParam.Length - 1)) + "......";
67 | str += "\n\n封装格式: " + ContainerFormat;
68 | str += "\n视频编码: " + VideoFormat;
69 | str += "\n视频帧率: " + (TimeCode ? "VFR" : string.Format("{0:0.000} fps", Fps));
70 | str += "\n音频编码(主音轨): " + AudioFormat;
71 | if (RenumberChapters)
72 | str += "\n章节名重编号: YES";
73 | str += "\n输入文件数量: " + InputFiles?.Count;
74 |
75 | return str;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | # Specify vpy files should be treated as Python source.
7 | *.vpy linguist-language=Python
8 |
9 | ###############################################################################
10 | # Set default behavior for command prompt diff.
11 | #
12 | # This is need for earlier builds of msysgit that does not have it on by
13 | # default for csharp files.
14 | # Note: This is only used by command line
15 | ###############################################################################
16 | #*.cs diff=csharp
17 |
18 | ###############################################################################
19 | # Set the merge driver for project and solution files
20 | #
21 | # Merging from the command prompt will add diff markers to the files if there
22 | # are conflicts (Merging from VS is not affected by the settings below, in VS
23 | # the diff markers are never inserted). Diff markers may cause the following
24 | # file extensions to fail to load in VS. An alternative would be to treat
25 | # these files as binary and thus will always conflict and require user
26 | # intervention with every merge. To do so, just uncomment the entries below
27 | ###############################################################################
28 | #*.sln merge=binary
29 | #*.csproj merge=binary
30 | #*.vbproj merge=binary
31 | #*.vcxproj merge=binary
32 | #*.vcproj merge=binary
33 | #*.dbproj merge=binary
34 | #*.fsproj merge=binary
35 | #*.lsproj merge=binary
36 | #*.wixproj merge=binary
37 | #*.modelproj merge=binary
38 | #*.sqlproj merge=binary
39 | #*.wwaproj merge=binary
40 |
41 | ###############################################################################
42 | # behavior for image files
43 | #
44 | # image files are treated as binary by default.
45 | ###############################################################################
46 | #*.jpg binary
47 | #*.png binary
48 | #*.gif binary
49 |
50 | ###############################################################################
51 | # diff behavior for common document formats
52 | #
53 | # Convert binary document formats to text before diffing them. This feature
54 | # is only available from the command line. Turn it on by uncommenting the
55 | # entries below.
56 | ###############################################################################
57 | #*.doc diff=astextplain
58 | #*.DOC diff=astextplain
59 | #*.docx diff=astextplain
60 | #*.DOCX diff=astextplain
61 | #*.dot diff=astextplain
62 | #*.DOT diff=astextplain
63 | #*.pdf diff=astextplain
64 | #*.PDF diff=astextplain
65 | #*.rtf diff=astextplain
66 | #*.RTF diff=astextplain
67 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Job/Job.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace OKEGui
5 | {
6 | public enum ProcessPriority : int { IDLE = 0, BELOW_NORMAL, NORMAL, ABOVE_NORMAL, HIGH, PARALLEL };
7 |
8 | public enum JobType
9 | {
10 | Video,
11 | Audio,
12 | VideoInfo,
13 | Mux,
14 | RpCheck
15 | }
16 |
17 | ///
18 | /// 任务信息
19 | ///
20 | public abstract class Job
21 | {
22 | #region important details
23 |
24 | public string Input;
25 | public string Output;
26 | public List FilesToDelete;
27 |
28 | #endregion important details
29 |
30 | #region JobStatus
31 |
32 | public string Status
33 | {
34 | set
35 | {
36 | if (ts != null)
37 | {
38 | ts.CurrentStatus = value;
39 | }
40 | }
41 | }
42 |
43 | public double Progress
44 | {
45 | set
46 | {
47 | if (ts != null)
48 | {
49 | ts.ProgressValue = value;
50 | }
51 | }
52 | }
53 |
54 | public string Speed
55 | {
56 | set
57 | {
58 | if (ts != null)
59 | {
60 | ts.Speed = value;
61 | }
62 | }
63 | }
64 |
65 | public TimeSpan TimeRemain
66 | {
67 | set
68 | {
69 | if (ts != null)
70 | {
71 | ts.TimeRemain = value;
72 | }
73 | }
74 | }
75 |
76 | public string BitRate
77 | {
78 | set
79 | {
80 | if (ts != null)
81 | {
82 | ts.BitRate = value;
83 | }
84 | }
85 | }
86 |
87 | protected TaskStatus ts;
88 |
89 | public void SetUpdate(TaskStatus taskStatus)
90 | {
91 | ts = taskStatus;
92 | }
93 |
94 | #endregion JobStatus
95 |
96 | #region init
97 | public Job()
98 | {
99 |
100 | }
101 |
102 | public Job(string codec) : base()
103 | {
104 | CodecString = codec.ToUpper();
105 | }
106 |
107 | #endregion init
108 |
109 | #region queue display details
110 |
111 | ///
112 | /// 使用的编码格式
113 | ///
114 | public string CodecString;
115 |
116 | public abstract JobType GetJobType();
117 |
118 | #endregion queue display details
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/OKEGui/OKEGui/Model/MediaFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using OKEGui.Model;
7 |
8 | namespace OKEGui.Model
9 | {
10 | ///
11 | /// 松散媒体文件结构类
12 | /// 程序内部抽象媒体结构,包含的轨道一般为未封装文件;
13 | /// 需要调用IMediaContainer封装保存到硬盘里。
14 | ///
15 | /// 最终轨道ID顺序:视频轨->音频轨->
16 | public class MediaFile
17 | {
18 | ///
19 | /// 返回所有轨道
20 | ///
21 | /// 通过此变量删除轨道不会产生影响。
22 | public List