Skip to content

Commit

Permalink
Added workaround for problem with overlaid subtitles in MKV.
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcclive committed Sep 3, 2019
1 parent a4a3040 commit 5bbad73
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
51 changes: 51 additions & 0 deletions Tricycle.Media.FFmpeg.Tests/FFmpegArgumentGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,57 @@ public void GeneratesArgumentsForTonemapJob()
Assert.AreEqual(expected, actual);
}

[TestMethod]
public void GeneratesArgumentsForMkvSubtitleJob()
{
var job = new TranscodeJob()
{
Format = ContainerFormat.Mkv,
OutputFileName = "output.mkv",
SourceInfo = new MediaInfo()
{
FileName = "input.m4v",
Duration = new TimeSpan(0, 1, 42, 37, 610),
Streams = new StreamInfo[]
{
new VideoStreamInfo()
{
Index = 0,
Dimensions = new Dimensions(3840, 2160),
DynamicRange = DynamicRange.Standard
},
new StreamInfo()
{
Index = 1,
StreamType = StreamType.Subtitle
}
}
},
Streams = new OutputStream[]
{
new VideoOutputStream()
{
SourceStreamIndex = 0,
Format = VideoFormat.Avc,
DynamicRange = DynamicRange.Standard,
Quality = 20
}
},
Subtitles = new SubtitlesConfig()
{
SourceStreamIndex = 1
}
};

var actual = _generator.GenerateArguments(job);
string expected = "-hide_banner -y -canvas_size 3840x2160 -i \"input.m4v\" -f matroska -t 1:42:37.610 " +
"-map 0:0 -c:v:0 libx264 -preset medium -crf 20 " +
"-filter_complex [0:1][0:0]'scale2ref[sub][ref];[ref][sub]overlay' " +
"\"output.mkv\"";

Assert.AreEqual(expected, actual);
}

[TestMethod]
public void GenerateArgumentsRespectsConfig()
{
Expand Down
20 changes: 19 additions & 1 deletion Tricycle.Media.FFmpeg/FFmpegArgumentGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ public string GenerateArguments(TranscodeJob job)
AppendFormat(argBuilder, job.Format);
AppendDelimiter(argBuilder);

// This is a workaround for subtitle overlays with MKV reporting an incorrect duration
if (job.Format == ContainerFormat.Mkv && subtitlesIndex.HasValue)
{
AppendDuration(argBuilder, job.SourceInfo.Duration);
AppendDelimiter(argBuilder);
}

try
{
AppendStreamMap(argBuilder, job.SourceInfo, job.Streams, subtitlesIndex);
Expand Down Expand Up @@ -197,6 +204,11 @@ void AppendFormat(StringBuilder builder, ContainerFormat format)
builder.Append($"-f {container}");
}

void AppendDuration(StringBuilder builder, TimeSpan duration)
{
builder.Append($"-t {duration:h':'mm':'ss'.'fff}");
}

void AppendStreamMap(StringBuilder builder,
MediaInfo sourceInfo,
IList<OutputStream> streams,
Expand Down Expand Up @@ -404,6 +416,8 @@ void AppendVideoStream(StringBuilder builder,
AppendVideoOverlayFilter(filterBuilder);
}

bool setSampleAspectRatio = false;

if ((outputStream.CropParameters != null) &&
((outputStream.CropParameters.Size.Width < sourceStream.Dimensions.Width) ||
(outputStream.CropParameters.Size.Height < sourceStream.Dimensions.Height)))
Expand All @@ -414,6 +428,8 @@ void AppendVideoStream(StringBuilder builder,
}

AppendVideoCropFilter(filterBuilder, outputStream.CropParameters);

setSampleAspectRatio = true;
}

if (outputStream.ScaledDimensions.HasValue &&
Expand All @@ -425,9 +441,11 @@ void AppendVideoStream(StringBuilder builder,
}

AppendVideoScaleFilter(filterBuilder, outputStream.ScaledDimensions.Value);

setSampleAspectRatio = true;
}

if (filterBuilder.Length > 0)
if (setSampleAspectRatio)
{
AppendListDelimiter(filterBuilder);
AppendVideoSampleAspectRatioFilter(filterBuilder);
Expand Down

0 comments on commit 5bbad73

Please sign in to comment.