using System.Linq;
using System.Threading.Tasks;
namespace BililiveRecorder.Flv.Pipeline.Rules
{
///
/// 处理延后收到的音频头
///
///
/// 本规则应该放在所有规则前面
///
public class HandleDelayedAudioHeaderRule : IFullProcessingRule
{
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.DecodingHeader, "检测到延后收到的音频头");
public Task RunAsync(FlvProcessingContext context, ProcessingDelegate next)
{
if (context.OriginalInput is PipelineDataAction dataAction)
{
if (!dataAction.Tags.Any(x => x.IsHeader()))
return next(context);
else
return this.RunAsyncCore(dataAction, context, next);
}
else
return next(context);
}
private async Task RunAsyncCore(PipelineDataAction dataAction, FlvProcessingContext context, ProcessingDelegate next)
{
context.ClearOutput();
context.AddComment(comment);
var tags = dataAction.Tags;
var index = tags.IndexOf(tags.Last(x => x.Flag == TagFlag.Header));
for (var i = 0; i < index; i++)
{
if (tags[i].Type == TagType.Audio)
{
context.AddDisconnectAtStart();
return;
}
}
var headerTags = tags.Where(x => x.Flag == TagFlag.Header).ToList();
var newHeaderAction = new PipelineHeaderAction(headerTags);
var dataTags = tags.Where(x => x.Flag != TagFlag.Header).ToList();
var newDataAction = new PipelineDataAction(dataTags);
var localContext = new FlvProcessingContext(newHeaderAction, context.SessionItems);
await next(localContext).ConfigureAwait(false);
context.Output.AddRange(localContext.Output);
context.Comments.AddRange(localContext.Comments);
localContext.Reset(newDataAction, context.SessionItems);
await next(localContext).ConfigureAwait(false);
context.Output.AddRange(localContext.Output);
context.Comments.AddRange(localContext.Comments);
}
}
}