Skip to content

Commit

Permalink
Merge pull request #12 from MikeMoolenaar/release/1.2.0
Browse files Browse the repository at this point in the history
Release 1.2.0
  • Loading branch information
MikeMoolenaar authored Mar 10, 2024
2 parents e323805 + 02851e8 commit 71008ab
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 57 deletions.
38 changes: 19 additions & 19 deletions MatroskaLib/MatroskaLib.Test/ByteHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace MatroskaLib.Test;
public class ByteHelperTest
{
public static TheoryData<ulong, List<byte>> TestData1 = new() {
{ 2UL, new () { 0x2 } },
{ 909UL, new () { 0x3, 0x8D } },
{ 1_800_70UL, new () { 0x2, 0xBF, 0x66 } },
{ 2UL, [0x2] },
{ 909UL, [0x3, 0x8D] },
{ 1_800_70UL, [0x2, 0xBF, 0x66] },
};
[Theory, MemberData(nameof(TestData1))]
public void ToBytesTest(ulong value, List<byte> lsBytesExpected)
Expand All @@ -19,10 +19,10 @@ public void ToBytesTest(ulong value, List<byte> lsBytesExpected)
}

public static TheoryData<List<byte>, List<byte>> TestData2 = new() {
{ new() {0x0, 0x0, 0x0, 0x96}, new () { 0x96 } },
{ new() {0x0, 0x0, 0x5, 0x0, 0x9}, new () { 0x5, 0x0, 0x9 } },
{ new() {0x9}, new () { 0x9 } },
{ new() {}, new () { } }
{ [0x0, 0x0, 0x0, 0x96], [0x96] },
{ [0x0, 0x0, 0x5, 0x0, 0x9], [0x5, 0x0, 0x9] },
{ [0x9], [0x9] },
{ [], [] }
};
[Theory, MemberData(nameof(TestData2))]
public void RemoveLeftZeroesTest(List<byte> lsBytes, List<byte> lsBytesExpected)
Expand All @@ -34,34 +34,34 @@ public void RemoveLeftZeroesTest(List<byte> lsBytes, List<byte> lsBytesExpected)

public static IEnumerable<object[]> Data()
{
yield return new object[]
{
yield return
[
new List<byte>{ 0x6B, 0x2D, 0xAE, 0xBB, 0xD7, 0x81, 0x02 },
new List<byte>{ 0x6B, 0x2D, 0xAE, 0xBE, 0xD7, 0x81, 0x02 },
4,
3
};
yield return new object[]
{
];
yield return
[
new List<byte>{ 0x81, 0x02, 0xAE, 0x42, 0x83, 0xD7, 0x81, 0x03 },
new List<byte>{ 0x81, 0x02, 0xAE, 0x42, 0x87, 0xD7, 0x81, 0x03 },
5,
4
};
yield return new object[]
{
];
yield return
[
new List<byte>{ 0x81, 0x02, 0xAE, 0x42, 0x83, 0xD7, 0x81, 0x03 },
new List<byte>{ 0x81, 0x02, 0xAE, 0x42, 0x87, 0xD7, 0x81, 0x03 },
5,
4
};
yield return new object[]
{
];
yield return
[
new List<byte>{ 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x3A, 0xD7, 81 },
new List<byte>{ 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x3D, 0xD7, 81 },
11,
3
};
];
}
[Theory, MemberData(nameof(Data))]

Expand Down
2 changes: 2 additions & 0 deletions MatroskaLib/MatroskaLib.Test/Helpers/MkvValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static class MkvValidator
private const string OutputRemoveRegex = @"(^At least one output file must be specified)|(^\[(.*)\] )";
public static void Validate(string filePath)
{
// Validate with ffmpeg
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
Expand All @@ -26,6 +27,7 @@ public static void Validate(string filePath)
throw new Exception("ffmpeg's mkv validation produced errors:" + Environment.NewLine + output);
}

