BililiveRecorder/BililiveRecorder.FlvProcessor/FlvClipProcessor.cs

72 lines
2.2 KiB
C#
Raw Normal View History

2018-03-12 18:57:20 +08:00
using System;
using System.Collections.Generic;
2018-03-19 16:51:35 +08:00
using System.IO;
2018-03-12 18:57:20 +08:00
using System.Text;
namespace BililiveRecorder.FlvProcessor
{
2018-03-21 20:56:56 +08:00
public class FlvClipProcessor
2018-03-12 18:57:20 +08:00
{
2018-03-19 01:05:02 +08:00
public readonly FlvMetadata Header;
2018-03-21 00:33:34 +08:00
public readonly List<FlvTag> Tags;
2018-03-19 16:51:35 +08:00
private int target = -1;
2018-03-12 18:57:20 +08:00
2018-03-20 00:12:32 +08:00
public Func<string> GetFileName;
2018-03-19 16:51:35 +08:00
public FlvClipProcessor(FlvMetadata header, List<FlvTag> past, int future)
2018-03-12 18:57:20 +08:00
{
2018-03-13 13:21:01 +08:00
Header = header;
2018-03-19 16:51:35 +08:00
Tags = past;
2018-03-19 17:35:27 +08:00
target = Tags[Tags.Count - 1].TimeStamp + (future * FlvStreamProcessor.SEC_TO_MS);
2018-03-12 18:57:20 +08:00
}
2018-03-19 01:05:02 +08:00
public void AddTag(FlvTag tag)
2018-03-13 13:21:01 +08:00
{
2018-03-19 16:51:35 +08:00
Tags.Add(tag);
if (tag.TimeStamp >= target)
{
FinallizeFile();
}
2018-03-13 13:21:01 +08:00
}
2018-03-19 16:51:35 +08:00
public void FinallizeFile()
{
2018-03-20 00:12:32 +08:00
using (var fs = new FileStream(GetFileName(), FileMode.CreateNew, FileAccess.ReadWrite))
2018-03-19 16:51:35 +08:00
{
fs.Write(FlvStreamProcessor.FLV_HEADER_BYTES, 0, FlvStreamProcessor.FLV_HEADER_BYTES.Length);
Header.Meta["duration"] = Tags[Tags.Count - 1].TimeStamp / 1000.0;
Header.Meta["lasttimestamp"] = (double)Tags[Tags.Count - 1].TimeStamp;
2018-03-21 20:56:56 +08:00
var t = new FlvTag
{
TagType = TagType.DATA,
Data = Header.ToBytes()
};
2018-03-19 16:51:35 +08:00
var b = t.ToBytes();
fs.Write(b, 0, b.Length);
fs.Write(t.Data, 0, t.Data.Length);
fs.Write(BitConverter.GetBytes(t.Data.Length + b.Length).ToBE(), 0, 4);
int timestamp = Tags[0].TimeStamp;
Tags.ForEach(tag =>
{
tag.TimeStamp -= timestamp;
var vs = tag.ToBytes();
fs.Write(vs, 0, vs.Length);
fs.Write(tag.Data, 0, tag.Data.Length);
fs.Write(BitConverter.GetBytes(tag.Data.Length + vs.Length).ToBE(), 0, 4);
});
fs.Close();
}
2018-03-21 00:33:34 +08:00
Tags.Clear();
2018-03-19 16:51:35 +08:00
ClipFinalized?.Invoke(this, new ClipFinalizedArgs() { ClipProcessor = this });
}
2018-03-13 13:21:01 +08:00
public event ClipFinalizedEvent ClipFinalized;
2018-03-12 18:57:20 +08:00
}
}