Esempio n. 1
0
func writeStreamFrame(rframe flv.Frame, baseDts int) (err error) {
	if streamsWriters == nil {
		streamsWriters = make(map[uint32]*streamWriter)
	}
	stream := rframe.GetStream()
	var stWr *streamWriter
	if _, ok := streamsWriters[stream]; !ok {
		log.Printf("Write new stream %d from dts %d", stream, baseDts)
		splitFileNumber++
		stWr = new(streamWriter)
		stWr.fileName = fmt.Sprintf("n-%05d-ts-%d-s-%d.flv", splitFileNumber, baseDts, stream)
		stWr.fd, err = os.Create(stWr.fileName)
		if err != nil {
			log.Fatalf("Cannot open file %s: %s", stWr.fileName, err.Error())
		}
		stWr.writer = flv.NewWriter(stWr.fd)
		stWr.writer.WriteHeader(commonHeader)
		stWr.firstDts = baseDts
		stWr.offsetDts = rframe.GetDts()
		streamsWriters[stream] = stWr
	} else {
		stWr = streamsWriters[stream]
	}
	rframe.SetDts(rframe.GetDts() - stWr.offsetDts)
	stWr.writer.WriteFrame(rframe)
	stWr.lastDts = baseDts
	return nil
}
Esempio n. 2
0
func writeFrames(frReader *flv.FlvReader, frW map[flv.TagType]*flv.FlvWriter, offset int) (outOffset int) {
	lastTs := make(map[flv.TagType]map[uint32]uint32)
	lastTsDiff := make(map[flv.TagType]map[uint32]uint32)
	shiftTs := make(map[flv.TagType]map[uint32]uint32)
	for _, c := range []flv.TagType{flv.TAG_TYPE_VIDEO, flv.TAG_TYPE_AUDIO, flv.TAG_TYPE_META} {
		lastTs[c] = make(map[uint32]uint32)
		lastTsDiff[c] = make(map[uint32]uint32)
		shiftTs[c] = make(map[uint32]uint32)
	}

	updateDts := func(cframe flv.Frame) (newDts uint32) {
		c := cframe.GetType()
		s := cframe.GetStream()
		d := cframe.GetDts()
		if lastTs[c][s] > d {
			warnTs(lastTs[c][s], s, d)
			if fixDts {
				newDts := lastTs[c][s] + lastTsDiff[c][s]
				shiftTs[c][s] = newDts - d
				d += shiftTs[c][s]
			}
		}
		d = uint32(int(float64(d)*scaleDts) + offset)
		lastTsDiff[c][s] = d - lastTs[c][s]
		lastTs[c][s] = d
		return d
	}

	var lastInTs uint32 = 0
	var compensateTs uint32 = 0
	for {
		var rframe flv.Frame
		var err error
		var skipBytes int

		rframe, rerr := frReader.ReadFrame()
		switch {
		case rerr != nil && !readRecover:
			log.Fatal(rerr)
		case rerr != nil && rerr.IsRecoverable():
			rframe, err, skipBytes = frReader.Recover(rerr, maxScanSize)
			if err != nil {
				log.Fatalf("recovery error: %s", err)
			}
			log.Printf("recover: got fine frame after %d bytes", skipBytes)
			continue
		}

		if rframe != nil {

			// if rframe.GetType() == flv.TAG_TYPE_META {
			// 	metaBody := rframe.GetBody()
			// 	buf := bytes.NewReader(*metaBody)
			// 	dec := amf0.NewDecoder(buf)
			// 	_, err := dec.Decode()
			// 	if err != nil {
			// 		log.Printf("Bad metadata at DTS %d", rframe.GetDts())
			// 		continue
			// 	}
			// }

			isCrop := permitCrop(rframe)
			isSkip := permitSkip(rframe)
			isSplitStream := splitStreams && rframe.GetStream() != 0 && rframe.GetType() != flv.TAG_TYPE_META
			if (streams[rframe.GetType()] != -1 && rframe.GetStream() != uint32(streams[rframe.GetType()])) || isCrop || isSkip || isSplitStream {
				if compensateDts || isCrop {
					compensateTs += (rframe.GetDts() - lastInTs)
				}
				lastInTs = rframe.GetDts()
				if splitStreams {
					err = writeStreamFrame(rframe, outOffset)
					if err != nil {
						log.Fatal(err)
					}
				}
				continue
			}
			checkSplitWriters(outOffset)
			lastInTs = rframe.GetDts()
			newDts := updateDts(rframe) - compensateTs
			if rframe.GetStream() == 0 {
				outOffset = int(newDts)
			}
			rframe.SetDts(newDts)
			err = frW[rframe.GetType()].WriteFrame(rframe)
			if err != nil {
				log.Fatal(err)
			}
		} else {
			break
		}
	}
	return
}