|
@@ -0,0 +1,166 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Diagnostics;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace WechatPCMsgBakTool.Helpers
|
|
|
+{
|
|
|
+ public class ToolsHelper
|
|
|
+ {
|
|
|
+ public static TaskFactory factory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(10));
|
|
|
+ public static string DecodeVoice(string source,string pcm,string to)
|
|
|
+ {
|
|
|
+ string ffmpeg = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tools", "ffmpeg.exe");
|
|
|
+ string silk_decoder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tools", "silk_v3_decoder.exe");
|
|
|
+
|
|
|
+ Task task = factory.StartNew(() =>
|
|
|
+ {
|
|
|
+ Process silk = new Process();
|
|
|
+ silk.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
|
+ silk.StartInfo.UseShellExecute = false;
|
|
|
+ silk.StartInfo.CreateNoWindow = true;
|
|
|
+ silk.StartInfo.FileName = silk_decoder;
|
|
|
+ silk.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\"", source, pcm);
|
|
|
+ silk.Start();
|
|
|
+ silk.WaitForExit();
|
|
|
+
|
|
|
+ if (File.Exists(pcm))
|
|
|
+ {
|
|
|
+ Process ff = new Process();
|
|
|
+ ff.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
|
+ ff.StartInfo.UseShellExecute= false;
|
|
|
+ ff.StartInfo.CreateNoWindow = true;
|
|
|
+ ff.StartInfo.FileName = ffmpeg;
|
|
|
+ ff.StartInfo.Arguments = string.Format(" -y -f s16le -ar 24000 -ac 1 -i \"{0}\" -ar 24000 -b:a 320k \"{1}\"", pcm, to);
|
|
|
+ ff.Start();
|
|
|
+ ff.WaitForExit();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
|
|
|
+ {
|
|
|
+
|
|
|
+ [ThreadStatic]
|
|
|
+ private static bool _currentThreadIsProcessingItems;
|
|
|
+
|
|
|
+
|
|
|
+ private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
|
|
|
+
|
|
|
+
|
|
|
+ private readonly int _maxDegreeOfParallelism;
|
|
|
+
|
|
|
+
|
|
|
+ private int _delegatesQueuedOrRunning = 0;
|
|
|
+
|
|
|
+
|
|
|
+ public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
|
|
|
+ {
|
|
|
+ if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
|
|
|
+ _maxDegreeOfParallelism = maxDegreeOfParallelism;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected sealed override void QueueTask(Task task)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ lock (_tasks)
|
|
|
+ {
|
|
|
+ _tasks.AddLast(task);
|
|
|
+ if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
|
|
|
+ {
|
|
|
+ ++_delegatesQueuedOrRunning;
|
|
|
+ NotifyThreadPoolOfPendingWork();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void NotifyThreadPoolOfPendingWork()
|
|
|
+ {
|
|
|
+ ThreadPool.UnsafeQueueUserWorkItem(_ =>
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ _currentThreadIsProcessingItems = true;
|
|
|
+ try
|
|
|
+ {
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ Task item;
|
|
|
+ lock (_tasks)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ if (_tasks.Count == 0)
|
|
|
+ {
|
|
|
+ --_delegatesQueuedOrRunning;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ item = _tasks.First.Value;
|
|
|
+ _tasks.RemoveFirst();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ base.TryExecuteTask(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ finally { _currentThreadIsProcessingItems = false; }
|
|
|
+ }, null);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (!_currentThreadIsProcessingItems) return false;
|
|
|
+
|
|
|
+
|
|
|
+ if (taskWasPreviouslyQueued)
|
|
|
+
|
|
|
+ if (TryDequeue(task))
|
|
|
+ return base.TryExecuteTask(task);
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+ else
|
|
|
+ return base.TryExecuteTask(task);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected sealed override bool TryDequeue(Task task)
|
|
|
+ {
|
|
|
+ lock (_tasks) return _tasks.Remove(task);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
|
|
|
+
|
|
|
+
|
|
|
+ protected sealed override IEnumerable<Task> GetScheduledTasks()
|
|
|
+ {
|
|
|
+ bool lockTaken = false;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Monitor.TryEnter(_tasks, ref lockTaken);
|
|
|
+ if (lockTaken) return _tasks;
|
|
|
+ else throw new NotSupportedException();
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ if (lockTaken) Monitor.Exit(_tasks);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|