aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
diff options
context:
space:
mode:
authorAndrew Rabert <ar@nullsum.net>2018-12-27 18:27:57 -0500
committerAndrew Rabert <ar@nullsum.net>2018-12-27 18:27:57 -0500
commita86b71899ec52c44ddc6c3018e8cc5e9d7ff4d62 (patch)
treea74f6ea4a8abfa1664a605d31d48bc38245ccf58 /MediaBrowser.Controller/MediaEncoding/JobLogger.cs
parent9bac3ac616b01f67db98381feb09d34ebe821f9a (diff)
Add GPL modules
Diffstat (limited to 'MediaBrowser.Controller/MediaEncoding/JobLogger.cs')
-rw-r--r--MediaBrowser.Controller/MediaEncoding/JobLogger.cs149
1 files changed, 149 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/MediaEncoding/JobLogger.cs b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
new file mode 100644
index 000000000..5f3f79d77
--- /dev/null
+++ b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs
@@ -0,0 +1,149 @@
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace MediaBrowser.Controller.MediaEncoding
+{
+ public class JobLogger
+ {
+ private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+ private readonly ILogger _logger;
+
+ public JobLogger(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public async void StartStreamingLog(EncodingJobInfo state, Stream source, Stream target)
+ {
+ try
+ {
+ using (var reader = new StreamReader(source))
+ {
+ while (!reader.EndOfStream)
+ {
+ var line = await reader.ReadLineAsync().ConfigureAwait(false);
+
+ ParseLogLine(line, state);
+
+ var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
+
+ await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+ await target.FlushAsync().ConfigureAwait(false);
+ }
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ // Don't spam the log. This doesn't seem to throw in windows, but sometimes under linux
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error reading ffmpeg log", ex);
+ }
+ }
+
+ private void ParseLogLine(string line, EncodingJobInfo state)
+ {
+ float? framerate = null;
+ double? percent = null;
+ TimeSpan? transcodingPosition = null;
+ long? bytesTranscoded = null;
+ int? bitRate = null;
+
+ var parts = line.Split(' ');
+
+ var totalMs = state.RunTimeTicks.HasValue
+ ? TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalMilliseconds
+ : 0;
+
+ var startMs = state.BaseRequest.StartTimeTicks.HasValue
+ ? TimeSpan.FromTicks(state.BaseRequest.StartTimeTicks.Value).TotalMilliseconds
+ : 0;
+
+ for (var i = 0; i < parts.Length; i++)
+ {
+ var part = parts[i];
+
+ if (string.Equals(part, "fps=", StringComparison.OrdinalIgnoreCase) &&
+ (i + 1 < parts.Length))
+ {
+ var rate = parts[i + 1];
+ float val;
+
+ if (float.TryParse(rate, NumberStyles.Any, _usCulture, out val))
+ {
+ framerate = val;
+ }
+ }
+ else if (state.RunTimeTicks.HasValue &&
+ part.StartsWith("time=", StringComparison.OrdinalIgnoreCase))
+ {
+ var time = part.Split(new[] { '=' }, 2).Last();
+ TimeSpan val;
+
+ if (TimeSpan.TryParse(time, _usCulture, out val))
+ {
+ var currentMs = startMs + val.TotalMilliseconds;
+
+ var percentVal = currentMs / totalMs;
+ percent = 100 * percentVal;
+
+ transcodingPosition = val;
+ }
+ }
+ else if (part.StartsWith("size=", StringComparison.OrdinalIgnoreCase))
+ {
+ var size = part.Split(new[] { '=' }, 2).Last();
+
+ int? scale = null;
+ if (size.IndexOf("kb", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ scale = 1024;
+ size = size.Replace("kb", string.Empty, StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (scale.HasValue)
+ {
+ long val;
+
+ if (long.TryParse(size, NumberStyles.Any, _usCulture, out val))
+ {
+ bytesTranscoded = val * scale.Value;
+ }
+ }
+ }
+ else if (part.StartsWith("bitrate=", StringComparison.OrdinalIgnoreCase))
+ {
+ var rate = part.Split(new[] { '=' }, 2).Last();
+
+ int? scale = null;
+ if (rate.IndexOf("kbits/s", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ scale = 1024;
+ rate = rate.Replace("kbits/s", string.Empty, StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (scale.HasValue)
+ {
+ float val;
+
+ if (float.TryParse(rate, NumberStyles.Any, _usCulture, out val))
+ {
+ bitRate = (int)Math.Ceiling(val * scale.Value);
+ }
+ }
+ }
+ }
+
+ if (framerate.HasValue || percent.HasValue)
+ {
+ state.ReportTranscodingProgress(transcodingPosition, 0, percent, 0, bitRate);
+ }
+ }
+ }
+}