func ParseInfoElement(buf []byte) InfoElement { typeInfo := map[int]int{ IdTimecodeScale: ebml.TypeUint, IdDuration: ebml.TypeFloat, IdDateUTC: ebml.TypeInt} client := &infoParserClient{ timecodeScale: 1000000, duration: math.Inf(1), date: 0} parser := ebml.NewParser(ebml.GetListIDs(typeInfo), map[int][]int{}, ebml.NewElementParser(client, typeInfo)) if !parser.Append(buf) { log.Printf("Failed to parse info.") return nil } if client.TimecodeScale() == 0 || client.Duration() <= 0 { return nil } return client }
func (c *DemuxerClient) ParseBlockGroup(buf []byte) bool { if c.clusterTimecode == -1 { panic("Got a block group before the cluster timecode.") } typeInfo := map[int]int{ webm.IdBlock: ebml.TypeBinary, webm.IdBlockAdditions: ebml.TypeBinary, webm.IdBlockDuration: ebml.TypeUint, webm.IdReferenceBlock: ebml.TypeInt, webm.IdDiscardPadding: ebml.TypeInt, } bw := ebml.NewBufferWriter(len(buf)) bc := &BlockGroupClient{parsedBlock: false, writer: ebml.NewWriter(bw)} p := ebml.NewParser(ebml.GetListIDs(typeInfo), webm.UnknownSizeInfo(), ebml.NewElementParser(bc, typeInfo)) if !p.Append(buf) { log.Printf("Parser error") return false } p.EndOfData() id := bc.id rawTimecode := bc.rawTimecode flags := bc.flags timecode := c.clusterTimecode + rawTimecode //log.Printf("in track %d %d 0x%x %d\n", id, timecode, flags, len(buf)-3-idSize) if c.startTimecode == -1 { c.startTimecode = timecode } blockList, ok := c.blocks[id] if !ok { return false } c.blocks[id] = append(blockList, NewBlock(id, false, timecode, flags, bc.blockData, bw.Bytes())) c.tryWritingNextBlock() return true }
func main() { if len(os.Args) < 3 { fmt.Fprintf(os.Stderr, "Usage: %s <infile> <outfile>\n", os.Args[0]) return } var in io.Reader = nil if os.Args[1] == "-" { in = os.Stdin } else if strings.HasPrefix(os.Args[1], "ws://") { url, err := url.Parse(os.Args[1]) checkError("Output url", err) origin := "http://localhost/" ws, err := websocket.Dial(url.String(), "", origin) checkError("WebSocket Dial", err) in = io.Reader(ws) } else { file, err := os.Open(os.Args[1]) checkError(fmt.Sprintf("can't open file %s", os.Args[1]), err) in = io.Reader(file) } file, err := os.Create(os.Args[2]) checkError(fmt.Sprintf("Failed to create file %s", os.Args[2]), err) out := io.WriteSeeker(file) buf := [4096]byte{} c := NewTestClient(out) parser := ebml.NewParser(ebml.GetListIDs(webm.IdTypes()), webm.UnknownSizeInfo(), ebml.NewElementParser(c, webm.IdTypes())) for { bytesRead, err := in.Read(buf[:]) if err != nil { parser.EndOfData() break } parser.Append(buf[0:bytesRead]) } }
func main() { var minClusterDurationInMS int flag.IntVar(&minClusterDurationInMS, "cm", 250, "Minimum Cluster Duration (ms)") flag.Parse() if minClusterDurationInMS < 0 || minClusterDurationInMS > 30000 { log.Printf("Invalid minimum cluster duration\n") os.Exit(-1) } if len(flag.Args()) < 2 { log.Printf("Usage: %s [-cm <duration>] <infile> <outfile>\n", os.Args[0]) return } var in *os.File = nil var err error = nil inputArg := flag.Arg(0) outputArg := flag.Arg(1) if inputArg == "-" { in = os.Stdin } else { in, err = os.Open(inputArg) checkError("Open input", err) } var out *ebml.Writer = nil if outputArg == "-" { out = ebml.NewNonSeekableWriter(io.WriteSeeker(os.Stdout)) } else { if inputArg == outputArg { log.Printf("Input and output filenames can't be the same.\n") return } if strings.HasPrefix(outputArg, "ws://") { url, err := url.Parse(outputArg) checkError("Output url", err) origin := "http://localhost/" ws, err := websocket.Dial(url.String(), "", origin) checkError("WebSocket Dial", err) out = ebml.NewNonSeekableWriter(io.Writer(ws)) } else { file, err := os.Create(outputArg) if err != nil { log.Printf("Failed to create '%s'; err=%s\n", outputArg, err.Error()) os.Exit(1) } out = ebml.NewWriter(io.WriteSeeker(file)) } } buf := [1024]byte{} c := NewDemuxerClient(out, minClusterDurationInMS) typeInfo := map[int]int{ ebml.IdHeader: ebml.TypeBinary, webm.IdSegment: ebml.TypeList, webm.IdInfo: ebml.TypeBinary, webm.IdTracks: ebml.TypeBinary, webm.IdCluster: ebml.TypeList, webm.IdTimecode: ebml.TypeUint, webm.IdSimpleBlock: ebml.TypeBinary, } parser := ebml.NewParser(ebml.GetListIDs(typeInfo), webm.UnknownSizeInfo(), ebml.NewElementParser(c, typeInfo)) for done := false; !done; { bytesRead, err := in.Read(buf[:]) if err == io.EOF || err == io.ErrClosedPipe { parser.EndOfData() done = true continue } if !parser.Append(buf[0:bytesRead]) { log.Printf("Parser error") done = true continue } } }
func NewWebMParser() *ebml.Parser { c := newWebMClient() return ebml.NewParser(ebml.GetListIDs(webm.IdTypes()), webm.UnknownSizeInfo(), ebml.NewElementParser(c, webm.IdTypes())) }