예제 #1
0
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
}
예제 #2
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
}
예제 #3
0
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])
	}
}
예제 #4
0
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
		}
	}
}
예제 #5
0
func NewWebMParser() *ebml.Parser {
	c := newWebMClient()

	return ebml.NewParser(ebml.GetListIDs(webm.IdTypes()), webm.UnknownSizeInfo(),
		ebml.NewElementParser(c, webm.IdTypes()))
}