public FlvClipProcessor(FlvMetadata header, List <FlvTag> head, List <FlvTag> past, uint future) { Header = header; HTags = head; Tags = past; target = Tags[Tags.Count - 1].TimeStamp + (int)(future * FlvStreamProcessor.SEC_TO_MS); logger.Debug("Clip 创建 Tags.Count={0} Tags[0].TimeStamp={1} Tags[Tags.Count-1].TimeStamp={2} Tags里秒数={3}", Tags.Count, Tags[0].TimeStamp, Tags[Tags.Count - 1].TimeStamp, (Tags[Tags.Count - 1].TimeStamp - Tags[0].TimeStamp) / 1000d); }
public static FlvMetadata Parse(byte[] data) { var m = new FlvMetadata { Meta = _Decode(data) }; if (!m.Meta.ContainsKey("duration")) { m.Meta["duration"] = 0.0; } if (!m.Meta.ContainsKey("lasttimestamp")) { m.Meta["lasttimestamp"] = 0.0; } return(m); }
private void _TagCreated(FlvTag tag) { if (Metadata == null) { if (tag.TagType == TagType.DATA) { _fs?.Write(FLV_HEADER_BYTES, 0, FLV_HEADER_BYTES.Length); _fs?.Write(new byte[] { 0, 0, 0, 0, }, 0, 4); Metadata = FlvMetadata.Parse(tag.Data); // TODO: 添加录播姬标记、录制信息 tag.Data = Metadata.ToBytes(); tag.WriteTo(_fs); } else { throw new Exception("onMetaData not found"); } } else { if (!hasOffset) { if (tag.TagType == TagType.VIDEO) { TagVideoCount++; if (TagVideoCount < 2) { logger.Trace("第一个 Video Tag 时间戳 {0} ms", tag.TimeStamp); HTags.Add(tag); } else { BaseTimeStamp = tag.TimeStamp; hasOffset = true; logger.Trace("重设时间戳 {0} 毫秒", BaseTimeStamp); } } else if (tag.TagType == TagType.AUDIO) { TagAudioCount++; if (TagAudioCount < 2) { logger.Trace("第一个 Audio Tag 时间戳 {0} ms", tag.TimeStamp); HTags.Add(tag); } else { BaseTimeStamp = tag.TimeStamp; hasOffset = true; logger.Trace("重设时间戳 {0} 毫秒", BaseTimeStamp); } } } if (hasOffset) { tag.TimeStamp -= BaseTimeStamp; // 修复时间戳 if (tag.TimeStamp < 0) { tag.TimeStamp = 0; } MaxTimeStamp = Math.Max(MaxTimeStamp, tag.TimeStamp); } else { tag.TimeStamp = 0; } // 如果没有禁用 Clip 功能 if (!_noClip) { Tags.Add(tag); // Clip 缓存 // 移除过旧的数据 if (MaxTimeStamp - LasttimeRemovedTimestamp > 800) { LasttimeRemovedTimestamp = MaxTimeStamp; int max_remove_index = Tags.FindLastIndex(x => x.IsVideoKeyframe && ((MaxTimeStamp - x.TimeStamp) > (Clip_Past * SEC_TO_MS))); if (max_remove_index > 0) { Tags.RemoveRange(0, max_remove_index); } // Tags.RemoveRange(0, max_remove_index + 1 - 1); // 给将来的备注:这里是故意 + 1 - 1 的,因为要保留选中的那个关键帧, + 1 就把关键帧删除了 } } // 写入硬盘 tag.WriteTo(_fs); TagProcessed?.Invoke(this, new TagProcessedArgs() { Tag = tag }); } // if (Metadata == null) else }