情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

WPFのMediaElementの罠

下の記事からの派生です。

インターネット上で情報を検索したりすると、「MediaElementでaviやwmvは再生できるが、mp4は再生できない」、「MediaElementではaviやwmvの他mp4なども(適切なコーデックを使えば)再生できる」という相反した情報が見付かったりします。

実際のところ、「MediaElementでは適切なコーデックさえ入れればどんなメディアファイルでも再生できる」訳ですが、何故か間違った情報が流れています(最近はSilverlightの情報ばかりで良く分からなくなっていますが)。

何故かなとずっと思っていたのですが、その原因の一端がようやく分かったかもしれません。

原因はWindows Media Playerです

実は、WPFのMediaElementコントロールとWindows Media Playerは密接に関係していて、WPFの内部で使用しているメディア再生コンポーネントがWMPのそれの変形バージョンらしいです。

そして、Windows Media Playerの設定がWPFのMediaElementコントロールに影響を与えるのです。

ここで問題となるのは、WMPの拡張子設定です。

WMPは予め登録された拡張子のファイルしか再生できないようになっています。そして、この拡張子設定が、MediaElementコントロールにも影響を与えます。すなわち、登録されていない拡張子のファイルはMediaElementでも再生できません。拡張子MP4はデフォルトでは登録されていないようです。これが、MediaElementでmp4などが再生できないように見える理由の一つなのではと思います。

因みに、WMPで登録されていない拡張子のファイルを再生しようとすると、以下のようなメッセージが表示され、自動で拡張子を登録してくれます。

MediaElementで登録されていない拡張子のファイルを再生しようとすると以下のようなエラーが出るだけで何が悪いのかさっぱり分かりません。

これを回避するために、動画再生前に動画拡張子の登録を行う必要があります。

具体的な場所は、HKEY_LOCAL_MACHINE\Software\Microsoft\Multimedia\WMPlayer\Extensions\またはHKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Player\Extensions\です。

以下のように設定すれば再生できるようになります。

プログラムから登録する場合は、下のようにします。

string localMachineSubkey = "Software\\Microsoft\\Multimedia\\WMPlayer\\Extensions\\" + fileInfo.Extension;
string currentUserSubkey = "Software\\Microsoft\\MediaPlayer\\Player\\Extensions\\" + fileInfo.Extension;
//チェックするレジストリ項目
string entryPermissions = "Permissions";
string entryRuntime = "Runtime";

//チェックするメソッド
Func<string, bool> Check = (subkey) =>
{
    try
    {
        //レジストリ下位鍵を開く(存在しない場合はNullReferenceExceptionが発生)
        using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(subkey)) { };

        return true;
    }
    catch (NullReferenceException)
    {
        return false;
    }
};

//レジストリ下位鍵が存在しない場合
if (!(Check(localMachineSubkey) || Check(currentUserSubkey)))
{
    LogService.WriteMessage("レジストリの設定が見付からなかったため、自動設定します。", 5);

    try
    {
        //レジストリ下位鍵を新規作成
        using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(currentUserSubkey))
        {
            //レジストリ項目を設定
            registryKey.SetValue(entryPermissions, 31);
            registryKey.SetValue(entryRuntime, 7);
        }
    }
    catch (Exception ex)
    {
        LogService.WriteErrorMessage("レジストリの設定でエラーが発生しました。", 5, ex);
    }
}
pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-C#, wpf