Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new ebml.xml + ebml_matroska.xml file (July 2023) #17

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<Version>0.0.9</Version>
<Version>0.0.11-preview-01</Version>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<LangVersion>11.0</LangVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/StefH/Matroska</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
Expand Down
14 changes: 14 additions & 0 deletions Matroska Solution.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MatroskaDemuxer", "examples
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Span.ReaderWriter", "..\Span.ReaderWriter\src\Span.ReaderWriter\Span.ReaderWriter.csproj", "{2FBBA506-46CC-4BB1-BE69-37D1090E6999}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xtremegaida.DataStructures", "examples\Xtremegaida.DataStructures\Xtremegaida.DataStructures.csproj", "{57939DE5-D42C-4159-BCC4-D3749B01F7EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaContainers.Matroska", "examples\MediaContainers.Matroska\MediaContainers.Matroska.csproj", "{85DAF737-65D4-4E6C-A105-90392AFCE666}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -55,6 +59,14 @@ Global
{2FBBA506-46CC-4BB1-BE69-37D1090E6999}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FBBA506-46CC-4BB1-BE69-37D1090E6999}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FBBA506-46CC-4BB1-BE69-37D1090E6999}.Release|Any CPU.Build.0 = Release|Any CPU
{57939DE5-D42C-4159-BCC4-D3749B01F7EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57939DE5-D42C-4159-BCC4-D3749B01F7EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57939DE5-D42C-4159-BCC4-D3749B01F7EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57939DE5-D42C-4159-BCC4-D3749B01F7EF}.Release|Any CPU.Build.0 = Release|Any CPU
{85DAF737-65D4-4E6C-A105-90392AFCE666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85DAF737-65D4-4E6C-A105-90392AFCE666}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85DAF737-65D4-4E6C-A105-90392AFCE666}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85DAF737-65D4-4E6C-A105-90392AFCE666}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -65,6 +77,8 @@ Global
{4C05193C-5952-4099-B7CE-F927AC956754} = {1078C845-29AD-475F-9DB7-9DACB4422ABC}
{924EF542-984A-4DB2-9597-1FAC00A6A618} = {0A5440F7-A395-41CA-ACE5-817920F2172C}
{2FBBA506-46CC-4BB1-BE69-37D1090E6999} = {1078C845-29AD-475F-9DB7-9DACB4422ABC}
{57939DE5-D42C-4159-BCC4-D3749B01F7EF} = {0A5440F7-A395-41CA-ACE5-817920F2172C}
{85DAF737-65D4-4E6C-A105-90392AFCE666} = {0A5440F7-A395-41CA-ACE5-817920F2172C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DE2715BA-336F-4774-B880-BE171CE1018B}
Expand Down
7 changes: 7 additions & 0 deletions Matroska Solution.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CRC/@EntryIndexedValue">CRC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EBML/@EntryIndexedValue">EBML</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Demuxer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Matroska/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=webm/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
8 changes: 4 additions & 4 deletions examples/MatroskaConsole/MatroskaConsole.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<AssemblyName>MatroskaConsole</AssemblyName>
<RootNamespace>Matroska</RootNamespace>
</PropertyGroup>
Expand All @@ -12,11 +12,11 @@
<PackageReference Include="CSCore" Version="1.2.1.2" />
<PackageReference Include="CSCore.Ogg" Version="1.0.0" />
<PackageReference Include="CSCore.Opus" Version="1.0.1" />
<PackageReference Include="NEbml" Version="0.10.1" />
<PackageReference Include="OggVorbisEncoder" Version="1.2.0" />
<PackageReference Include="NEbml" Version="0.11.0" />
<PackageReference Include="OggVorbisEncoder" Version="1.2.2" />
<PackageReference Include="System.Runtime.Caching" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.0" />
<PackageReference Include="z440.atl.core" Version="3.18.0" />
<PackageReference Include="z440.atl.core" Version="3.25.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Binary file not shown.
35 changes: 23 additions & 12 deletions examples/MatroskaDemuxer/MatroskaDemuxer.csproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Matroska.Muxer\Matroska.Muxer.csproj" />
<ProjectReference Include="..\..\src\Matroska\Matroska.csproj" />
</ItemGroup>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Matroska.Muxer\Matroska.Muxer.csproj" />
<ProjectReference Include="..\..\src\Matroska\Matroska.csproj" />
<ProjectReference Include="..\MediaContainers.Matroska\MediaContainers.Matroska.csproj" />
<ProjectReference Include="..\Xtremegaida.DataStructures\Xtremegaida.DataStructures.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Estas Tonne - Internal Flight Experience %28Live in Cluj Napoca%29.webm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="issue16.webm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
38 changes: 23 additions & 15 deletions examples/MatroskaDemuxer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
using System;
using System.IO;
using System.Linq;
using Matroska.Muxer;
using System.IO;
using System.Threading.Tasks;
using MediaContainers.Matroska;

