diff --git a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
index e113521ecf..39d1c32202 100644
--- a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
+++ b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace MediaBrowser.Controller.MediaEncoding
{
@@ -24,7 +23,18 @@ namespace MediaBrowser.Controller.MediaEncoding
/// Gets or sets the chapters.
///
/// The chapters.
- public List Chapters { get; set; }
+ public MediaChapter[] Chapters { get; set; }
+ }
+
+ public class MediaChapter
+ {
+ public int id { get; set; }
+ public string time_base { get; set; }
+ public long start { get; set; }
+ public string start_time { get; set; }
+ public long end { get; set; }
+ public string end_time { get; set; }
+ public Dictionary tags { get; set; }
}
///
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
index a27fa057ca..75a9d9c36a 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
@@ -50,12 +50,16 @@ namespace MediaBrowser.Providers.MediaInfo
return ItemUpdateType.MetadataImport;
}
+ private const string SchemaVersion = "1";
+
private async Task GetMediaInfo(BaseItem item, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var idString = item.Id.ToString("N");
- var cachePath = Path.Combine(_appPaths.CachePath, "ffprobe-audio", idString.Substring(0, 2), idString, "v" + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
+ var cachePath = Path.Combine(_appPaths.CachePath,
+ "ffprobe-audio",
+ idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
try
{
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index d516a8221f..58fe7f66d4 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -107,6 +107,8 @@ namespace MediaBrowser.Providers.MediaInfo
return ItemUpdateType.MetadataImport;
}
+ private const string SchemaVersion = "1";
+
private async Task GetMediaInfo(BaseItem item, IIsoMount isoMount, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -114,7 +116,9 @@ namespace MediaBrowser.Providers.MediaInfo
cancellationToken.ThrowIfCancellationRequested();
var idString = item.Id.ToString("N");
- var cachePath = Path.Combine(_appPaths.CachePath, "ffprobe-video", idString.Substring(0, 2), idString, "v" + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
+ var cachePath = Path.Combine(_appPaths.CachePath,
+ "ffprobe-video",
+ idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
try
{
@@ -161,7 +165,8 @@ namespace MediaBrowser.Providers.MediaInfo
var mediaStreams = MediaEncoderHelpers.GetMediaInfo(data).MediaStreams;
- var chapters = data.Chapters ?? new List();
+ var mediaChapters = (data.Chapters ?? new MediaChapter[] { }).ToList();
+ var chapters = mediaChapters.Select(GetChapterInfo).ToList();
if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
{
@@ -200,6 +205,24 @@ namespace MediaBrowser.Providers.MediaInfo
await _itemRepo.SaveChapters(video.Id, chapters, cancellationToken).ConfigureAwait(false);
}
+ private ChapterInfo GetChapterInfo(MediaChapter chapter)
+ {
+ var info = new ChapterInfo();
+
+ if (chapter.tags != null)
+ {
+ string name;
+ if (chapter.tags.TryGetValue("title", out name))
+ {
+ info.Name = name;
+ }
+ }
+
+ info.StartPositionTicks = chapter.start/100;
+
+ return info;
+ }
+
private void FetchBdInfo(BaseItem item, List chapters, List mediaStreams, BlurayDiscInfo blurayInfo)
{
var video = (Video)item;
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
index fddba76626..c646d80bce 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
@@ -175,6 +175,10 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
string probeSizeArgument,
CancellationToken cancellationToken)
{
+ var args = extractChapters
+ ? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
+ : "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format";
+
var process = new Process
{
StartInfo = new ProcessStartInfo
@@ -186,8 +190,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = FFProbePath,
- Arguments = string.Format(
- "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format",
+ Arguments = string.Format(args,
probeSizeArgument, inputPath).Trim(),
WindowStyle = ProcessWindowStyle.Hidden,
@@ -204,7 +207,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
InternalMediaInfoResult result;
- string standardError = null;
try
{
@@ -221,24 +223,9 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
try
{
- Task standardErrorReadTask = null;
-
- // MUST read both stdout and stderr asynchronously or a deadlock may occurr
- if (extractChapters)
- {
- standardErrorReadTask = process.StandardError.ReadToEndAsync();
- }
- else
- {
- process.BeginErrorReadLine();
- }
+ process.BeginErrorReadLine();
result = _jsonSerializer.DeserializeFromStream(process.StandardOutput.BaseStream);
-
- if (extractChapters)
- {
- standardError = await standardErrorReadTask.ConfigureAwait(false);
- }
}
catch
{
@@ -282,11 +269,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
}
- if (extractChapters && !string.IsNullOrEmpty(standardError))
- {
- AddChapters(result, standardError);
- }
-
return result;
}
@@ -295,66 +277,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
///
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
- ///
- /// Adds the chapters.
- ///
- /// The result.
- /// The standard error.
- private void AddChapters(InternalMediaInfoResult result, string standardError)
- {
- var lines = standardError.Split('\n').Select(l => l.TrimStart());
-
- var chapters = new List();
-
- ChapterInfo lastChapter = null;
-
- foreach (var line in lines)
- {
- if (line.StartsWith("Chapter", StringComparison.OrdinalIgnoreCase))
- {
- // Example:
- // Chapter #0.2: start 400.534, end 4565.435
- const string srch = "start ";
- var start = line.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
-
- if (start == -1)
- {
- continue;
- }
-
- var subString = line.Substring(start + srch.Length);
- subString = subString.Substring(0, subString.IndexOf(','));
-
- double seconds;
-
- if (double.TryParse(subString, NumberStyles.Any, UsCulture, out seconds))
- {
- lastChapter = new ChapterInfo
- {
- StartPositionTicks = TimeSpan.FromSeconds(seconds).Ticks
- };
-
- chapters.Add(lastChapter);
- }
- }
-
- else if (line.StartsWith("title", StringComparison.OrdinalIgnoreCase))
- {
- if (lastChapter != null && string.IsNullOrEmpty(lastChapter.Name))
- {
- var index = line.IndexOf(':');
-
- if (index != -1)
- {
- lastChapter.Name = line.Substring(index + 1).Trim().TrimEnd('\r');
- }
- }
- }
- }
-
- result.Chapters = chapters;
- }
-
///
/// Processes the exited.
///