MSWMMファイルからXML部分を抜き出す

MSWMM(Windowsムービーメーカーのプロジェクトファイル)のファイルフォーマットが公開されていないように思えたので調べてみました。
一応、Windowsムービーメーカー6.0(Windows Vistaに同梱)で作ったファイルで調べました。

XML部分の抽出プログラム(C#)

XML部分はMovieMaker要素をルートとして、UTF-16の文字コードで記録されています。
メタデータと呼べるものかどうかは分かりませんが、とりあえずメタデータという名前で読み込んでます。

抽出したXMLの例(この動画の編集プロジェクトから抽出。131KB)

using System;
using System.IO;
using System.Text;

namespace MifuminLib
{
 public class MSWMMReader
 {
  enum ReadState
  {
   BeforeXML,
   HeadOfXML,
   ReadingXML
  };

  public string Metadata { get; protected set; }

  public MSWMMReader(string fileName)
  {
   Read(fileName);
  }

  private void Read(string fileName)
  {
   using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 1024))
   {
    Read(stream);
   }
  }

  private void Read(Stream stream)
  {
   using (BinaryReader br = new BinaryReader(stream))
   {
    ReadState rs = ReadState.BeforeXML;
    StringBuilder sb = new StringBuilder(1024 * 1024);
    try
    {
     while (true)
     {
      short ch = br.ReadInt16();
      switch (rs)
      {
       case ReadState.BeforeXML:
        // メタデータ登場前
        if (ch == '<')
        {
         // メタデータの始まりかもしれない
         sb.Append((char)ch);
         rs = ReadState.HeadOfXML;
        }
        break;
       case ReadState.HeadOfXML:
        // メタデータ候補登場
        sb.Append((char)ch);
        if ("<MovieMaker".StartsWith(sb.ToString(), StringComparison.CurrentCultureIgnoreCase))
        {
         if ("<MovieMaker".Equals(sb.ToString(), StringComparison.CurrentCultureIgnoreCase))
         {
          // メタデータであることが確定
          rs = ReadState.ReadingXML;
         }
        }
        else
        {
         // 実はメタデータではなかった
         sb.Clear();
         rs = ReadState.BeforeXML;
        }
        break;
       case ReadState.ReadingXML:
        // メタデータの内容
        sb.Append((char)ch);
        if (ch == '>' && sb.ToString().EndsWith("</MovieMaker>", StringComparison.CurrentCultureIgnoreCase))
        {
         // メタデータ終了
         Metadata = sb.ToString();
         return;
        }
        break;
       default:
        break;
      }
     }
    }
    catch (Exception) { }
   }
  }
 }
}