BililiveRecorder/BililiveRecorder.Flv/Pipeline/Rules/HandleNewScriptRule.cs

118 lines
4.5 KiB
C#
Raw Normal View History

2021-02-08 16:51:19 +08:00
using System;
2021-02-23 18:03:37 +08:00
using System.Collections.Generic;
using BililiveRecorder.Flv.Amf;
using BililiveRecorder.Flv.Pipeline.Actions;
2021-02-08 16:51:19 +08:00
namespace BililiveRecorder.Flv.Pipeline.Rules
{
/// <summary>
2022-05-02 00:01:41 +08:00
/// 处理 Script Tag
2021-02-08 16:51:19 +08:00
/// </summary>
public class HandleNewScriptRule : ISimpleProcessingRule
{
private const string STORE_KEY = "HandleNewScriptRule_MetaDataReceived";
private const string onMetaData = "onMetaData";
2022-06-17 17:42:50 +08:00
private static readonly ProcessingComment comment_onmetadata = new ProcessingComment(CommentType.OnMetaData, false, "收到了 onMetaData");
2021-02-27 20:44:04 +08:00
2021-03-09 00:50:13 +08:00
public void Run(FlvProcessingContext context, Action next)
2021-02-08 16:51:19 +08:00
{
2021-03-09 00:50:13 +08:00
context.PerActionRun(this.RunPerAction);
next();
}
private IEnumerable<PipelineAction?> RunPerAction(FlvProcessingContext context, PipelineAction action)
{
ScriptTagBody? data;
2021-03-09 00:50:13 +08:00
if (action is PipelineScriptAction scriptAction)
2021-02-08 16:51:19 +08:00
{
data = scriptAction.Tag.ScriptData;
if (data is not null)
2021-02-23 18:03:37 +08:00
{
if (data.Values.Count == 2
&& data.Values[0] is ScriptDataString name
&& name == onMetaData)
2021-02-23 18:03:37 +08:00
{
goto IsOnMetaData;
}
else if (data.Values.Count == 3
&& data.Values[2] is ScriptDataNull
&& data.Values[0] is ScriptDataString name2
&& name2 == onMetaData)
{
/* d1--ov-gotcha07.bilivideo.com
* CNAME d1--ov-gotcha07.bilivideo.com.a.bcelive.com
* CNAME d1--ov-gotcha07.bilivideo.com.zengslb.com
* Singapore AS21859 Zenlayer Inc
*
* script tag NULL
*/
goto IsOnMetaData;
}
else
2021-02-23 18:03:37 +08:00
{
goto notOnMetaData;
}
2021-02-23 18:03:37 +08:00
}
else
{
goto notOnMetaData;
2021-02-23 18:03:37 +08:00
}
2021-02-08 16:51:19 +08:00
}
2021-02-23 18:03:37 +08:00
else
{
2021-03-09 00:50:13 +08:00
yield return action;
yield break;
}
IsOnMetaData:
ScriptDataEcmaArray value = data.Values[1] switch
{
ScriptDataObject obj => obj,
ScriptDataEcmaArray arr => arr,
_ => new ScriptDataEcmaArray()
};
var metaDataReceived = context.SessionItems.ContainsKey(STORE_KEY);
if (!metaDataReceived)
{
context.SessionItems[STORE_KEY] = true;
context.AddComment(comment_onmetadata);
yield return PipelineNewFileAction.Instance;
yield return (new PipelineScriptAction(new Tag
{
Type = TagType.Script,
ScriptData = new ScriptTagBody(new List<IScriptDataValue>
{
(ScriptDataString)onMetaData,
value
})
}));
yield break;
}
else
{
// 记录信息,不对文件进行分段。
var message = $"收到直播服务器发送的 onMetaData 数据,请检查此位置是否有重复的直播片段或缺少数据。\n造成这个问题的原因可能是录播姬所连接的直播服务器与它的上级服务器的连接断开重连了。\n数据内容: {data?.ToJson() ?? "(null)"}";
2022-06-17 17:42:50 +08:00
context.AddComment(new ProcessingComment(CommentType.OnMetaData, false, message));
yield return new PipelineLogMessageWithLocationAction(message);
yield return (new PipelineScriptAction(new Tag
{
Type = TagType.Script,
ScriptData = new ScriptTagBody(new List<IScriptDataValue>
{
(ScriptDataString)onMetaData,
value
})
}));
yield break;
}
notOnMetaData:
2022-06-17 17:42:50 +08:00
context.AddComment(new ProcessingComment(CommentType.Logging, false, "收到了非 onMetaData 的 Script Tag: " + (data?.ToJson() ?? "(null)")));
yield break;
2021-02-08 16:51:19 +08:00
}
}
}