// Validate with mkvalidator
p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
Expand Down
4 changes: 4 additions & 0 deletions MatroskaLib/MatroskaLib.Test/MatroskaLib.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
<Link>mkv files\TestFile5_MkvProEdit.mkv</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\TestMkvFiles\mkv files\TestFile6_SmallSeekHead.mkv">
<Link>mkv files\TestFile6_SmallSeekHead.mkv</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="mkvalidator.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down
37 changes: 25 additions & 12 deletions MatroskaLib/MatroskaLib.Test/MatroskaLibTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ namespace MatroskaLib.Test;
* Only first void with checksum elements
* MkvProEdit
* Only second void and may need to change length of that void
* TestFile6_SmallSeekHead.mkv
* SeekHead size of 2, which caused an exception (see github issue #10).
* Do that this is not a valid mkv file accordant to MkValidator.
*/
public class MatroskaLibTest
{
Expand All @@ -22,7 +25,7 @@ public class MatroskaLibTest
[InlineData("mkv files/TestFile1_MkvToolNix.mkv")]
public void ReadTestFile1(string file)
{
string[] filePaths = { file };
string[] filePaths = [file];

List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(filePaths);
List<Track> lsTracks = lsMkvFiles[0].tracks;
Expand All @@ -40,12 +43,12 @@ public void ReadTestFile1(string file)
public void WriteTestFile1(string file)
{
File.Copy(file, TestFilePath, true);
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
lsMkvFiles[0].tracks[0].flagDefault = false;
lsMkvFiles[0].tracks[2].flagDefault = false;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
List<Track> lsTracks = lsMkvFiles[0].tracks;

lsTracks.Should().HaveCount(3);
Expand All @@ -59,7 +62,7 @@ public void WriteTestFile1(string file)
[InlineData("mkv files/TestFile2_MkvToolNix.mkv")]
public void ReadTestFile2(string file)
{
string[] filePaths = { file };
string[] filePaths = [file];

List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(filePaths);
List<Track> lsTracks = lsMkvFiles[0].tracks;
Expand All @@ -79,12 +82,12 @@ public void ReadTestFile2(string file)
public void WriteTestFile2(string file)
{
File.Copy(file, TestFilePath, true);
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
lsMkvFiles[0].tracks[1].flagDefault = true;
lsMkvFiles[0].tracks[3].flagDefault = true;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
List<Track> lsTracks = lsMkvFiles[0].tracks;

lsTracks.Should().HaveCount(5);
Expand All @@ -100,7 +103,7 @@ public void WriteTestFile2(string file)
[InlineData("mkv files/TestFile3_HandBrake.mkv")]
public void ReadTestFile3(string file)
{
string[] filePaths = { file };
string[] filePaths = [file];

List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(filePaths);
List<Track> lsTracks = lsMkvFiles[0].tracks;
Expand All @@ -119,12 +122,12 @@ public void ReadTestFile3(string file)
public void WriteTestFile3(string file)
{
File.Copy(file, TestFilePath, true);
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
lsMkvFiles[0].tracks[1].flagDefault = true;
lsMkvFiles[0].tracks[3].flagDefault = true;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
List<Track> lsTracks = lsMkvFiles[0].tracks;

lsTracks.Should().HaveCount(4);
Expand All @@ -140,7 +143,7 @@ public void WriteTestFile3(string file)
[InlineData("mkv files/TestFile5_MkvProEdit.mkv")]
public void ReadTestFile4(string file)
{
string[] filePaths = { file };
string[] filePaths = [file];

List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(filePaths);
List<Track> lsTracks = lsMkvFiles[0].tracks;
Expand All @@ -158,12 +161,12 @@ public void ReadTestFile4(string file)
public void WriteTestFile4(string file)
{
File.Copy(file, TestFilePath, true);
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
lsMkvFiles[0].tracks[0].flagDefault = false;
lsMkvFiles[0].tracks[2].flagDefault = false;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
lsMkvFiles = MatroskaReader.ReadMkvFiles(new[] { TestFilePath });
lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
List<Track> lsTracks = lsMkvFiles[0].tracks;

lsTracks.Should().HaveCount(3);
Expand All @@ -172,4 +175,14 @@ public void WriteTestFile4(string file)
lsTracks[2].Should().BeEquivalentTo(new { flagDefault = false, flagForced = false, language = "jpn", type = TrackTypeEnum.audio });
MkvValidator.Validate(TestFilePath);
}

[Fact]
public void FileWithSeekHeadSizeOf2ShouldNotThrow()
{
File.Copy("mkv files/TestFile6_SmallSeekHead.mkv", TestFilePath, true);
List<MkvFile> lsMkvFiles = MatroskaReader.ReadMkvFiles([TestFilePath]);
lsMkvFiles[0].tracks[0].flagDefault = false;

MatroskaWriter.WriteMkvFile(lsMkvFiles[0]);
}
}
3 changes: 2 additions & 1 deletion MatroskaLib/MatroskaLib/Helpers/ByteHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public static void ChangeLength(List<byte> lsBytes, int position, List<byte> lsL

// Convert new length to bytes and strip bytes
List<byte> lsNewBytes = ToBytes(ret);
if (lsNewBytes.Count != lsLengthBytes.Count) throw new Exception("New length doesn't fit into existing length element");
if (lsNewBytes.Count != lsLengthBytes.Count)
throw new InvalidOperationException($"New length bytes are not the same length as the old ones. Old length: {lsLengthBytes.Count}, new length: {lsNewBytes.Count}");

// Replace old length with new length bytes
lsBytes.RemoveRange(position, lsNewBytes.Count);
Expand Down
2 changes: 1 addition & 1 deletion MatroskaLib/MatroskaLib/Helpers/CustomExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static void LocateElement(this EbmlReader reader, ulong descriptor)
}
}

throw new Exception($"Cannot find descriptor 0x{descriptor:X}");
throw new InvalidOperationException($"Cannot find descriptor 0x{descriptor:X}");
}
}
}
10 changes: 7 additions & 3 deletions MatroskaLib/MatroskaLib/MatroskaWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ private static void _ChangeVoidLengthAndHeaders(List<Seek> seekList, int? seekHe
foreach (var s in seekList.Where(s =>
s.seekId is MatroskaElements.Tracks or MatroskaElements.SegmentInfo))
{
int desiredLength = Convert.ToInt32(lsBytes[s.seekPositionByteNumber - 1] - 0x80);
List<byte> lsNewBytes = ByteHelper.ToBytes(s.seekPosition - (ulong)offset);
if (desiredLength != lsNewBytes.Count)
throw new Exception("New seekposition doesn't fit into existing element");
if (lsNewBytes.Count > s.elementLength)
throw new InvalidOperationException($"New seekPosition bytes are bigger than the old one. Trying to fit {lsNewBytes.Count} bytes into {s.elementLength} bytes");
if (lsNewBytes.Count < s.elementLength)
{
// The new seekPosition is smaller than the old one, add padding
lsNewBytes.AddRange(new byte[s.elementLength - lsNewBytes.Count]);
}

lsBytes.RemoveRange(s.seekPositionByteNumber, lsNewBytes.Count);
lsBytes.InsertRange(s.seekPositionByteNumber, lsNewBytes);
Expand Down
7 changes: 4 additions & 3 deletions MatroskaLib/MatroskaLib/MkvFilesContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ namespace MatroskaLib;
public class MkvFilesContainer
{
public readonly List<MkvFile> MkvFiles = new();
public readonly List<MkvFile> MkFilesRejected = new();
public readonly List<(MkvFile file, string error)> MkFilesRejected = new();

public MkvFilesContainer(string[] filePaths)
{
var files = MatroskaReader.ReadMkvFiles(filePaths);
MkvFiles.Add(files[0]);
for (int i = 1; i < files.Count; i++)
{
if (files[0].CompareTo(files[i]) == 0)
string? error = files[0].CompareToGetError(files[i]);
if (error is null)
MkvFiles.Add(files[i]);
else
MkFilesRejected.Add(files[i]);
MkFilesRejected.Add((files[i], error));
}
}

Expand Down
15 changes: 10 additions & 5 deletions MatroskaLib/MatroskaLib/Types/MkvFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace MatroskaLib.Types;

public record MkvFile : IComparable<MkvFile>
public record MkvFile
{
public required string filePath { get; init; }
public required List<Track> tracks { get; init; }
Expand All @@ -18,7 +18,7 @@ public record MkvFile : IComparable<MkvFile>
public required int tracksPosition { get; init; }
public required int beginHeaderPosition { get; init; }

public int CompareTo(MkvFile? other)
public string? CompareToGetError(MkvFile? other)
{
if (other is null)
throw new ArgumentNullException(nameof(other));
Expand All @@ -27,11 +27,16 @@ public int CompareTo(MkvFile? other)
{
var track = tracks[i];
var trackOther = other.tracks.ElementAtOrDefault(i);
if (trackOther is null || track.number != trackOther.number || track.language != trackOther.language)
return -1;

if (trackOther is null)
return $"Track at index {i} does not exist, expected {track.type} with language {track.language}.";
if (track.number != trackOther.number)
return $"Track number at index {i} does not match. Expected {track.number}, got {trackOther.number}.";
if (track.language != trackOther.language)
return $"Track language at index {i} does not match. Expected {track.language}, got {trackOther.language}.";
}

return 0;
return null;
}

public override string ToString() =>
Expand Down
2 changes: 2 additions & 0 deletions MatroskaLib/MatroskaLib/Types/Seek.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class Seek
public ulong seekId { get; private set; }
public ulong seekPosition { get; private set; }
public int seekPositionByteNumber { get; private set; }
public int elementLength { get; private set; }

public Seek(EbmlReader reader) =>
_reader = reader;
Expand All @@ -23,6 +24,7 @@ public void ApplyElement(FileStream fileStream)
{
seekPositionByteNumber = (int)fileStream.Position;
seekPosition = _reader.ReadUInt();
elementLength = (int)_reader.ElementSize;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleIdentifier</key>
<string>com.mikemoolenaar.MkvDefaultTrackChanger</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.2.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
<key>CFBundleDevelopmentRegion</key>
Expand Down
20 changes: 13 additions & 7 deletions MkvDefaultTrackChanger/MkvDefaultTrackChanger/ErrorForm.xeto
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
xmlns="http://schema.picoe.ca/eto.forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MkvDefaultTrackChanger"
MinimumSize="370,530"
MinimumSize="370,570"
Size="370,530"
Padding="10"
>
<StackLayout Spacing="20" HorizontalContentAlignment="Center">
<Label x:Name="lblTitle" Text="An error occured!"></Label>
<LinkButton Text="Create issue" Click="BtnCreateIssueClicked"></LinkButton>
<DynamicLayout Spacing="0,15" Padding="15,5,15,0">
<StackLayout Spacing="5" HorizontalContentAlignment="Center">
<Label x:Name="lblTitle" Text="An error occured!"></Label>
<LinkButton Text="Create issue" Click="BtnCreateIssueClicked"></LinkButton>
</StackLayout>
<Label Text="You can report this error by creating an issue on GitHub, please copy and paste the below box-contained text in the issue description."></Label>
<Label Text="DISCLAIMER: The text includes basic info about your OS, tracks of the MKV file and about where the error occured in the codebase. It does not include the filename(s). By creating an issue you consent to sharing the below text publicly on the internet."></Label>

<TextArea Width="320" Height="150" Wrap="false" x:Name="txaExceptionMessage" ReadOnly="true"></TextArea>
<DynamicLayout Spacing="0,10">
<TextArea Wrap="false" Height="200" x:Name="txaExceptionMessage" ReadOnly="true"></TextArea>
</DynamicLayout>

<Button x:Name="btnClose" Click="BtnCloseClicked">Close</Button>
</StackLayout>
<StackLayout Spacing="5" HorizontalContentAlignment="Center">
<Button x:Name="btnClose" Click="BtnCloseClicked">Close</Button>
</StackLayout>
</DynamicLayout>
</Form>
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,15 @@ private void LoadFiles()
mkvContainer = new MkvFilesContainer(filePaths);
if (mkvContainer.MkFilesRejected.Count > 0)
{
var sourceFile = Path.GetFileName(filePaths[0]);

string rejectedFiles = Environment.NewLine + Environment.NewLine;
mkvContainer.MkFilesRejected.ForEach((x) =>
{
rejectedFiles += Path.GetFileName(x.filePath) + Environment.NewLine + Environment.NewLine;
rejectedFiles += $"- {Path.GetFileName(x.file.filePath)}: {x.error} {Environment.NewLine}{Environment.NewLine}";
});
MessageBox.Show("The following files were rejected: " + rejectedFiles, MessageBoxType.Warning);
MessageBox.Show($"The following files have different tracks or the order is different than {sourceFile}: {rejectedFiles}These files cannot be processed.",
MessageBoxType.Warning);
}

var lsSubtitleTracks = mkvContainer.GetSubtitleTracks();
Expand Down
Loading

0 comments on commit 71008ab

Please sign in to comment.