【VisualStudioC#】動画の長さを取得する【Shell32】

VisualStudio C# で動画(mp4ファイル)の長さを取得する処理を作成した。

色々調べたが、何故かうまくいかない…! Shell32 がうまく使えない…!
成功した例をいかに示す。というか、関数を作った。

 

① shell32 を使用する準備をする。
using shell32; としたいところだが、参照設定しないと使用できない。

f:id:chipomote:20150915132432p:plain

参照設定にて、マウスの右クリック→参照の追加をクリックすると、上記の画面が出るので、
Microsoft Shell 」と検索をする。検索し、チェックを入れて完了をすると、
ソリューションにshell32が追加される。

 

② shell32 を使用するための関数を作成する

    public Shell32.Folder GetShell32NameSpaceFolder(Object folder)
    {
        Type shellAppType = Type.GetTypeFromProgID("Shell.Application");

        Object shell = Activator.CreateInstance(shellAppType);
        return (Shell32.Folder)shellAppType.InvokeMember("NameSpace",
        System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
    }

 

③動画の再生長の長さを取得する

第一引数にファイル名を渡す(フルパスで)
すると、第二引数に動画の秒数が帰ってくる。
FolderItem なども使用するので、 using shell32 以外にも using System.IO も必要になる

private bool getPositionValue(string _movieName, ref int _val)
    {
        // shellClass クラスのインスタンス生成
        string strResultValue;

        // FolderItemインタフェイス
        FolderItem fItem = null;
        FileInfo fInfo = new FileInfo(_movieName);

        // Folderインタフェイス
        Folder f = GetShell32NameSpaceFolder(fInfo.DirectoryName);

        try
        {
            // ファイル情報を取得する
            fItem = f.ParseName(fInfo.Name);

            if (fItem != null)
            {
                // 時間を取得する
                // OS判定して、XP以前とインデックス区別
                // XPはMajor:5 Minor:1、7はMajor:6 Minor:1、8はMajor:6 Minor:2
                int index = 0;
                System.OperatingSystem os = System.Environment.OSVersion;

                if (os.Version.Major < 6)
                {
                    index = 21;
                }
                else
                {
                    index = 27;
                }

                strResultValue = f.GetDetailsOf(fItem, index);
                if (strResultValue.Trim() == "")
                {
                    Console.WriteLine("{0}:{1} は破損している可能性があります。", DateTime.Now.ToString("F"), _movieName);
                    return false;
                }

                // 時間の変換を行う
                string[] timeList = strResultValue.Split(':');
                _val = int.Parse(timeList[0]) * 3600;
                _val += int.Parse(timeList[1]) * 60;
                _val += int.Parse(timeList[2]);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("{0}:{1}のファイル秒数取得に失敗しました。({2})", DateTime.Now.ToString("F"), _movieName, e.Message);
            return false;
        }
        finally
        {
            // null を代入
            f = null;
            fInfo = null;
            fItem = null;
        }

        return true;
    }