namespace MatroskaDemuxerConsoleApp
namespace MatroskaDemuxer;

class Program
{
class Program
private static async Task Main(string[] args)
{
static void Main(string[] args)
{
string folder = $"C:\\Users\\{Environment.UserName}\\Downloads\\Nuclear";
var doc = await MatroskaReader.Read(new BufferedStream(File.OpenRead("issue16.webm")));

foreach (var file in Directory.GetFiles(folder).Where(f => f.EndsWith(".webm")))
{
Console.WriteLine(file);
var outputStream = File.OpenWrite(file.Replace(".webm", ".opus"));
MatroskaDemuxer.ExtractOggOpusAudio(File.OpenRead(file), outputStream);
await doc.ReadTrackInfo();

outputStream.Close();
while (true)
{
var frame = await doc.ReadFrame();
if (frame.Buffer == null)
{
break;
}
}

var outputStream1 = File.OpenWrite("issue16.opus");
Matroska.Muxer.MatroskaDemuxer.ExtractOggOpusAudio(File.OpenRead("issue16.webm"), outputStream1);
outputStream1.Close();

var outputStream2 = File.OpenWrite("Estas Tonne - Internal Flight Experience (Live in Cluj Napoca).opus");
Matroska.Muxer.MatroskaDemuxer.ExtractOggOpusAudio(File.OpenRead("Estas Tonne - Internal Flight Experience (Live in Cluj Napoca).webm"), outputStream2);
outputStream2.Close();
}
}
Binary file added examples/MatroskaDemuxer/issue16.webm
Binary file not shown.
30 changes: 30 additions & 0 deletions examples/MediaContainers.Matroska/EBML/EBMLDocType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace MediaContainers
{
public struct EBMLDocType
{
public readonly string DocType;
public readonly int WriteVersion;
public readonly int ReadVersion;

public EBMLDocType(string type, int writeVersion, int readVersion)
{
DocType = type;
WriteVersion = writeVersion;
ReadVersion = readVersion;
}

public bool CanReadDocument(EBMLHeader header)
{
if (header.DocType != DocType) { return false; }
if (header.DocTypeReadVersion > ReadVersion) { return false; }
return true;
}

public bool CanWriteDocument(EBMLHeader header)
{
if (header.DocType != DocType) { return false; }
if (header.DocTypeVersion > WriteVersion) { return false; }
return true;
}
}
}
24 changes: 24 additions & 0 deletions examples/MediaContainers.Matroska/EBML/EBMLDocTypeLookup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;

namespace MediaContainers
{
public static class EBMLDocTypeLookup
{
private static readonly List<Func<EBMLHeader, EBMLReader, bool>> handlers = new List<Func<EBMLHeader, EBMLReader, bool>>();

public static void AddEBMLDocType(Func<EBMLHeader, EBMLReader, bool> handler)
{
lock (handlers) { handlers.Add(handler); }
}

public static bool HandleEBMLDocType(EBMLHeader header, EBMLReader reader)
{
for (int i = handlers.Count - 1; i >= 0; i--)
{
if (handlers[i](header, reader)) { return true; }
}
return false;
}
}
}
61 changes: 61 additions & 0 deletions examples/MediaContainers.Matroska/EBML/EBMLDocumentReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Xtremegaida.DataStructures;

namespace MediaContainers
{
public sealed class EBMLDocumentReader : IDisposable
{
private readonly EBMLReader reader;

public EBMLHeader Header { get; private set; }
public EBMLMasterElement Body { get; private set; }
public EBMLReader Reader => reader;

private EBMLDocumentReader(EBMLReader reader, EBMLHeader header, EBMLMasterElement body)
{
this.reader = reader;
Header = header;
Body = body;
}

public bool CanBeReadBy(EBMLDocType type)
{
return type.CanReadDocument(Header);
}

private static async ValueTask<EBMLDocumentReader> Read(EBMLHeader header, EBMLReader reader, CancellationToken cancellationToken = default)
{
if (!EBMLDocTypeLookup.HandleEBMLDocType(header, reader))
{
throw new Exception("Unrecognised EBML doctype: " + header.DocType + " version " + header.DocTypeVersion);
}
var body = await reader.ReadNextElement(true, cancellationToken) as EBMLMasterElement;
if (body == null) { throw new Exception("Expected a master element as document body"); }
return new EBMLDocumentReader(reader, header, body);
}

public static async ValueTask<EBMLDocumentReader> Read(IDataQueueReader reader, bool keepReaderOpen = false,
DataBufferCache cache = null, CancellationToken cancellationToken = default)
{
var header = await EBMLHeader.Read(reader, cache, cancellationToken);
var ebml = new EBMLReader(reader, keepReaderOpen, cache);
return await Read(header, ebml, cancellationToken);
}

public static async ValueTask<EBMLDocumentReader> Read(Stream stream, bool keepStreamOpen = false,
DataBufferCache cache = null, CancellationToken cancellationToken = default)
{
var header = await EBMLHeader.Read(stream, cache, cancellationToken);
var ebml = new EBMLReader(stream, keepStreamOpen, cache);
return await Read(header, ebml, cancellationToken);
}

public void Dispose()
{
reader.Dispose();
}
}
}
53 changes: 53 additions & 0 deletions examples/MediaContainers.Matroska/EBML/EBMLDocumentWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Xtremegaida.DataStructures;

namespace MediaContainers
{
public sealed class EBMLDocumentWriter : IDisposable, IAsyncDisposable
{
private readonly EBMLWriter writer;

public EBMLHeader Header { get; private set; }
public EBMLWriter Writer => writer;

private EBMLDocumentWriter(EBMLWriter writer, EBMLHeader header)
{
this.writer = writer;
Header = header;
}

public bool CanBeWrittenBy(EBMLDocType type)
{
return type.CanWriteDocument(Header);
}

public static async ValueTask<EBMLDocumentWriter> Write(EBMLHeader header, IDataQueueWriter writer, bool keepWriterOpen = false,
DataBufferCache cache = null, CancellationToken cancellationToken = default)
{
var ebml = new EBMLWriter(writer, keepWriterOpen, cache);
await header.Write(ebml, cancellationToken);
return new EBMLDocumentWriter(ebml, header);
}

public static async ValueTask<EBMLDocumentWriter> Write(EBMLHeader header, Stream stream, bool keepStreamOpen = false,
DataBufferCache cache = null, CancellationToken cancellationToken = default)
{
var ebml = new EBMLWriter(stream, keepStreamOpen, cache);
await header.Write(ebml, cancellationToken);
return new EBMLDocumentWriter(ebml, header);
}

public ValueTask DisposeAsync()
{
return writer.DisposeAsync();
}

public void Dispose()
{
writer.Dispose();
}
}
}
Loading