Пример #1
0
        public Atom GetStco(MediaReader reader, Atom track)
        {
            List <Atom> tracksub = reader.GetAtoms(track.Position + track.HeadLength, track.Size - track.HeadLength).ToList();
            Atom        mdia     = tracksub.FirstOrDefault(m => m.Name == "mdia");
            List <Atom> mdiasub  = reader.GetAtoms(mdia.Position + mdia.HeadLength, mdia.Size - mdia.HeadLength).ToList();
            Atom        minf     = mdiasub.FirstOrDefault(m => m.Name == "minf");
            List <Atom> minfsub  = reader.GetAtoms(minf.Position + minf.HeadLength, minf.Size - minf.HeadLength).ToList();
            Atom        stbl     = minfsub.FirstOrDefault(m => m.Name == "stbl");
            List <Atom> stblsub  = reader.GetAtoms(stbl.Position + stbl.HeadLength, stbl.Size - stbl.HeadLength).ToList();
            Atom        stco     = stblsub.FirstOrDefault(m => m.Name == "stco" || m.Name == "co64");

            return(stco);
        }
Пример #2
0
        /// <summary>
        /// 把moov信息移动到视频信息前端
        /// </summary>
        /// <param name="newfile">新文件路径</param>
        /// <returns>true:移动成功,false:moov信息无需移动</returns>
        public bool MoveMoov2Top(string newfile)
        {
            MediaReader reader = new MediaReader(OriginStream);
            List <Atom> atoms  = reader.GetAtoms().ToList();
            //判断moov和mdata的位置
            int moovIndex = 0;
            int mdatIndex = 0;

            for (int i = 0; i < atoms.Count; i++)
            {
                Atom atom = atoms[i];
                if (atom.Position < 0 || atom.Size < 0)
                {
                    throw new Exception("视频信息异常,视频过大");
                }
                if (atom.Name == "moov")
                {
                    moovIndex = i;
                }
                else if (atom.Name == "mdat")
                {
                    mdatIndex = i;
                }
            }

            if (moovIndex == 0 || mdatIndex == 0)
            {
                throw new Exception("视频信息异常");
            }

            if (moovIndex < mdatIndex)
            {
                return(false);
            }


            //移动
            if (atoms[0].Name != "ftyp")
            {
                throw new Exception("视频信息有异常,ftype位置不对");
            }
            Atom moov = atoms[moovIndex];

            for (int i = moovIndex; i > 1; i--)
            {
                atoms[i] = atoms[i - 1];
            }
            atoms[1] = moov;
            //Atom temple = atoms[moovIndex];
            //atoms[moovIndex] = atoms[mdatIndex];
            //atoms[mdatIndex] = temple;

            byte[] moovData = reader.ReadData(moov);

            List <Atom> moovsub = reader.GetAtoms(moov.Position + moov.HeadLength, moov.Size - moov.HeadLength).ToList();

            List <Atom> tracks = moovsub.Where(m => m.Name == "trak").ToList();

            List <Atom> stcos = new List <Atom>();

            byte[] offsetBytes   = new byte[4];
            byte[] offset64Bytes = new byte[8];
            foreach (var track in tracks)
            {
                Atom stco = GetStco(reader, track);

                byte[] data = reader.ReadDataWithoutHead(stco);

                byte[] number_of_entries = new byte[4];
                Array.Copy(data, number_of_entries, number_of_entries.Length);
                Array.Reverse(number_of_entries);
                long length = BitConverter.ToUInt32(number_of_entries, 0);
                if (stco.Name == "stco")
                {
                    for (long i = 0; i < length; i++)
                    {
                        Array.Copy(data, 4 + 4 * i, offsetBytes, 0, offsetBytes.Length);
                        Array.Reverse(offsetBytes);
                        UInt32 offset = BitConverter.ToUInt32(offsetBytes, 0);
                        offset     += (UInt32)moov.Size;
                        offsetBytes = BitConverter.GetBytes(offset);
                        Array.Reverse(offsetBytes);
                        Array.Copy(offsetBytes, 0, moovData, (stco.Position - moov.Position) + stco.HeadLength + 4 + i * 4, offsetBytes.Length);
                    }
                }
                else if (stco.Name == "co64")
                {
                    for (long i = 0; i < length; i++)
                    {
                        Array.Copy(data, 4 + 8 * i, offset64Bytes, 0, offset64Bytes.Length);
                        Array.Reverse(offset64Bytes);
                        long offset = (long)BitConverter.ToUInt64(offset64Bytes, 0);
                        if (offset < 0)
                        {
                            throw new Exception("文件过大");
                        }
                        offset       += moov.Size;
                        offset64Bytes = BitConverter.GetBytes(offset);
                        Array.Reverse(offset64Bytes);
                        Array.Copy(offset64Bytes, 0, moovData, (stco.Position - moov.Position) + stco.HeadLength + 4 + i * 8, offset64Bytes.Length);
                    }
                }
            }

            using (FileStream newStream = File.Create(newfile))
            {
                foreach (Atom atom in atoms)
                {
                    byte[] buffer = null;
                    if (atom.Name == "moov")
                    {
                        buffer = moovData;
                    }
                    else
                    {
                        buffer = new byte[atom.Size];
                        OriginStream.Seek(atom.Position, SeekOrigin.Begin);
                        OriginStream.Read(buffer, 0, buffer.Length);
                    }
                    newStream.Write(buffer, 0, buffer.Length);
                }
            }

            return(true);
        }