func (self *SimpleH264Writer) Finish() (err error) { self.sample.SampleDesc.Avc1Desc.Conf.Record, err = atom.CreateAVCDecoderConfRecord( self.SPS, self.PPS, ) if err != nil { return } if self.timeToSample != nil { self.sample.TimeToSample.Entries = append( self.sample.TimeToSample.Entries, *self.timeToSample, ) } if err = self.mdatWriter.Close(); err != nil { return } moov := &atom.Movie{} moov.Header = &atom.MovieHeader{ TimeScale: self.TimeScale, Duration: self.duration, PreferredRate: atom.IntToFixed(1), PreferredVolume: atom.IntToFixed(1), Matrix: [9]int{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000}, NextTrackId: 2, } track := &atom.Track{ Header: &atom.TrackHeader{ TrackId: 1, Flags: 0x0003, // Track enabled | Track in movie Duration: self.duration, Volume: atom.IntToFixed(1), Matrix: [9]int{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000}, TrackWidth: atom.IntToFixed(self.Width), TrackHeight: atom.IntToFixed(self.Height), }, Media: &atom.Media{ Header: &atom.MediaHeader{ TimeScale: self.TimeScale, Duration: self.duration, }, Info: &atom.MediaInfo{ Video: &atom.VideoMediaInfo{ Flags: 0x000001, }, Sample: self.sample, Data: &atom.DataInfo{ Refer: &atom.DataRefer{ Url: &atom.DataReferUrl{ Flags: 0x000001, // Self reference }, }, }, }, Handler: &atom.HandlerRefer{ SubType: "vide", Name: "Video Media Handler", }, }, } moov.Tracks = append(moov.Tracks, track) if err = atom.WriteMovie(self.W, moov); err != nil { return } return }
func TestConvert(filename string) (err error) { var osfile *os.File if osfile, err = os.Open(filename); err != nil { return } var finfo os.FileInfo if finfo, err = osfile.Stat(); err != nil { return } log.Println("filesize", finfo.Size()) lr := &io.LimitedReader{R: osfile, N: finfo.Size()} var outfile *os.File if outfile, err = os.Create(filename + ".out.mp4"); err != nil { return } for lr.N > 0 { var ar *io.LimitedReader var cc4 string if ar, cc4, err = atom.ReadAtomHeader(lr, ""); err != nil { return } if cc4 == "moov" { curPos, _ := outfile.Seek(0, 1) origSize := ar.N + 8 var moov *atom.Movie if moov, err = atom.ReadMovie(ar); err != nil { return } //log.Println(moov.Tracks[0].Media.Info.Data.Refer) if err = atom.WriteMovie(outfile, moov); err != nil { return } curPosAfterRead, _ := outfile.Seek(0, 1) bytesWritten := curPosAfterRead - curPos log.Println("regen moov", "tracks nr", len(moov.Tracks), "origSize", origSize, "bytesWritten", bytesWritten, ) padSize := origSize - bytesWritten - 8 aw, _ := atom.WriteAtomHeader(outfile, "free") atom.WriteDummy(outfile, int(padSize)) aw.Close() } else { outcc4 := cc4 if outcc4 != "mdat" { log.Println("omit", cc4) outcc4 = "free" } else { log.Println("copy", cc4) } var aw *atom.Writer if aw, err = atom.WriteAtomHeader(outfile, outcc4); err != nil { return } if _, err = io.CopyN(aw, ar, ar.N); err != nil { return } if err = aw.Close(); err != nil { return } } //log.Println("atom", cc4, "left", lr.N) //atom.ReadDummy(ar, int(ar.N)) } if err = outfile.Close(); err != nil { return } return }