示例#1
0
        private void CopyID32DataToMP4(ID3V2Tag.id3tag id3tag, MP4.ATOM mp4)
        {
            if (id3tag == null)
            {
                return;
            }
            var geob = id3tag.frame.Find(_ => _.id == "GEOB" && _.geob_mime.StartsWith("image/"));

            if ((geob == null) || (geob.geob_binarydata == null))
            {
                return;
            }

            var covrdata = new MP4.ATOM_raw();

            covrdata.AtomCode = Encoding.ASCII.GetBytes("data");
            covrdata.data     = new byte[geob.geob_binarydata.Length + 8];
            covrdata.data[0]  = 0x00;
            covrdata.data[1]  = 0x00;
            covrdata.data[2]  = 0x00;
            covrdata.data[3]  = 0x0D;
            covrdata.data[4]  = 0x00;
            covrdata.data[5]  = 0x00;
            covrdata.data[6]  = 0x00;
            covrdata.data[7]  = 0x00;
            Buffer.BlockCopy(geob.geob_binarydata, 0, covrdata.data, 8, geob.geob_binarydata.Length);

            var covratom = new MP4.ATOM_covr();

            covratom.AtomCode = Encoding.ASCII.GetBytes("covr");

            var covr = mp4.GetChildNode <MP4.ATOM_covr>();

            if (covr == null)
            {
                covr          = new MP4.ATOM_covr();
                covr.AtomCode = Encoding.ASCII.GetBytes("covr");
                var ilst = mp4.GetChildNode <MP4.ATOM_ilst>();
                if (ilst == null)
                {
                    return;
                }
                ilst.AddChild(covr);
            }
            covr.AddChild(covrdata);

            AppendLog("  歌詞画像をコピーしました");
        }
示例#2
0
        private bool FixMoraMP4(string filepath)
        {
            if (!File.Exists(filepath))
            {
                return(false);
            }
            var destfilepath = (System.IO.Path.GetExtension(filepath).ToLower() == ".m4a")
                ? filepath + ".m4a"
                : System.IO.Path.ChangeExtension(filepath, ".m4a");

            using (var fs = System.IO.File.OpenRead(filepath))
            {
                try
                {
                    // 元のファイルサイズを保持
                    var originalsize = fs.Length;

                    // mp4の読み出し
                    var mp4 = MP4.Read(fs, true);

                    // トラック名を表示
                    var title  = getTagText <MP4.ATOM__nam>(mp4);
                    var artist = getTagText <MP4.ATOM__ART>(mp4);
                    AppendLog(String.Format("  {0} - {1}", title ?? "?", artist ?? "?"));

                    // brandを修正
                    mp4.GetChildNode <MP4.ATOM_ftyp>().brands = M4A_FTYP_BRANDS;

                    // id32を探す
                    var id32atom = mp4.GetChildNode <MP4.ATOM_ID32>();
                    if (id32atom != null)
                    {
                        var id32body = new byte[id32atom.data.Length - 6];
                        System.Buffer.BlockCopy(id32atom.data, 6, id32body, 0, id32atom.data.Length - 6);
                        ID3V2Tag.id3tag id3tag = null;
                        try
                        {
                            id3tag = ID3V2Tag.read_id3tag(new MemoryStream(id32body), false);
                        }
                        catch {
                            AppendLog("ID32領域の内容が読めませんでした。が処理を続行します。");
                        }

                        // ID3から使えるデータを引っこ抜く
                        if (id3tag != null)
                        {
                            CopyID32DataToMP4(id3tag, mp4);
                        }

                        // ID32の親から、hdlrとID32を削除する
                        var parent = id32atom.ParentNode;
                        parent.RemoveChild(parent.GetChildNode <MP4.ATOM_hdlr>());
                        parent.RemoveChild(id32atom);

                        // ID32の入っていたmetaが空になっているなら、それも削除
                        if (parent.GetChildNodes <MP4.ATOM>().Count() == 0)
                        {
                            parent.ParentNode.RemoveChild(parent);
                        }
                    }

                    using (var fsw = System.IO.File.OpenWrite(destfilepath))
                    {
                        var buf = new byte[fs.Length + M4A_FTYP_BRANDS.Length];
                        // 一旦編集後のmp4をバッファに書き出してみる
                        var len = mp4.WriteToByteArray(buf, 0);

                        // stco atomのシークテーブルを補正
                        var stcos = mp4.GetChildNodes <MP4.ATOM_stco>();
                        foreach (var stco in stcos)
                        {
                            stco.Adjust((int)(len - originalsize));
                        }

                        // mp4を生成しなおしてファイルに書く
                        len = mp4.WriteToByteArray(buf, 0);
                        fsw.Write(buf, 0, len);
                    }
                }
                catch (Exception ex)
                {
                    AppendLog(ex.StackTrace);
                    return(false);
                }
            }
            return(true);
        }