This commit is contained in:
Genteure 2018-03-19 01:05:02 +08:00
parent 6fb17543dc
commit 2459867f8f
10 changed files with 160 additions and 41 deletions

View File

@ -25,7 +25,7 @@ namespace BililiveRecorder.Core
public RecordedRoom()
{
Processor.BlockProcessed += Processor_BlockProcessed;
Processor.TagProcessed += Processor_TagProcessed;
streamMonitor.StreamStatusChanged += StreamMonitor_StreamStatusChanged;
UpdateRoomInfo();
@ -171,9 +171,9 @@ namespace BililiveRecorder.Core
}
}
private void Processor_BlockProcessed(object sender, BlockProcessedArgs e)
private void Processor_TagProcessed(object sender, TagProcessedArgs e)
{
Clips.ToList().ForEach((fcp) => fcp.AddBlock(e.DataBlock));
Clips.ToList().ForEach((fcp) => fcp.AddTag(e.Tag));
}

View File

@ -1,11 +1,10 @@
namespace BililiveRecorder.FlvProcessor
{
public enum TagType
public enum TagType : int
{
NONE = 0x0,
AUDIO = 0x8,
VIDEO = 0x9,
META = 0x12,
AUDIO = 8,
VIDEO = 9,
DATA = 18,
}
public enum AMFTypes

View File

@ -4,10 +4,10 @@ using System.Text;
namespace BililiveRecorder.FlvProcessor
{
public delegate void BlockProcessedEvent(object sender, BlockProcessedArgs e);
public class BlockProcessedArgs
public delegate void TagProcessedEvent(object sender, TagProcessedArgs e);
public class TagProcessedArgs
{
public FlvDataBlock DataBlock;
public FlvTag Tag;
}

View File

@ -6,16 +6,16 @@ namespace BililiveRecorder.FlvProcessor
{
public class FlvClipProcessor : IDisposable
{
public readonly FlvHeader Header;
public readonly FlvMetadata Header;
public FlvClipProcessor(FlvHeader header)
public FlvClipProcessor(FlvMetadata header)
{
Header = header;
}
public void AddBlock(FlvDataBlock block)
public void AddTag(FlvTag tag)
{
throw new NotImplementedException();
}

View File

@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BililiveRecorder.FlvProcessor
{
public class FlvDataBlock
{
}
}

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BililiveRecorder.FlvProcessor
{
public class FlvHeader
{
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BililiveRecorder.FlvProcessor
{
public class FlvMetadata
{
public byte[] ToBytes()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
@ -7,13 +10,19 @@ namespace BililiveRecorder.FlvProcessor
{
public class FlvStreamProcessor : IDisposable
{
private const int MIN_BUFFER_SIZE = 1024 * 2;
public RecordInfo Info; // not used for now.
public readonly FlvHeader Header = new FlvHeader();
private readonly List<FlvDataBlock> dataBlocks = new List<FlvDataBlock>();
public readonly FlvMetadata Metadata = new FlvMetadata();
public event TagProcessedEvent TagProcessed;
private byte[] headers;
public event BlockProcessedEvent BlockProcessed;
private bool _headerParsed = false;
private readonly List<FlvTag> Tags = new List<FlvTag>();
private readonly MemoryStream _buffer = new MemoryStream();
private readonly MemoryStream _data = new MemoryStream();
private FlvTag currentTag = null;
public FlvStreamProcessor(RecordInfo info)
{
@ -22,7 +31,86 @@ namespace BililiveRecorder.FlvProcessor
public void AddBytes(byte[] data)
{
throw new NotImplementedException();
// lock ( ) { _AddBytes() }
}
private void _AddBytes(byte[] data)
{
if (currentTag == null)
{
if (_buffer.Position >= MIN_BUFFER_SIZE)
{
_ParseTag(data);
}
}
else
{
_WriteTagData(data);
}
}
private void _WriteTagData(byte[] data)
{
int toRead = Math.Min(data.Length, (currentTag.TagSize - (int)_data.Position));
_data.Write(data, 0, toRead);
if ((int)_data.Position == currentTag.TagSize)
{
currentTag.Data = _data.ToArray();
_data.SetLength(0); // reset data buffer
_TagCreated(currentTag);
currentTag = null;
_AddBytes(data.Skip(toRead).ToArray());
}
}
private void _TagCreated(FlvTag tag)
{
tag.TimeStamp -= 0;//TODO: 修复时间戳
Tags.Add(tag);
// TODO: remove old tag
TagProcessed?.Invoke(this, new TagProcessedArgs() { Tag = tag });
if (tag.TagType == TagType.DATA)
{
// TODO: onMetaData
}
}
private void _ParseTag(byte[] data)
{
byte[] b = { 0, 0, 0, 0, };
_buffer.Write(data, 0, data.Length);
long dataLen = _buffer.Position;
_buffer.Position = 0;
FlvTag tag = new FlvTag();
// TagType UI8
tag.TagType = (TagType)_buffer.ReadByte();
Debug.Write(string.Format("Tag Type: {0}\n", tag.TagType));
// DataSize UI24
_buffer.Read(b, 1, 3);
tag.TagSize = BitConverter.ToInt32(b.ToBE(), 0); // TODO: test this
// Timestamp UI24
_buffer.Read(b, 1, 3);
// TimestampExtended UI8
_buffer.Read(b, 0, 1);
tag.TimeStamp = BitConverter.ToInt32(b.ToBE(), 0);
// StreamID UI24
_buffer.Read(tag.StreamId, 0, 3);
currentTag = tag;
byte[] rest = _buffer.GetBuffer().Skip((int)_buffer.Position).Take((int)(dataLen - _buffer.Position)).ToArray();
_buffer.Position = 0;
_AddBytes(rest);
}
private void _ParseHeader()
{
}
public FlvClipProcessor Clip()

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BililiveRecorder.FlvProcessor
{
public class FlvTag
{
public TagType TagType = 0;
public int TagSize = 0;
public int TimeStamp = 0;
public byte[] StreamId = new byte[3];
public byte[] Data = null;
public byte[] ToBytes()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Linq;
namespace BililiveRecorder.FlvProcessor
{
internal static class Utils
{
internal static byte[] ToBE(this byte[] b)
{
if (BitConverter.IsLittleEndian)
return b.Reverse().ToArray();
else
return b;
}
}
}