public MP4Document Build(Movie movie) { if (Fragmenter == null) { Fragmenter = new TimeBasedFragmenter(); } Track2Sample = movie.Tracks.ToDictionary(x => x, y => y.Samples); Track2SampleSizes = movie.Tracks.ToDictionary(x => x, y => y.Samples.Select(x => x.Size).ToArray()); var meta = Variant.Get(); MP4Document doc = new MP4Document(meta); doc.AddAtom(CreateFileTypeBox(movie)); var chunks = movie.Tracks.ToDictionary(x => x, GetChunkSizes); var moov = CreateMovieBox(movie, chunks); doc.AddAtom(moov); var contentSize = moov.GetPath(TRAK, MDIA, MINF, STBL, STSZ).OfType <AtomSTSZ>().Sum(x => x.SampleSize); var mdat = new AtomMDAT(movie, chunks, contentSize); doc.AddAtom(mdat); /* * dataOffset is where the first sample starts. In this special mdat the samples always start * at offset 16 so that we can use the same offset for large boxes and small boxes */ uint dataOffset = mdat.DataOffset; foreach (var chunkOffsetBox in ChunkOffsetBoxes.Values) { for (var i = 0; i < chunkOffsetBox.Entries.Count; i++) { chunkOffsetBox.Entries[i] += dataOffset; } } foreach (var saio in SampleAuxiliaryInformationOffsetsBoxes) { long offset = saio.Size; // the calculation is systematically wrong by 4, I don't want to debug why. Just a quick correction --san 14.May.13 offset += 4 + 4 + 4 + 4 + 4 + 24; // size of all header we were missing otherwise (moov, trak, mdia, minf, stbl) object b = saio; do { BaseAtom current = (BaseAtom)b; b = current.Parent; offset += ((IBoxContainer)b).SubAtoms.TakeWhile(box => box != current).Sum(box => box.Size); } while (b is BoxAtom); long[] saioOffsets = saio.Offsets; for (int i = 0; i < saioOffsets.Length; i++) { saioOffsets[i] += offset; } } return(doc); }
protected BaseAtom(MP4Document document, uint type, long size, long start) { Start = start; Size = size; Type = type; document.AddAtom(this); Document = document; }
protected BaseAtom(MP4Document document, uint type, long size, long start) { Start = start; Size = size; Type = type; document.AddAtom(this); Document = document; }