Skip to content

Commit

Permalink
Add support for freeform tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Mbucari committed Jul 3, 2023
1 parent 71cb1d3 commit 3e4c479
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 11 deletions.
2 changes: 1 addition & 1 deletion AAXClean.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</metadata>
<dependencies>
<group targetFramework="net6.0">
<dependency id="Mpeg4Lib" version="0.1.12" />
<dependency id="Mpeg4Lib" version="0.1.20" />
</group>
</dependencies>
<files>
Expand Down
2 changes: 1 addition & 1 deletion src/AAXClean/AAXClean.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.0.3</Version>
<Version>1.1.0</Version>
<Authors>MrGneissGuy</Authors>
<Company>Just Me, Inc.</Company>
<Description>Decrypts Audible aax and aaxc files to mp4.</Description>
Expand Down
2 changes: 1 addition & 1 deletion src/Mpeg4Lib/Boxes/AdrmBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public AdrmBox(Stream file, BoxHeader header, IBox parent) : base(header, parent
DrmBlob = file.ReadBlock(56);
middleBlob = file.ReadBlock(4);
Checksum = file.ReadBlock(20);
long len = Header.FilePosition + Header.TotalBoxSize - file.Position;
long len = RemainingBoxLength(file);
endBlob = file.ReadBlock((int)len);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Mpeg4Lib/Boxes/AppleDataBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public AppleDataBox(Stream file, BoxHeader header, IBox parent) : base(header, p
{
DataType = (AppleDataType)file.ReadUInt32BE();
Flags = file.ReadUInt32BE();
long length = Header.FilePosition + Header.TotalBoxSize - file.Position;
long length = RemainingBoxLength(file);
Data = file.ReadBlock((int)length);
}
protected override void Render(Stream file)
Expand Down
66 changes: 63 additions & 3 deletions src/Mpeg4Lib/Boxes/AppleListBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ public AppleListBox(Stream file, BoxHeader header, IBox parent) : base(header, p

while (file.Position < endPos)
{
AppleTagBox appleTag = new AppleTagBox(file, new BoxHeader(file), this);
BoxHeader tagBoxHeader = new BoxHeader(file);

AppleTagBox appleTag
= tagBoxHeader.Type == "----"
? new FreeformTagBox(file, tagBoxHeader, this)
: new AppleTagBox(file, tagBoxHeader, this);

if (appleTag.Header.TotalBoxSize == 0)
break;

Children.Add(appleTag);
}
}
Expand All @@ -33,7 +39,7 @@ public void AddTag(string name, string data)
public void AddTag(string name, byte[] data, AppleDataType type)
{
AppleTagBox.Create(this, name, data, type);
}
}

public void EditOrAddTag(string name, string data)
{
Expand All @@ -59,6 +65,44 @@ public void EditOrAddTag(string name, byte[] data, AppleDataType type)
}
}

public void AddFreeformTag(string domain, string name, string data)
{
FreeformTagBox.Create(this, domain, name, Encoding.UTF8.GetBytes(data), AppleDataType.Utf_8);
}

public void AddFreeformTag(string domain, string name, byte[] data, AppleDataType type)
{
FreeformTagBox.Create(this, domain, name, data, type);
}

public void EditOrAddFreeformTag(string domain, string name, string data)
{
EditOrAddFreeformTag(domain, name, Encoding.UTF8.GetBytes(data), AppleDataType.Utf_8);
}

public void EditOrAddFreeformTag(string domain, string name, byte[] data)
{
EditOrAddFreeformTag(domain, name, data, AppleDataType.ContainsData);
}

public void EditOrAddFreeformTag(string domain, string name, byte[] data, AppleDataType type)
{
FreeformTagBox tag
= Tags
.OfType<FreeformTagBox>()
.Where(t => t.Mean.ReverseDnsDomain == domain && t.Name.Name == name)
.FirstOrDefault();

if (tag is null)
{
AddFreeformTag(domain, name, data, type);
}
else if (tag?.Data.DataType == type)
{
tag.Data.Data = data;
}
}

public string GetTagString(string name)
{
byte[] tag = GetTagBytes(name);
Expand All @@ -72,6 +116,22 @@ public byte[] GetTagBytes(string name)
.Where(t => t.Header.Type == name)
.FirstOrDefault()
?.GetChild<AppleDataBox>()
?.Data;
?.Data;

public string GetFreeformTagString(string domain, string name)
{
byte[] tag = GetFreeformTagBytes(domain, name);
if (tag is null) return null;

return Encoding.UTF8.GetString(tag);
}

public byte[] GetFreeformTagBytes(string domain, string name)
=> Tags
.OfType<FreeformTagBox>()
.Where(t => t.Mean.ReverseDnsDomain == domain && t.Name.Name == name)
.FirstOrDefault()
?.GetChild<AppleDataBox>()
?.Data;
}
}
12 changes: 9 additions & 3 deletions src/Mpeg4Lib/Boxes/AppleTagBox.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
using System.IO;
using System;
using System.IO;
using System.Text;

