示例#1
0
func permitSkip(frame flv.Frame) (isSkip bool) {
	if frame.GetType() == flv.TAG_TYPE_META {
		metaBody := frame.GetBody()
		buf := bytes.NewReader(*metaBody)
		dec := amf0.NewDecoder(buf)
		evName, err := dec.Decode()
		if err == nil {
			switch evName {
			case amf0.StringType("onMetaData"):
				md, err := dec.Decode()
				if err == nil {
					var ea map[amf0.StringType]interface{}
					switch md := md.(type) {
					case *amf0.EcmaArrayType:
						ea = *md
					case *amf0.ObjectType:
						ea = *md
					}
					for skipK, skipV := range skipMeta {
						if s, ok := ea[amf0.StringType(skipK)]; ok {
							for _, t := range skipV {
								if amf0.StringType(t) == s {
									return true
								}
							}
						}
					}
				}
			}
		}
	}
	return false
}
示例#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
}