diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs
index 6c6aa3b3..5115bb58 100644
--- a/AaxDecrypter/AaxcDownloadConverter.cs
+++ b/AaxDecrypter/AaxcDownloadConverter.cs
@@ -168,72 +168,19 @@ namespace AaxDecrypter
return aaxcProcesser.Succeeded;
}
- private void AaxcProcesser_ProgressUpdate(object sender, TimeSpan e)
+ private void AaxcProcesser_ProgressUpdate(object sender, AaxcProcessUpdate e)
{
- double averageRate = getAverageProcessRate(e);
- double remainingSecsToProcess = (aaxcTagLib.Properties.Duration - e).TotalSeconds;
- double estTimeRemaining = remainingSecsToProcess / averageRate;
+ double remainingSecsToProcess = (aaxcTagLib.Properties.Duration - e.ProcessPosition).TotalSeconds;
+ double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed;
if (double.IsNormal(estTimeRemaining))
- DecryptTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining));
+ DecryptTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining));
- double progressPercent = 100 * e.TotalSeconds / aaxcTagLib.Properties.Duration.TotalSeconds;
+ double progressPercent = 100 * e.ProcessPosition.TotalSeconds / aaxcTagLib.Properties.Duration.TotalSeconds;
DecryptProgressUpdate?.Invoke(this, (int)progressPercent);
}
- ///
- /// Calculates the average processing rate based on the last 2 to samples.
- ///
- /// Position in the audio file last processed
- /// The average processing rate, in book_duration_seconds / second.
- private double getAverageProcessRate(TimeSpan lastProcessedPosition)
- {
- streamPositions.Enqueue(new StreamPosition
- {
- ProcessPosition = lastProcessedPosition,
- EventTime = DateTime.Now,
- });
-
- if (streamPositions.Count < 2)
- return double.PositiveInfinity;
-
- //Calculate the harmonic mean of the last 2 to MAX_NUM_AVERAGE progress updates
- //Units are Book_Duration_Seconds / second
-
- var lastPos = streamPositions.Count > MAX_NUM_AVERAGE ? streamPositions.Dequeue() : null;
-
- double harmonicDenominator = 0;
- int harmonicNumerator = 0;
-
- foreach (var pos in streamPositions)
- {
- if (lastPos is null)
- {
- lastPos = pos;
- continue;
- }
- double dP = (pos.ProcessPosition - lastPos.ProcessPosition).TotalSeconds;
- double dT = (pos.EventTime - lastPos.EventTime).TotalSeconds;
-
- harmonicDenominator += dT / dP;
- harmonicNumerator++;
- lastPos = pos;
- }
-
- double harmonicMean = harmonicNumerator / harmonicDenominator;
- return harmonicMean;
- }
-
- private const int MAX_NUM_AVERAGE = 15;
- private class StreamPosition
- {
- public TimeSpan ProcessPosition { get; set; }
- public DateTime EventTime { get; set; }
- }
-
- private Queue streamPositions = new Queue();
-
///
/// Copy all aacx metadata to m4b file, including cover art.
///
diff --git a/AaxDecrypter/FFMpegAaxcProcesser.cs b/AaxDecrypter/FFMpegAaxcProcesser.cs
index 89734dcf..6c144a3f 100644
--- a/AaxDecrypter/FFMpegAaxcProcesser.cs
+++ b/AaxDecrypter/FFMpegAaxcProcesser.cs
@@ -7,13 +7,25 @@ using System.Threading.Tasks;
namespace AaxDecrypter
{
+ class AaxcProcessUpdate
+ {
+ public AaxcProcessUpdate(TimeSpan position, double speed)
+ {
+ ProcessPosition = position;
+ ProcessSpeed = speed;
+ EventTime = DateTime.Now;
+ }
+ public TimeSpan ProcessPosition { get; }
+ public double ProcessSpeed { get; }
+ public DateTime EventTime { get; }
+ }
///
/// Download audible aaxc, decrypt, and remux with chapters.
///
class FFMpegAaxcProcesser
{
- public event EventHandler ProgressUpdate;
+ public event EventHandler ProgressUpdate;
public string FFMpegPath { get; }
public DownloadLicense DownloadLicense { get; }
public bool IsRunning { get; private set; }
@@ -24,7 +36,7 @@ namespace AaxDecrypter
private StringBuilder remuxerError = new StringBuilder();
private StringBuilder downloaderError = new StringBuilder();
- private static Regex processedTimeRegex = new Regex("time=(\\d{2}):(\\d{2}):(\\d{2}).\\d{2}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ private static Regex processedTimeRegex = new Regex("time=(\\d{2}):(\\d{2}):(\\d{2}).\\d{2}.*speed=\\s{0,1}([0-9]*[.]?[0-9]+)(?:e\\+([0-9]+)){0,1}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private Process downloader;
private Process remuxer;
@@ -115,6 +127,7 @@ namespace AaxDecrypter
if (processedTimeRegex.IsMatch(e.Data))
{
//get timestamp of of last processed audio stream position
+ //and processing speed
var match = processedTimeRegex.Match(e.Data);
int hours = int.Parse(match.Groups[1].Value);
@@ -123,7 +136,11 @@ namespace AaxDecrypter
var position = new TimeSpan(hours, minutes, seconds);
- ProgressUpdate?.Invoke(sender, position);
+ double speed = double.Parse(match.Groups[4].Value);
+ int exp = match.Groups[5].Success ? int.Parse(match.Groups[5].Value) : 0;
+ speed *= Math.Pow(10, exp);
+
+ ProgressUpdate?.Invoke(this, new AaxcProcessUpdate(position, speed));
}
if (e.Data.Contains("aac bitstream error"))