private static string ProcessAtomsButDumber(Memory <byte> buffer) { var cursor = 0; while (cursor < buffer.Length) { var atom = new MP4Atom(buffer.Span.Slice(cursor)); cursor += Math.Max(4, atom.Size); if (atom.Name == "ilst" || atom.Name == "?nam") { return(ProcessAtomsButDumber(atom.Buffer)); } if (atom.Name == "data") { return(Encoding.UTF8.GetString(atom.Buffer.Slice(8).ToArray())); } } return(""); }
private static IEnumerable <(string, string[])> ProcessAtoms(Memory <byte> buffer) { var cursor = 0; var filename = default(string); while (cursor < buffer.Length) { var atom = new MP4Atom(buffer.Span.Slice(cursor)); cursor += atom.Size; if (atom.Name == "moov" || atom.Name == "udta") { foreach (var(fn, str) in ProcessAtoms(atom.Buffer)) { yield return(fn, str); } continue; } if (atom.Name == "meta") { filename = ProcessAtomsButDumber(atom.Buffer); } if (atom.Name != "Xtra") { continue; // moov -> udta -> Xtra } if (atom.Buffer.Length < 0x1F) { Console.Out.WriteLine("\nReplay is f****d\n"); continue; } var localCursor = 0; var blockSize = BinaryPrimitives.ReadInt32BigEndian(atom.Buffer.Span); if (blockSize != atom.Buffer.Length) { Console.Out.WriteLine("\nReplay has a lot of data?\n"); } localCursor += 4; var blockNameLength = BinaryPrimitives.ReadInt32BigEndian(atom.Buffer.Span.Slice(localCursor)); if (blockNameLength == 0) { continue; } localCursor += 4; var name = Encoding.ASCII.GetString(atom.Buffer.Span.Slice(localCursor, blockNameLength).ToArray()); localCursor += blockNameLength; if (name != "WM/EncodingSettings") { Console.Out.WriteLine("\nReplay is f****d\n"); continue; } var settingCount = BinaryPrimitives.ReadInt32BigEndian(atom.Buffer.Span.Slice(localCursor)); localCursor += 4; for (var i = 0; i < settingCount; ++i) { var encodedSettingLength = BinaryPrimitives.ReadInt32BigEndian(atom.Buffer.Span.Slice(localCursor)); if (encodedSettingLength == 0) { continue; } var type = BinaryPrimitives.ReadInt16BigEndian(atom.Buffer.Span.Slice(localCursor + 4)); if (type != 8) { Console.Out.WriteLine("\nNot Type 8?\n"); } var data = atom.Buffer.Span.Slice(localCursor + 6, encodedSettingLength - 6); var b64Str = Encoding.Unicode.GetString(data.ToArray()); localCursor += encodedSettingLength; yield return(filename, b64Str.Split(':')); } } }