Esempio n. 1
0
 public int WriteToByteArray(Byte[] dest, int offset)
 {
     bool isRoot = this.AtomCode == null; // このnodeListがルートかどうか
     int bodyLen = WriteBodyToByteArray(dest, offset + (isRoot ? 0 : 8));
     if (!isRoot)
     {
         MP4.UIn32ToBE((UInt32)(bodyLen + 8), dest, offset);
         dest[offset + 4] = AtomCode[0];
         dest[offset + 5] = AtomCode[1];
         dest[offset + 6] = AtomCode[2];
         dest[offset + 7] = AtomCode[3];
     }
     return bodyLen + (isRoot ? 0 : 8);
 }
Esempio n. 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);
        }