namespace Mpeg4Lib.Boxes
{
public class AppleTagBox : Box
{
public static void Create(AppleListBox parent, string name, byte[] data, AppleDataType dataType)
public static AppleTagBox Create(AppleListBox parent, string name, byte[] data, AppleDataType dataType)
{
if (Encoding.ASCII.GetByteCount(name) != 4)
throw new ArgumentOutOfRangeException($"{nameof(name)} must be exactly 4 bytes long");

int size = data.Length + 2 + 8 /* empty Box size*/ ;
BoxHeader header = new BoxHeader((uint)size, name);

AppleTagBox tagBox = new AppleTagBox(header, parent);
AppleDataBox.Create(tagBox, data, dataType);

parent.Children.Add(tagBox);
return tagBox;
}

private AppleTagBox(BoxHeader header, IBox parent) : base(header, parent) { }
protected AppleTagBox(BoxHeader header, IBox parent) : base(header, parent) { }

public AppleTagBox(Stream file, BoxHeader header, IBox parent) : base(header, parent)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Mpeg4Lib/Boxes/Box.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public abstract class Box : IBox
public List<IBox> Children { get; } = new List<IBox>();
public virtual long RenderSize => 8 + Children.Sum(b => b.RenderSize);

protected long RemainingBoxLength(Stream file) => Header.FilePosition + Header.TotalBoxSize - file.Position;

public Box(BoxHeader header, IBox parent)
{
Header = header;
Expand Down
2 changes: 2 additions & 0 deletions src/Mpeg4Lib/Boxes/BoxFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public static IBox CreateBox(Stream file, IBox parent)
"meta" => new MetaBox(file, header, parent),
"ilst" => new AppleListBox(file, header, parent),
"data" => new AppleDataBox(file, header, parent),
"mean" => new MeanBox(file, header, parent),
"name" => new NameBox(file, header, parent),
_ => new UnknownBox(file, header, parent),
};
}
Expand Down
37 changes: 37 additions & 0 deletions src/Mpeg4Lib/Boxes/FreeformTagBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.IO;
using System.Text;

namespace Mpeg4Lib.Boxes
{
//https://mutagen.readthedocs.io/en/latest/api/mp4.html
public class FreeformTagBox : AppleTagBox
{
public MeanBox Mean => GetChild<MeanBox>();
public NameBox Name => GetChild<NameBox>();

public static FreeformTagBox Create(AppleListBox parent, string domain, string tagName, byte[] data, AppleDataType dataType)
{
int size
= 12 /* empty FullBox size*/ + Encoding.UTF8.GetByteCount(domain)
+ 12 /* empty FullBox size*/ + Encoding.UTF8.GetByteCount(tagName)
+ 8 /* empty Box size*/ + data.Length + 2;

BoxHeader header = new BoxHeader((uint)size, "----");

var tagBox = new FreeformTagBox(header, parent);
MeanBox.Create(tagBox, domain);
NameBox.Create(tagBox, tagName);
AppleDataBox.Create(tagBox, data, dataType);

parent.Children.Add(tagBox);
return tagBox;
}

protected FreeformTagBox(BoxHeader header, IBox parent) : base(header, parent) { }

public FreeformTagBox(Stream file, BoxHeader header, IBox parent) : base(header, parent)
{
LoadChildren(file);
}
}
}
39 changes: 39 additions & 0 deletions src/Mpeg4Lib/Boxes/MeanBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Mpeg4Lib.Util;
using System.IO;
using System.Text;

namespace Mpeg4Lib.Boxes
{
public class MeanBox : FullBox
{
public override long RenderSize => base.RenderSize + Encoding.UTF8.GetByteCount(ReverseDnsDomain);
public string ReverseDnsDomain { get; set; }
public MeanBox(Stream file, BoxHeader header, IBox parent) : base(file, header, parent)
{
var stringSize = RemainingBoxLength(file);
var stringData = file.ReadBlock((int)stringSize);
ReverseDnsDomain = Encoding.UTF8.GetString(stringData);
}

public static void Create(IBox parent, string domain)
{
int size = Encoding.UTF8.GetByteCount(domain) + 12 /* empty FullBox size*/;
BoxHeader header = new BoxHeader((uint)size, "mean");

MeanBox meanBox = new MeanBox(header, parent, domain);

parent.Children.Add(meanBox);
}

private MeanBox(BoxHeader header, IBox parent, string domain) : base(new byte[4], header, parent)
{
ReverseDnsDomain = domain;
}

protected override void Render(Stream file)
{
base.Render(file);
file.Write(Encoding.UTF8.GetBytes(ReverseDnsDomain));
}
}
}
39 changes: 39 additions & 0 deletions src/Mpeg4Lib/Boxes/NameBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Mpeg4Lib.Util;
using System.IO;
using System.Text;

namespace Mpeg4Lib.Boxes
{
public class NameBox : FullBox
{
public override long RenderSize => base.RenderSize + Encoding.UTF8.GetByteCount(Name);
public string Name { get; set; }
public NameBox(Stream file, BoxHeader header, IBox parent) : base(file, header, parent)
{
var stringSize = RemainingBoxLength(file);
var stringData = file.ReadBlock((int)stringSize);
Name = Encoding.UTF8.GetString(stringData);
}

public static void Create(IBox parent, string name)
{
int size = Encoding.UTF8.GetByteCount(name) + 12 /* empty FullBox size*/;
BoxHeader header = new BoxHeader((uint)size, "name");

NameBox nameBox = new NameBox(header, parent, name);

parent.Children.Add(nameBox);
}

private NameBox(BoxHeader header, IBox parent, string name) : base(new byte[4], header, parent)
{
Name = name;
}

protected override void Render(Stream file)
{
base.Render(file);
file.Write(Encoding.UTF8.GetBytes(Name));
}
}
}
2 changes: 1 addition & 1 deletion src/Mpeg4Lib/Mpeg4Lib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>0.1.12</Version>
<Version>0.1.2</Version>
<Authors>MrGneissGuy</Authors>
<Company>Just Me, Inc.</Company>
<Description>Parsees mpeg-4 files</Description>
Expand Down

0 comments on commit 3e4c479

Please sign in to comment.