FLV: Merge and clean up flv test projects

This commit is contained in:
genteure 2021-11-13 02:01:03 +08:00
parent 7669c865fe
commit c9419bfa0a
82 changed files with 8749 additions and 51178 deletions

View File

@ -2,6 +2,12 @@ namespace BililiveRecorder.Flv.Pipeline.Actions
{
public abstract class PipelineAction
{
protected PipelineAction()
{
this.Name = this.GetType().Name;
}
public string Name { get; }
public abstract PipelineAction Clone();
}
}

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29924.181
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FD13D9F6-94CD-4CBA-AEA8-EF71002EAC6B}"
ProjectSection(SolutionItems) = preProject
@ -25,11 +25,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.Flv", "Bil
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.Core.UnitTests", "test\BililiveRecorder.Core.UnitTests\BililiveRecorder.Core.UnitTests.csproj", "{521EC763-5694-45A8-B87F-6E6B7F2A3BD4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.Flv.UnitTests", "test\BililiveRecorder.Flv.UnitTests\BililiveRecorder.Flv.UnitTests.csproj", "{560E8483-9293-410E-81E9-AB36B49F8A7C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.ToolBox", "BililiveRecorder.ToolBox\BililiveRecorder.ToolBox.csproj", "{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.Flv.RuleTests", "test\BililiveRecorder.Flv.RuleTests\BililiveRecorder.Flv.RuleTests.csproj", "{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BililiveRecorder.ToolBox", "BililiveRecorder.ToolBox\BililiveRecorder.ToolBox.csproj", "{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BililiveRecorder.Flv.Tests", "test\BililiveRecorder.Flv.Tests\BililiveRecorder.Flv.Tests.csproj", "{32E554B1-0ECC-4145-85B8-3FC128FEBEA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -57,18 +55,14 @@ Global
{521EC763-5694-45A8-B87F-6E6B7F2A3BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{521EC763-5694-45A8-B87F-6E6B7F2A3BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{521EC763-5694-45A8-B87F-6E6B7F2A3BD4}.Release|Any CPU.Build.0 = Release|Any CPU
{560E8483-9293-410E-81E9-AB36B49F8A7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{560E8483-9293-410E-81E9-AB36B49F8A7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{560E8483-9293-410E-81E9-AB36B49F8A7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{560E8483-9293-410E-81E9-AB36B49F8A7C}.Release|Any CPU.Build.0 = Release|Any CPU
{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC}.Release|Any CPU.Build.0 = Release|Any CPU
{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200}.Release|Any CPU.Build.0 = Release|Any CPU
{32E554B1-0ECC-4145-85B8-3FC128FEBEA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32E554B1-0ECC-4145-85B8-3FC128FEBEA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32E554B1-0ECC-4145-85B8-3FC128FEBEA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32E554B1-0ECC-4145-85B8-3FC128FEBEA1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -79,9 +73,8 @@ Global
{1B626335-283F-4313-9045-B5B96FAAB2DF} = {2D44A59D-E437-4FEE-8A2E-3FF00D53A64D}
{7610E19C-D3AB-4CBC-983E-6FDA36F4D4B3} = {2D44A59D-E437-4FEE-8A2E-3FF00D53A64D}
{521EC763-5694-45A8-B87F-6E6B7F2A3BD4} = {623A2ACC-DAC6-4E6F-9242-B4B54381AAE1}
{560E8483-9293-410E-81E9-AB36B49F8A7C} = {623A2ACC-DAC6-4E6F-9242-B4B54381AAE1}
{75DA0162-DE06-4FA0-B6F8-C82C11AF65BC} = {623A2ACC-DAC6-4E6F-9242-B4B54381AAE1}
{4FAAE8E7-AC4E-4E99-A7D1-53D20AD8A200} = {2D44A59D-E437-4FEE-8A2E-3FF00D53A64D}
{32E554B1-0ECC-4145-85B8-3FC128FEBEA1} = {623A2ACC-DAC6-4E6F-9242-B4B54381AAE1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
RESX_SortFileContentOnSave = True

View File

@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Spectre.Verify.Extensions" Version="0.5.0" />
<PackageReference Include="Verify.Xunit" Version="13.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BililiveRecorder.Flv\BililiveRecorder.Flv.csproj" />
</ItemGroup>
</Project>

View File

@ -1,41 +0,0 @@
# 有问题的测试样本
## 文件夹结构
每个样本文件夹内至少有 3 个文件
- `input.xml``input.xml.gz` - 样本数据
- `info.json` - 测试通过的标准
- `README.md` - 问题的具体说明和备注
## 文件夹命名方式
`问题程度-文件来源-日期-简单问题描述`
举例:
`p1-brec_std-20210121-double_audio_header`
### 问题程度
对某个测试样本的复杂程度和迷惑程度的主观评价,主要为了方便排序。大概的评分标准是:
- `p1` 一个很简单、无关紧要的小问题
- `p2` 一个或多个小问题
- `p3` 会影响播放的问题
- `p4` 比较复杂的问题
- `p5` 在没救了的边缘摩擦
### 问题来源
样本原文件的生成或录制工具,如录播姬(本项目)或 ffmpeg 等。
- `mock` 手动修改一个正常样本得到的问题样本
- `brec_std` 录播姬 1.3+ 标准模式
- `brec_raw` 录播姬 1.3+ 原始数据模式
- `brec_legacy` 录播姬 1.2 及以下版本
- `ffmpeg` ffmpeg
### 日期
`年年年年月月日日` 格式的日期。

View File

@ -1,168 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
文件连续出现多个不同的 Header
-->
<BililiveRecorderFlv xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Tags>
<Tag Type="Script" Flag="None" Size="293" Timestamp="0">
<ScriptData>[{"Type":"String","Value":"onMetaData"},{"Type":"EcmaArray","Value":{"duration":{"Type":"Number","Value":22.233},"width":{"Type":"Number","Value":1920.0},"height":{"Type":"Number","Value":1080.0},"videodatarate":{"Type":"Number","Value":1464.84375},"framerate":{"Type":"Number","Value":30.0},"videocodecid":{"Type":"Number","Value":7.0},"audiodatarate":{"Type":"Number","Value":156.25},"audiosamplerate":{"Type":"Number","Value":48000.0},"audiosamplesize":{"Type":"Number","Value":16.0},"stereo":{"Type":"Boolean","Value":true},"audiocodecid":{"Type":"Number","Value":10.0},"encoder":{"Type":"String","Value":"Lavf58.29.100"},"filesize":{"Type":"Number","Value":524554.0}}}]</ScriptData>
</Tag>
<Tag Type="Video" Flag="Header Keyframe" Size="49" Timestamp="0">
<BinaryData>170000000001640028FFE1001D67640028ACD940780227E59A808080A0000003002000000791E30632C001000468EF8FCBBABABABABABA</BinaryData>
</Tag>
<Tag Type="Audio" Flag="Header" Size="7" Timestamp="0">
<BinaryData>AF00119056E500FFFFFFFFFFFFFFFF</BinaryData>
</Tag>
<Tag Type="Video" Flag="Header Keyframe" Size="49" Timestamp="0">
<BinaryData>170000000001640028FFE1001D67640028ACD940780227E59A808080A0000003002000000791E30632C001000468EF8FCB</BinaryData>
</Tag>
<Tag Type="Audio" Flag="Header" Size="7" Timestamp="0">
<BinaryData>AF00119056E500AAAAAAAAAAAA</BinaryData>
</Tag>
<Tag Type="Audio" Flag="Header" Size="7" Timestamp="0">
<BinaryData>AF00119056E500</BinaryData>
</Tag>
<Tag Type="Video" Flag="Keyframe" Size="1993" Timestamp="0">
<Nalus StartPosition="9" FullSize="753" Type="Sei" />
<Nalus StartPosition="766" FullSize="29" Type="Sps" />
<Nalus StartPosition="799" FullSize="4" Type="Pps" />
<Nalus StartPosition="807" FullSize="753" Type="Sei" />
<Nalus StartPosition="1564" FullSize="429" Type="CodedSliceOfAnIdrPicture" />
</Tag>
<Tag Type="Video" Flag="None" Size="76" Timestamp="34">
<Nalus StartPosition="9" FullSize="67" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Video" Flag="None" Size="73" Timestamp="67">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="405" Timestamp="67" />
<Tag Type="Audio" Flag="None" Size="481" Timestamp="88" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="100">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="444" Timestamp="110" />
<Tag Type="Audio" Flag="None" Size="431" Timestamp="131" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="134">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="329" Timestamp="152" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="167">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="336" Timestamp="174" />
<Tag Type="Audio" Flag="None" Size="339" Timestamp="195" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="200">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="337" Timestamp="216" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="234">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="355" Timestamp="238" />
<Tag Type="Audio" Flag="None" Size="409" Timestamp="259" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="267">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="401" Timestamp="280" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="300">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="409" Timestamp="302" />
<Tag Type="Audio" Flag="None" Size="411" Timestamp="323" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="334">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="443" Timestamp="344" />
<Tag Type="Audio" Flag="None" Size="394" Timestamp="366" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="367">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="425" Timestamp="387" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="400">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="432" Timestamp="408" />
<Tag Type="Audio" Flag="None" Size="424" Timestamp="430" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="434">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="415" Timestamp="451" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="467">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="475" Timestamp="472" />
<Tag Type="Audio" Flag="None" Size="462" Timestamp="494" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="500">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="415" Timestamp="515" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="534">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="425" Timestamp="536" />
<Tag Type="Audio" Flag="None" Size="422" Timestamp="558" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="567">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="418" Timestamp="579" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="600">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="401" Timestamp="600" />
<Tag Type="Audio" Flag="None" Size="415" Timestamp="622" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="634">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="419" Timestamp="643" />
<Tag Type="Audio" Flag="None" Size="412" Timestamp="664" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="667">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="438" Timestamp="686" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="700">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="426" Timestamp="707" />
<Tag Type="Audio" Flag="None" Size="425" Timestamp="728" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="734">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="447" Timestamp="750" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="767">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="404" Timestamp="771" />
<Tag Type="Audio" Flag="None" Size="442" Timestamp="792" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="800">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="440" Timestamp="814" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="834">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="439" Timestamp="835" />
<Tag Type="Audio" Flag="None" Size="425" Timestamp="856" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="867">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="471" Timestamp="878" />
<Tag Type="Audio" Flag="None" Size="466" Timestamp="899" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="900">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="447" Timestamp="920" />
<Tag Type="Video" Flag="None" Size="73" Timestamp="934">
<Nalus StartPosition="9" FullSize="64" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="455" Timestamp="942" />
<Tag Type="Audio" Flag="None" Size="450" Timestamp="963" />
<Tag Type="Video" Flag="None" Size="77" Timestamp="967">
<Nalus StartPosition="9" FullSize="68" Type="CodedSliceOfANonIdrPicture" />
</Tag>
<Tag Type="Audio" Flag="None" Size="409" Timestamp="984" />
<Tag Type="Video" Flag="None" Size="75" Timestamp="1000">
<Nalus StartPosition="9" FullSize="66" Type="CodedSliceOfANonIdrPicture" />
</Tag>
</Tags>
</BililiveRecorderFlv>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,14 +2,18 @@ using System;
using System.Collections.Generic;
using BililiveRecorder.Flv.Amf;
using FluentAssertions;
using VerifyTests;
using VerifyXunit;
using Xunit;
namespace BililiveRecorder.Flv.UnitTests.Amf
namespace BililiveRecorder.Flv.Tests.AmfTests
{
public class SerializationTests
[UsesVerify]
[ExpectationPath("Amf")]
public class AmfSerializerTests
{
[Theory, MemberData(nameof(GetTestData))]
public void EqualAfterJsonSerialization(ScriptTagBody input)
public void ShouldEqualAfterJsonSerialization(int index, ScriptTagBody input)
{
var json = input.ToJson();
var body2 = ScriptTagBody.Parse(json);
@ -17,10 +21,12 @@ namespace BililiveRecorder.Flv.UnitTests.Amf
body2.Should().BeEquivalentTo(input, options => options.RespectingRuntimeTypes());
json2.Should().Be(json);
Assert.Equal(index, index); // Suppress warnings
}
[Theory, MemberData(nameof(GetTestData))]
public void EqualAfterBinarySerialization(ScriptTagBody input)
public void ShouldEqualAfterBinarySerialization(int index, ScriptTagBody input)
{
var bytes = input.ToBytes();
var body2 = ScriptTagBody.Parse(bytes);
@ -28,10 +34,12 @@ namespace BililiveRecorder.Flv.UnitTests.Amf
body2.Should().BeEquivalentTo(input, options => options.RespectingRuntimeTypes());
bytes2.Should().BeEquivalentTo(bytes2, options => options.RespectingRuntimeTypes());
Assert.Equal(index, index); // Suppress warnings
}
[Theory, MemberData(nameof(GetTestData))]
public void EqualAfterMixedSerialization(ScriptTagBody input)
public void ShouldEqualAfterMixedSerialization(int index, ScriptTagBody input)
{
var a_json = input.ToJson();
var a_body = ScriptTagBody.Parse(a_json);
@ -47,12 +55,32 @@ namespace BililiveRecorder.Flv.UnitTests.Amf
a_body.Should().BeEquivalentTo(input, options => options.RespectingRuntimeTypes());
b_body.Should().BeEquivalentTo(input, options => options.RespectingRuntimeTypes());
a_body.Should().BeEquivalentTo(b_body, options => options.RespectingRuntimeTypes());
Assert.Equal(index, index); // Suppress warnings
}
[Expectation("Json")]
[Theory, MemberData(nameof(GetTestData))]
public async void JsonSerializationShouldMatchExpectation(int index, ScriptTagBody input)
{
var json = input.ToJson();
await Verifier.Verify(json).UseTextForParameters("i" + index);
}
[Expectation("Binary")]
[Theory, MemberData(nameof(GetTestData))]
public async void BinarySerializationShouldMatchExpectation(int index, ScriptTagBody input)
{
var binary = input.ToBytes();
await Verifier.Verify(binary).UseTextForParameters("i" + index);
}
public static IEnumerable<object[]> GetTestData()
{
yield return new object[] { CreateTestObject1() };
yield return new object[] { CreateTestObject2() };
yield return new object[] { 1, CreateTestObject1() };
yield return new object[] { 2, CreateTestObject2() };
}
public static ScriptTagBody CreateTestObject1() => new ScriptTagBody(new List<IScriptDataValue> {
@ -61,7 +89,7 @@ namespace BililiveRecorder.Flv.UnitTests.Amf
{
["bool_true"] = (ScriptDataBoolean)true,
["bool_false"] = (ScriptDataBoolean)false,
["date1"] = (ScriptDataDate)DateTimeOffset.FromUnixTimeMilliseconds(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()), // remove extra precision
["date1"] = (ScriptDataDate)DateTimeOffset.FromUnixTimeMilliseconds(1636715491972),
["date2"] = (ScriptDataDate)new DateTimeOffset(2345, 3, 14, 7, 8, 9, 12, TimeSpan.FromHours(4)),
["ecmaarray"] = new ScriptDataEcmaArray
{

View File

@ -2,7 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace BililiveRecorder.Flv.RuleTests
namespace BililiveRecorder.Flv.Tests
{
public static class AssertTags
{

View File

@ -8,18 +8,19 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.1.20200127.214830" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.2" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Spectre.Verify.Extensions" Version="0.5.0" />
<PackageReference Include="Verify.Xunit" Version="13.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

View File

@ -0,0 +1 @@
[{"Type":"String","Value":"test"},{"Type":"Object","Value":{"bool_true":{"Type":"Boolean","Value":true},"bool_false":{"Type":"Boolean","Value":false},"date1":{"Type":"Date","Value":"2021-11-12T11:11:31.972+00:00"},"date2":{"Type":"Date","Value":"2345-03-14T07:08:09.012+04:00"},"ecmaarray":{"Type":"EcmaArray","Value":{"element1":{"Type":"String","Value":"element1"},"element2":{"Type":"String","Value":"element2"},"element3":{"Type":"String","Value":"element3"}}},"longstring1":{"Type":"LongString","Value":"longstring1"},"longstring2":{"Type":"LongString","Value":"longstring2"},"null":{"Type":"Null"},"number1":{"Type":"Number","Value":0.0},"number2":{"Type":"Number","Value":197653.845},"number3":{"Type":"Number","Value":-95.7},"number4":{"Type":"Number","Value":5E-324},"strictarray":{"Type":"StrictArray","Value":[{"Type":"String","Value":"element1"},{"Type":"String","Value":"element2"},{"Type":"String","Value":"element3"}]},"string1":{"Type":"String","Value":"string1"},"string2":{"Type":"String","Value":"string2"},"undefined":{"Type":"Undefined"}}}]

View File

@ -0,0 +1 @@
[{"Type":"String","Value":"test"},{"Type":"Boolean","Value":true},{"Type":"Boolean","Value":false},{"Type":"Number","Value":0.0},{"Type":"Number","Value":-95.7}]

View File

@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using BililiveRecorder.Flv.Grouping;
using BililiveRecorder.Flv.Parser;
using BililiveRecorder.Flv.Pipeline.Actions;
using VerifyTests;
using VerifyXunit;
using Xunit;
namespace BililiveRecorder.Flv.Tests.FlvTests
{
[UsesVerify]
[ExpectationPath("FlvGrouping")]
public class GroupingTests
{
[Theory]
[Expectation("GroupingFromFlv")]
[SampleFileTestData("TestData/Flv", "*.flv")]
public async void GroupingShouldMatchExpection(string path)
{
var results = new List<PipelineAction>();
var grouping = new TagGroupReader(new FlvTagPipeReader(PipeReader.Create(File.OpenRead(SampleFileLoader.GetFullPath(path))), new TestRecyclableMemoryStreamProvider(), skipData: true, logger: null));
while (true)
{
var g = await grouping.ReadGroupAsync(default);
if (g is null) break;
results.Add(g);
}
await Verifier.Verify(results).UseParameters(path);
}
}
}

View File

@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Threading.Tasks;
using BililiveRecorder.Flv.Parser;
using VerifyTests;
using VerifyXunit;
using Xunit;
namespace BililiveRecorder.Flv.Tests.FlvTests
{
[UsesVerify]
[ExpectationPath("FlvParser")]
public class ParserTest
{
[Theory]
[Expectation("XmlOutput")]
[SampleFileTestData("TestData/Flv", "*.flv")]
public async Task ParserOutputIsCurrectAsync(string path)
{
var fullPath = SampleFileLoader.GetFullPath(path);
var tags = new List<Tag>();
var reader = new FlvTagPipeReader(PipeReader.Create(File.OpenRead(fullPath)), new TestRecyclableMemoryStreamProvider(), skipData: false, leaveOpen: false, logger: null);
while (true)
{
var tag = await reader.ReadTagAsync(default).ConfigureAwait(false);
if (tag is null) break;
tags.Add(tag);
}
await Verifier.Verify(tags.SerializeXml()).UseExtension("xml").UseParameters(path);
}
}
}

View File

@ -3,7 +3,7 @@ using System.IO;
using System.Text;
using Xunit;
namespace BililiveRecorder.Flv.UnitTests.Flv
namespace BililiveRecorder.Flv.Tests.FlvTests
{
public class TagTests
{

View File

@ -0,0 +1,60 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Threading.Tasks;
using BililiveRecorder.Flv.Parser;
using BililiveRecorder.Flv.Writer;
using VerifyTests;
using VerifyXunit;
using Xunit;
namespace BililiveRecorder.Flv.Tests.FlvTests
{
[UsesVerify]
[ExpectationPath("FlvWriter")]
public class WriterTests
{
[Theory]
[Expectation("Output")]
[SampleFileTestData("TestData/Flv", "*.flv")]
public async Task ParserOutputIsCurrectAsync(string path)
{
var fullPath = SampleFileLoader.GetFullPath(path);
var testRecyclableMemoryStreamProvider = new TestRecyclableMemoryStreamProvider();
var reader = new FlvTagPipeReader(PipeReader.Create(File.OpenRead(fullPath)), testRecyclableMemoryStreamProvider, skipData: false, leaveOpen: false, logger: null);
var msprovider = new MemoryStreamFlvTargetProvider();
var writer = new FlvTagFileWriter(msprovider, testRecyclableMemoryStreamProvider, null);
await writer.CreateNewFile();
while (true)
{
var tag = await reader.ReadTagAsync(default).ConfigureAwait(false);
if (tag is null) break;
await writer.WriteTag(tag);
}
await Verifier.Verify(msprovider.Stream).UseExtension("flv").UseParameters(path);
}
public class MemoryStreamFlvTargetProvider : IFlvWriterTargetProvider
{
public MemoryStream Stream { get; } = new MemoryStream();
private bool flag = false;
public Stream CreateAlternativeHeaderStream() => throw new System.NotImplementedException();
public (Stream stream, object? state) CreateOutputStream()
{
if (!this.flag)
this.flag = true;
else
throw new System.InvalidOperationException();
return (this.Stream, null);
}
}
}
}

View File

@ -13,9 +13,8 @@ using Newtonsoft.Json.Converters;
using VerifyTests;
using VerifyXunit;
using Xunit;
using Xunit.Abstractions;
namespace BililiveRecorder.Flv.RuleTests.Integrated
namespace BililiveRecorder.Flv.Tests.RuleTests
{
[UsesVerify]
[ExpectationPath("Bad")]
@ -23,11 +22,11 @@ namespace BililiveRecorder.Flv.RuleTests.Integrated
{
[Theory]
[Expectation("TestBadSamples")]
[SampleFileTestData("TestData/Bad")]
[SampleFileTestData("TestData/Bad", "*.xml")]
public async Task TestBadSamples(string path)
{
var originalTags = SampleFileLoader.Load(path).Tags;
var originalTags = SampleFileLoader.LoadXmlFlv(path).Tags;
var reader = new TagGroupReader(new FlvTagListReader(originalTags));
var flvTagListWriter = new FlvTagListWriter();
var comments = new List<ProcessingComment>();
@ -55,7 +54,7 @@ namespace BililiveRecorder.Flv.RuleTests.Integrated
AssertTags.ShouldHaveLinearTimestamps(outputTags);
await AssertTagsByRerunPipeline(outputTags).ConfigureAwait(false);
var xmlStr = SerializeTags(outputTags);
var xmlStr = outputTags.SerializeXml();
sw.WriteLine(xmlStr);
}

View File

@ -8,7 +8,7 @@ using VerifyTests;
using VerifyXunit;
using Xunit;
namespace BililiveRecorder.Flv.RuleTests.Integrated
namespace BililiveRecorder.Flv.Tests.RuleTests
{
[UsesVerify]
[ExpectationPath("Good")]
@ -16,12 +16,12 @@ namespace BililiveRecorder.Flv.RuleTests.Integrated
{
[Theory]
[Expectation("StandardTest")]
[SampleFileTestData("TestData/Good")]
[SampleFileTestData("TestData/Good", "*.xml")]
public async Task StrictTestsAsync(string path)
{
// Arrange
var originalTags = SampleFileLoader.Load(path).Tags;
var reader = new TagGroupReader(new FlvTagListReader(SampleFileLoader.Load(path).Tags));
var originalTags = SampleFileLoader.LoadXmlFlv(path).Tags;
var reader = new TagGroupReader(new FlvTagListReader(SampleFileLoader.LoadXmlFlv(path).Tags));
var flvTagListWriter = new FlvTagListWriter();
var comments = new List<ProcessingComment>();
@ -45,24 +45,24 @@ namespace BililiveRecorder.Flv.RuleTests.Integrated
await AssertTagsByRerunPipeline(outputTags).ConfigureAwait(false);
var xmlStr = SerializeTags(outputTags);
var xmlStr = outputTags.SerializeXml();
await Verifier.Verify(xmlStr).UseExtension("xml").UseParameters(path);
}
[Theory]
[Expectation("WithOffsetTest")]
[SampleFileTestData("TestData/Good")]
[SampleFileTestData("TestData/Good", "*.xml")]
public async Task StrictWithArtificalOffsetTestsAsync(string path)
{
// Arrange
var originalTags = SampleFileLoader.Load(path).Tags;
var originalTags = SampleFileLoader.LoadXmlFlv(path).Tags;
var random = new System.Random();
var offset = random.Next(51, 9999);
if (random.Next(2) == 1)
offset = -offset;
var inputTagsWithOffset = SampleFileLoader.Load(path).Tags;
var inputTagsWithOffset = SampleFileLoader.LoadXmlFlv(path).Tags;
foreach (var tag in inputTagsWithOffset)
tag.Timestamp += offset;
var reader = new TagGroupReader(new FlvTagListReader(inputTagsWithOffset));
@ -89,7 +89,7 @@ namespace BililiveRecorder.Flv.RuleTests.Integrated
await AssertTagsByRerunPipeline(outputTags).ConfigureAwait(false);
var xmlStr = SerializeTags(outputTags);
var xmlStr = outputTags.SerializeXml();
await Verifier.Verify(xmlStr).UseExtension("xml").UseParameters(path);
}
}

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BililiveRecorder.Flv.Grouping;
using BililiveRecorder.Flv.Pipeline;
@ -12,16 +9,11 @@ using BililiveRecorder.Flv.Xml;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace BililiveRecorder.Flv.RuleTests.Integrated
namespace BililiveRecorder.Flv.Tests.RuleTests
{
public abstract class IntegratedTestBase
{
protected static string SerializeTags(List<Tag> tags)
{
using var sw = new StringWriter();
XmlFlvFile.Serializer.Serialize(sw, new XmlFlvFile { Tags = tags });
return sw.ToString();
}
protected static async Task RunPipeline(ITagGroupReader reader, IFlvTagWriter output, List<ProcessingComment> comments)
{

View File

@ -4,19 +4,23 @@ using System.Linq;
using System.Reflection;
using BililiveRecorder.Flv.Xml;
namespace BililiveRecorder.Flv.RuleTests
namespace BililiveRecorder.Flv.Tests
{
public static class SampleFileLoader
{
public static XmlFlvFile Load(string fileName)
public static string GetFullPath(string fileName)
{
var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
var attr = frames.Select(x => x!.GetMethod()!.GetCustomAttribute<SampleFileTestDataAttribute>()).First(x => x is not null);
var fullPath = Path.Combine(attr!.FullPath, fileName);
return fullPath;
}
public static XmlFlvFile LoadXmlFlv(string fileName)
{
var fullPath = GetFullPath(fileName);
using var s = File.Open(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
return (XmlFlvFile)XmlFlvFile.Serializer.Deserialize(s)!;
}
}

View File

@ -6,13 +6,14 @@ using System.Reflection;
using VerifyTests;
using Xunit.Sdk;
namespace BililiveRecorder.Flv.RuleTests
namespace BililiveRecorder.Flv.Tests
{
public class SampleFileTestDataAttribute : DataAttribute
{
public SampleFileTestDataAttribute(string basePath)
public SampleFileTestDataAttribute(string basePath, params string[] patterns)
{
this.BasePath = basePath;
this.Patterns = patterns;
this.FullPath = Path.GetFullPath(Path.Combine(AttributeReader.GetProjectDirectory(), basePath));
}
@ -20,12 +21,14 @@ namespace BililiveRecorder.Flv.RuleTests
public string FullPath { get; }
public string[] Patterns { get; }
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
if (!Directory.Exists(this.FullPath))
throw new ArgumentException($"Could not find directory at path: {this.FullPath}");
return new[] { "*.xml" }.SelectMany(x => Directory.GetFiles(this.FullPath, x)).Select(x => new object[] { Path.GetFileName(x) });
return Patterns.SelectMany(x => Directory.GetFiles(this.FullPath, x)).Select(x => (new object[] { Path.GetFileName(x) }));
}
}
}

View File

@ -1,8 +1,7 @@
using System.Diagnostics;
using System.IO;
using Microsoft.IO;
namespace BililiveRecorder.Flv.UnitTests
namespace BililiveRecorder.Flv.Tests
{
public class TestRecyclableMemoryStreamProvider : IMemoryStreamProvider
{
@ -13,18 +12,6 @@ namespace BililiveRecorder.Flv.UnitTests
MaximumFreeLargePoolBytes = 64 * 1024 * 32,
};
static TestRecyclableMemoryStreamProvider()
{
//manager.StreamFinalized += (sender, e) =>
//{
// Debug.WriteLine("TestRecyclableMemoryStreamProvider: Stream Finalized");
//};
//manager.StreamDisposed += (sender, e) =>
//{
// // Debug.WriteLine("TestRecyclableMemoryStreamProvider: Stream Disposed");
//};
}
public Stream CreateMemoryStream(string tag) => manager.GetStream(tag);
}
}

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.IO;
using BililiveRecorder.Flv.Xml;
namespace BililiveRecorder.Flv.Tests
{
internal static class TestTagsExtensions
{
public static string SerializeXml(this List<Tag> tags)
{
using var sw = new StringWriter();
XmlFlvFile.Serializer.Serialize(sw, new XmlFlvFile { Tags = tags });
return sw.ToString();
}
}
}

View File

@ -1,8 +1,9 @@
using System.IO;
using System.Runtime.CompilerServices;
using DiffEngine;
using VerifyTests;
namespace BililiveRecorder.Flv.RuleTests
namespace BililiveRecorder.Flv.Tests
{
public static class VerifyConfig
{
@ -10,7 +11,7 @@ namespace BililiveRecorder.Flv.RuleTests
public static void Init()
{
VerifierSettings.DerivePathInfo(Expectations.Initialize);
VerifierSettings.UseStrictJson();
VerifierSettings.ModifySerialization(_ => _.IgnoreMembersWithType<Stream>());
DiffRunner.Disabled = true;
}
}

View File

@ -1,48 +0,0 @@
using System.Collections.Generic;
using BililiveRecorder.Flv.Amf;
using FluentAssertions;
using Xunit;
namespace BililiveRecorder.Flv.UnitTests.Amf
{
public class ParserTests
{
[Theory, MemberData(nameof(JsonData))]
public void ParseJson(ScriptTagBody expectation, string input)
{
var result = ScriptTagBody.Parse(input);
result.Should().BeEquivalentTo(expectation: expectation);
}
[Theory, MemberData(nameof(BinaryData))]
public void ParseBinary(ScriptTagBody expectation, byte[] input)
{
var result = ScriptTagBody.Parse(input);
result.Should().BeEquivalentTo(expectation: expectation);
}
public static IEnumerable<object[]> JsonData()
{
yield return new object[] {
SerializationTests.CreateTestObject1(),
"[{\"Type\":\"String\",\"Value\":\"test\"},{\"Type\":\"Object\",\"Value\":{\"bool_true\":{\"Type\":\"Boolean\",\"Value\":true},\"bool_false\":{\"Type\":\"Boolean\",\"Value\":false},\"date1\":{\"Type\":\"Date\",\"Value\":\"2021-02-08T14:43:58.257+00:00\"},\"date2\":{\"Type\":\"Date\",\"Value\":\"2345-03-14T07:08:09.012+04:00\"},\"ecmaarray\":{\"Type\":\"EcmaArray\",\"Value\":{\"element1\":{\"Type\":\"String\",\"Value\":\"element1\"},\"element2\":{\"Type\":\"String\",\"Value\":\"element2\"},\"element3\":{\"Type\":\"String\",\"Value\":\"element3\"}}},\"longstring1\":{\"Type\":\"LongString\",\"Value\":\"longstring1\"},\"longstring2\":{\"Type\":\"LongString\",\"Value\":\"longstring2\"},\"null\":{\"Type\":\"Null\"},\"number1\":{\"Type\":\"Number\",\"Value\":0.0},\"number2\":{\"Type\":\"Number\",\"Value\":197653.845},\"number3\":{\"Type\":\"Number\",\"Value\":-95.7},\"number4\":{\"Type\":\"Number\",\"Value\":5E-324},\"strictarray\":{\"Type\":\"StrictArray\",\"Value\":[{\"Type\":\"String\",\"Value\":\"element1\"},{\"Type\":\"String\",\"Value\":\"element2\"},{\"Type\":\"String\",\"Value\":\"element3\"}]},\"string1\":{\"Type\":\"String\",\"Value\":\"string1\"},\"string2\":{\"Type\":\"String\",\"Value\":\"string2\"},\"undefined\":{\"Type\":\"Undefined\"}}}]",
};
yield return new object[] {
SerializationTests.CreateTestObject2(),
"[{\"Type\":\"String\",\"Value\":\"test\"},{\"Type\":\"Boolean\",\"Value\":true},{\"Type\":\"Boolean\",\"Value\":false},{\"Type\":\"Number\",\"Value\":0.0},{\"Type\":\"Number\",\"Value\":-95.7}]",
};
}
public static IEnumerable<object[]> BinaryData()
{
yield return new object[] {
SerializationTests.CreateTestObject1(),
new byte[]{2,0,4,116,101,115,116,3,0,9,98,111,111,108,95,116,114,117,101,1,1,0,10,98,111,111,108,95,102,97,108,115,101,1,0,0,5,100,97,116,101,49,11,66,119,120,33,150,75,16,0,0,0,0,5,100,97,116,101,50,11,66,165,137,121,64,147,104,0,0,240,0,9,101,99,109,97,97,114,114,97,121,8,0,0,0,3,0,8,101,108,101,109,101,110,116,49,2,0,8,101,108,101,109,101,110,116,49,0,8,101,108,101,109,101,110,116,50,2,0,8,101,108,101,109,101,110,116,50,0,8,101,108,101,109,101,110,116,51,2,0,8,101,108,101,109,101,110,116,51,0,0,9,0,11,108,111,110,103,115,116,114,105,110,103,49,12,0,0,0,11,108,111,110,103,115,116,114,105,110,103,49,0,11,108,111,110,103,115,116,114,105,110,103,50,12,0,0,0,11,108,111,110,103,115,116,114,105,110,103,50,0,4,110,117,108,108,5,0,7,110,117,109,98,101,114,49,0,0,0,0,0,0,0,0,0,0,7,110,117,109,98,101,114,50,0,65,8,32,174,194,143,92,41,0,7,110,117,109,98,101,114,51,0,192,87,236,204,204,204,204,205,0,7,110,117,109,98,101,114,52,0,0,0,0,0,0,0,0,1,0,11,115,116,114,105,99,116,97,114,114,97,121,10,0,0,0,3,2,0,8,101,108,101,109,101,110,116,49,2,0,8,101,108,101,109,101,110,116,50,2,0,8,101,108,101,109,101,110,116,51,0,7,115,116,114,105,110,103,49,2,0,7,115,116,114,105,110,103,49,0,7,115,116,114,105,110,103,50,2,0,7,115,116,114,105,110,103,50,0,9,117,110,100,101,102,105,110,101,100,6,0,0,9},
};
yield return new object[] {
SerializationTests.CreateTestObject2(),
new byte[]{ 2, 0, 4, 116, 101, 115, 116, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 87, 236, 204, 204, 204, 204, 205 },
};
}
}
}

View File

@ -1,57 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Threading.Tasks;
using BililiveRecorder.Flv.Parser;
using BililiveRecorder.Flv.Xml;
using JetBrains.dotMemoryUnit;
using Xunit;
using Xunit.Abstractions;
namespace BililiveRecorder.Flv.UnitTests.Flv
{
public class ParsingTest
{
private readonly ITestOutputHelper _output;
public ParsingTest(ITestOutputHelper output)
{
this._output = output;
DotMemoryUnitTestOutput.SetOutputMethod(this._output.WriteLine);
}
// [AssertTraffic(AllocatedSizeInBytes = 1000)]
[Fact(Skip = "Not ready")]
public async Task Run()
{
var path = @"";
var tags = new List<Tag>();
var reader = new FlvTagPipeReader(PipeReader.Create(File.OpenRead(path)), new TestRecyclableMemoryStreamProvider(), skipData: true, logger: null);
while (true)
{
var tag = await reader.ReadTagAsync(default).ConfigureAwait(false);
if (tag is null)
break;
tags.Add(tag);
}
var xmlObj = new XmlFlvFile
{
Tags = tags
};
var writer = new StringWriter();
XmlFlvFile.Serializer.Serialize(writer, xmlObj);
var xmlStr = writer.ToString();
//var peakWorkingSet = Process.GetCurrentProcess().PeakWorkingSet64;
//throw new System.Exception("PeakWorkingSet64: " + peakWorkingSet);
}
}
}

View File

@ -1,115 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Linq;
using System.Threading.Tasks;
using BililiveRecorder.Flv.Grouping;
using BililiveRecorder.Flv.Parser;
using BililiveRecorder.Flv.Pipeline;
using BililiveRecorder.Flv.Pipeline.Actions;
using BililiveRecorder.Flv.Writer;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace BililiveRecorder.Flv.UnitTests.Grouping
{
public class GroupingTest
{
private const string TEST_OUTPUT_PATH = @"";
public class TestOutputProvider : IFlvWriterTargetProvider
{
public Stream CreateAlternativeHeaderStream() => throw new NotImplementedException();
public (Stream, object?) CreateOutputStream() => (File.Open(Path.Combine(TEST_OUTPUT_PATH, DateTimeOffset.Now.ToString("s").Replace(':', '-') + ".flv"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None), null);
}
[Fact(Skip = "Not ready")]
public async Task Test1Async()
{
var path = @"";
var results = new List<PipelineAction>();
var grouping = new TagGroupReader(new FlvTagPipeReader(PipeReader.Create(File.OpenRead(path)), new TestRecyclableMemoryStreamProvider(), skipData: true, logger: null));
var context = new FlvProcessingContext();
var session = new Dictionary<object, object?>();
var sp = new ServiceCollection().BuildServiceProvider();
var pipeline = new ProcessingPipelineBuilder(sp).AddDefault().AddRemoveFillerData().Build();
while (true)
{
var g = await grouping.ReadGroupAsync(default).ConfigureAwait(false);
if (g is null)
break;
context.Reset(g, session);
pipeline(context);
foreach (var item in context.Actions)
{
results.Add(item);
}
}
var sizes = results.Select(a => a switch
{
PipelineDataAction x => x.Tags.Sum(b => b.Size),
PipelineHeaderAction x => x.AllTags.Sum(b => b.Size),
PipelineScriptAction x => x.Tag.Size,
_ => 0,
}
).ToArray();
}
[Fact(Skip = "Not ready")]
public async Task Test2Async()
{
const string PATH = @"";
using var grouping = new TagGroupReader(new FlvTagPipeReader(PipeReader.Create(File.OpenRead(PATH)), new TestRecyclableMemoryStreamProvider(), skipData: false, logger: null));
var comments = new List<string>();
var context = new FlvProcessingContext();
var session = new Dictionary<object, object?>();
var sp = new ServiceCollection().BuildServiceProvider();
var pipeline = new ProcessingPipelineBuilder(sp).AddDefault().AddRemoveFillerData().Build();
using var writer = new FlvProcessingContextWriter(tagWriter: new FlvTagFileWriter(new TestOutputProvider(), new TestRecyclableMemoryStreamProvider(), null), allowMissingHeader: false, disableKeyframes: true);
while (true)
{
var g = await grouping.ReadGroupAsync(default).ConfigureAwait(false);
if (g is null)
break;
context.Reset(g, session);
pipeline(context);
comments.AddRange(context.Comments.Select(x => x.C));
await writer.WriteAsync(context).ConfigureAwait(false);
foreach (var action in context.Actions)
{
// TODO action.Dispose();
if (action is PipelineDataAction dataAction)
{
foreach (var tag in dataAction.Tags)
{
tag.BinaryData?.Dispose();
}
}
}
}
}
}
}

View File

@ -1,125 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Threading.Tasks;
using System.Xml.Serialization;
using BililiveRecorder.Flv.Amf;
using BililiveRecorder.Flv.Parser;
using BililiveRecorder.Flv.Xml;
using Xunit;
namespace BililiveRecorder.Flv.UnitTests.Xml
{
public class XmlTests
{
[Fact]
public void Test1()
{
// TODO cleanup
var source = new XmlFlvFile
{
Tags = new List<Tag>
{
new Tag
{
Type = TagType.Script,
Size=4321,
ScriptData = new ScriptTagBody(new List<IScriptDataValue>
{
(ScriptDataString)"test1",
new ScriptDataObject
{
["key1"] = (ScriptDataNumber)5,
["key2"] = (ScriptDataString)"testTest"
}
})
},
new Tag
{
Type = TagType.Audio,
ScriptData = new ScriptTagBody(new List<IScriptDataValue>
{
(ScriptDataString)"test2",
new ScriptDataObject
{
["key1"] = (ScriptDataNumber)5,
["key2"] = (ScriptDataString)"testTest"
}
})
},
new Tag
{
Type = TagType.Audio,
Flag = TagFlag.Header,
BinaryData = new MemoryStream(new byte[]{0,1,2,3,4,5,6,7})
},
new Tag
{
Type = TagType.Video,
Flag = TagFlag.Header | TagFlag.Keyframe
},
new Tag
{
Type = TagType.Video,
Nalus = new List<H264Nalu>
{
new H264Nalu(0,156, H264NaluType.CodedSliceDataPartitionB),
new H264Nalu(198,13216, H264NaluType.Pps),
new H264Nalu(432154,432156, H264NaluType.FillerData),
}
}
}
};
var serializer = new XmlSerializer(typeof(XmlFlvFile));
var writer1 = new StringWriter();
serializer.Serialize(writer1, source);
var str1 = writer1.ToString();
var obj1 = serializer.Deserialize(new StringReader(str1));
var writer2 = new StringWriter();
serializer.Serialize(writer2, obj1);
var str2 = writer2.ToString();
var obj2 = serializer.Deserialize(new StringReader(str1));
var writer3 = new StringWriter();
serializer.Serialize(writer3, obj2);
var str3 = writer3.ToString();
Assert.Equal(str1, str2);
Assert.Equal(str2, str3);
}
[Fact(Skip = "Not ready")]
public async Task Test2Async()
{
var PATH = @"";
var reader = new FlvTagPipeReader(PipeReader.Create(File.OpenRead(PATH)), new TestRecyclableMemoryStreamProvider(), skipData: true, logger: null);
var source = new XmlFlvFile
{
Tags = new List<Tag>()
};
while (true)
{
var tag = await reader.ReadTagAsync(default).ConfigureAwait(false);
if (tag is null)
break;
source.Tags.Add(tag);
}
var writer1 = new StringWriter();
XmlFlvFile.Serializer.Serialize(writer1, source);
var str1 = writer1.ToString();
}
}
}