示例#1
0
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() {
	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
		}
	}
}