プログラミングとかブログ

Unity/C#/SRPGStudio/RPGツクールMVの情報とかその他気になったことを調べて書きます。

【C#】m4aファイルのファイル名をプロパティのタイトル名に変更するプログラム

概略

レコチョクでダウンロードするとファイル名が番号
→いちいち変えるのがめんどくさい
→タイトルを変更するプログラムを書こう

プログラム

プログラムは以下のリンク先を保存してください。
m4aTitleRenamer.exe

使い方

名前を変えたいm4aファイルをexeファイルにドラッグドロップします。
f:id:shirakamisauto:20160516142310p:plain

コード

using System;
using System.Linq;
using System.Threading;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        string[] files = Environment.GetCommandLineArgs();

        files.ToList().ForEach(s => Console.WriteLine(s));

        for (int i = 1; i < files.Length; i++)
        {
            var filepath = files[i];
            if (Path.GetExtension(filepath) != ".m4a")
                continue;

            var binData = "";
            using (var sr = new StreamReader(filepath))
                binData = sr.ReadToEnd();
            //タイトル部まで読み進める
            var n = binData.IndexOf("titl", StringComparison.Ordinal);
            var titlStr = binData.Substring(n);
            //そこからmetaのインデックスを取得
            var m = titlStr.IndexOf("meta", StringComparison.Ordinal);
            //タイトル部分の取得
            //74 69 74 6C 00 00 00 00 2A 0E タイトル 00 00 XX XX XX 6D 65 74 61
            var title = titlStr.Substring(10, (m - 3) - 10).TrimEnd('\0');
            //タイトル使用不可文字列を置換
            title = title.Replace("\\", "¥").Replace("/", "/").Replace(":", ":")
                .Replace("*", "*").Replace("?", "?").Replace("|", "|")
                .Replace("\"", "”").Replace(">", ">").Replace("<", "<");
            //リネーム
            File.Move(files[i], Path.GetDirectoryName(files[1]) + "\\" + title + ".m4a");
        }
    }

解説

m4aファイルのバイナリデータを見ると、titl(74 69 74 6C) 00 00 00 00 2A 0Eと00 00 XX XX XX meta(6D 65 74 61)の間に楽曲タイトルがあります。
titlから先頭10バイトを飛ばしてmetaから3バイト戻した範囲を取得してnull文字を消せばタイトルが取得できます。
プロパティと書きましたがtitl部は内部データのようです。
(いじってもプロパティは変更されない)
といってもプロパティのタイトルと同じなので問題ないです。
プロパティデータはdata(64 61 74 61)がいくつか並んでいるとこを変更する必要があります。

m4aに限らずフォーマットは基本的にセクションごとのヘッダがあるので、そこからパターンを推測すれば大体ごにょごにょできるのが面白いです。