【C#】Sony PlayMemories Home向け動画のファイル名を撮影日時に変更するプログラム

Sonyの4Kビデオカメラ FDR-AX45を買いました。
PCでの動画管理にはSonyのPlayMemories Homeを使用していますが、
動画のファイル名がただの連番であるため管理しにくいです。

そこで、撮影日時をファイル名にするプログラムを作成しました。
変更後のファイル名は「20181009_2022.mp4」(2018年10月9日 20時22分撮影の場合)のようになります。
また、おまけ機能としてmoddファイルとmoffファイルを削除する機能も付けてあります。
PlayMemories Homeの[ツール]にある[プログラムから開く]にexeを追加しておくと良いでしょう。

ビルド環境は

  • C#
  • .NET Framework 4.6.1

です。
気を付ける点として、参照にshell32を追加し、プロパティの「相互運用型の埋め込み」をFalseにする必要があります。
この辺の詳細は「c# shell32 相互運用型の埋め込み」あたりでググってください。

以下にコードを載せます。


using System;
using System.IO;
using Shell32;

namespace SetMovieDateTime
{
    class Program
    {
        static dynamic shell;
  
        static void Main(string[] args)
        {
            if(args.Length == 0)
            {
                return;
            }

            Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
            shell = Activator.CreateInstance(shellAppType);
            foreach (string arg in args)
            {
                DeleteModdFile(arg);
                DeleteMoffFile(arg);
                SetMovieDateTime(arg);
            }

            Console.ReadLine();
        }

        static DateTime ParseDateTime(string str)
        {
            string dateTimeStr = "";
            foreach(char c in str)
            {
                if (int.TryParse(c.ToString(), out int tmp))
                {
                    dateTimeStr += c;
                }
                else if ((c == '/') || (c == ':') || (c == ' '))
                {
                    dateTimeStr += c;
                }
                else
                {
                    // Do Nothing
                }
            }

            DateTime dateTime = DateTime.ParseExact(dateTimeStr, "yyyy/MM/dd H:m", null);
            return dateTime;
        }

        static void SetMovieDateTime(string filePath)
        {
            string directoryPath = System.IO.Path.GetDirectoryName(filePath);
            Folder folder = shell.NameSpace(directoryPath);
            FolderItem file = folder.ParseName(System.IO.Path.GetFileName(filePath));

            string itemName = folder.GetDetailsOf(null, 209);
            string itemValue = folder.GetDetailsOf(file, 209);

            DateTime dateTime = ParseDateTime(itemValue);

            string newFileName = dateTime.ToString("yyyyMMdd_HHmm");
            string extention = ".mp4";
            string newFilePath = directoryPath + "\\" + newFileName + extention;
            if (System.IO.File.Exists(newFilePath))
            {
                return;
            }

            // 読み取り専用チェック
            FileAttributes fa = File.GetAttributes(filePath);
            bool isReadOnly = ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);

            // 読み取り専用だったら解除
            if (isReadOnly)
            {
                fa = fa & ~FileAttributes.ReadOnly;
                File.SetAttributes(filePath, fa);
            }

            // ファイルの作成日時を変更
            File.SetCreationTime(filePath, dateTime);
            File.SetLastAccessTime(filePath, dateTime);
            File.SetLastWriteTime(filePath, dateTime);

            // 読み取り専用の再設定
            if (isReadOnly)
            {
                fa = fa | FileAttributes.ReadOnly;
                File.SetAttributes(filePath, fa);
            }

            // ファイル名変更
            File.Move(filePath, newFilePath);

            // Debug out
            Console.WriteLine(filePath);
            Console.WriteLine(" ⇒ " + newFilePath);
        }

        static void DeleteModdFile(string baseFilePath)
        {
            if (System.IO.File.Exists(baseFilePath + ".modd"))
            {
                System.IO.File.Delete(baseFilePath + ".modd");
                Console.WriteLine("Del: " + baseFilePath + ".modd");
            }
        }
        static void DeleteMoffFile(string baseFilePath)
        {
            if (System.IO.File.Exists(baseFilePath + ".moff"))
            {
                System.IO.File.Delete(baseFilePath + ".moff");
                Console.WriteLine("Del: " + baseFilePath + ".moff");
            }
        }
    }
}

Leave a comment