func Parse(r io.ReadSeeker, m *WebM) (wr *Reader, err error) { var e *ebml.Element e, err = ebml.RootElement(r) if err == nil { err = e.Unmarshal(m) dt := m.Header.DocType if dt != "webm" && dt != "webm\000" { err = errors.New("Not a WebM file") } if err != nil && err.Error() == "Reached payload" { segment := err.(ebml.ReachedPayloadError).Element sh, _ := segment.Next() sh.Unmarshal(&m.SeekHead) pos := m.cuesPosition() if pos > 0 { curr, _ := segment.Seek(0, 1) segment.Seek(pos+sh.Offset, 0) ce, _ := segment.Next() ce.Unmarshal(&m.Segment.Cues) segment.Seek(curr, 0) } segment.Unmarshal(&m.Segment) payload := err.(ebml.ReachedPayloadError).Element wr = newReader(payload, m.Segment.Cues.CuePoint, sh.Offset) err = nil } } return }
func (r *Reader) sendCluster(elmts *ebml.Element, tbase time.Duration) { var err error for err == nil && len(r.seek) == 0 { var e *ebml.Element e, err = elmts.Next() var blk []byte if err == nil { switch e.Id { case 0xa3: if err == nil { blk, err = e.ReadData() } if err != nil && err != io.EOF { log.Println(err) } case 0xa0: var bg BlockGroup err = e.Unmarshal(&bg) if err == nil { blk = bg.Block } if err != nil && err != io.EOF { log.Println(err) } default: log.Printf("Unexpected packet %x", e.Id) } if err == nil && blk != nil && len(blk) > 4 { r.sendBlock(blk, tbase) } } } }
func (r *Reader) parseClusters(elmts *ebml.Element) { var err error for err == nil { var c Cluster var e *ebml.Element e, err = elmts.Next() if err == nil { err = e.Unmarshal(&c) } if err != nil && err.Error() == "Reached payload" { r.index.append(seekEntry{time.Millisecond * time.Duration(c.Timecode), e.Offset}) r.sendCluster(err.(ebml.ReachedPayloadError).Element, time.Millisecond*time.Duration(c.Timecode)) err = nil } seek := BadTC for len(r.seek) != 0 { seek = <-r.seek } if err == io.EOF { var eofpkt Packet eofpkt.Timecode = BadTC r.send(&eofpkt) seek = <-r.seek if seek != BadTC { err = nil } } if seek != BadTC { entry := r.index.search(seek) elmts.Seek(entry.offset, 0) var seekpkt Packet seekpkt.Timecode = seek r.send(&seekpkt) } if seek == shutdown { err = io.EOF } } close(r.Chan) }