Files
jellyfin-plugin-enigma2/Tests/BroadcastTrackTests.cs
T

39 lines
4.4 KiB
C#

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.Enigma2;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Entities;
public static class BroadcastTrackTests
{
public static async Task Run(Action<bool,string> check)
{
const string json="""{"streams":[{"index":0,"id":"0x100","codec_type":"video","codec_name":"h264","width":1920,"height":1080},{"index":2,"id":"0x102","codec_type":"audio","codec_name":"ac3","channels":6,"tags":{"language":"pol","title":"Polski"},"disposition":{"default":1}},{"index":3,"id":"0x103","codec_type":"audio","codec_name":"aac","channels":2,"tags":{"language":"eng","title":"English"}},{"index":5,"id":"0x105","codec_type":"subtitle","codec_name":"dvb_subtitle","tags":{"language":"pol","title":"Napisy"},"disposition":{"forced":1,"hearing_impaired":1},"extradata":"\n00000000: 0001 0001 ....\n"},{"index":6,"id":"0x106","codec_type":"subtitle","codec_name":"dvb_teletext","tags":{"language":"eng"}},{"index":1,"codec_type":"data","codec_name":"bin_data"}]}""";
var parsed=LiveStreamProbe.Parse(json);
check(parsed.Count==5&&parsed.Count(s=>s.Type==MediaStreamType.Subtitle)==2,"probe retains both audio languages and broadcast subtitles while excluding data PIDs");
check(parsed[3].Codec=="DVBSUB"&&!parsed[3].IsTextSubtitleStream&&parsed[4].Codec=="DVBTXT","native Jellyfin codec names distinguish DVB bitmap and teletext subtitles");
check(parsed[3].IsForced&&parsed[3].IsHearingImpaired&&parsed[1].IsDefault&&parsed[1].Title=="Polski","language labels and default/forced/hearing-impaired dispositions survive probing");
check(parsed[3] is BroadcastMediaStream {TransportId:261,SubtitleExtraData:var extra}&&extra.SequenceEqual(new byte[]{0,1,0,1}),"probe preserves transport PIDs and DVB page IDs");
var layout=new BroadcastTracks(parsed);
check(layout.Output[0].Width==1920&&layout.Output[0].Height==1080&&BroadcastTracks.Fallback().Output[0].Width==null,"native negotiation uses probed channel dimensions, never the status picture dimensions");
check(layout.Output.Select(s=>s.Index).SequenceEqual(Enumerable.Range(0,5))&&layout.Output[2].Language=="eng","explicitly ordered program exposes distinct stable selectable indices");
check(layout.Output.Where(s=>s.Type==MediaStreamType.Audio).All(s=>s.Codec=="aac"&&s.Channels==2),"each normalized audio language has its own AAC track");
check(EncodingHelper.FindIndex(layout.Output,layout.Output[2])==2&&EncodingHelper.GetSubtitleStreamIndexForFfmpeg(new(){MediaStreams=layout.Output},layout.Output[3])==3,"installed Jellyfin resolves alternate audio and subtitle maps without unknown-index auto-selection");
check(layout.MapArguments().Contains("0:i:261")&&!layout.MapArguments().Contains("-sn"),"producer maps broadcast PIDs instead of unstable probe positions and retains subtitles");
var untouched=new BroadcastTracks(parsed,false);
check(untouched.Output[1].Codec=="ac3"&&untouched.Output[1].Channels==6,"disabled slates preserve original audio codec and surround channels through remux");
var section=BroadcastSlateProgram.Section(layout);uint crc=0xffffffff;
foreach(var value in section){crc^=(uint)value<<24;for(var bit=0;bit<8;bit++)crc=(crc&0x80000000)!=0?(crc<<1)^0x04c11db7:crc<<1;}
check(crc==0&&section.Contains((byte)89)&&section.Contains((byte)86),"status program map has valid MPEG-TS CRC and DVB/teletext descriptors");
var subtitleClock=new DvbSubtitleVersions(SyntheticBroadcastFixture.Tracks());var cc=0;
var wire=SyntheticBroadcastFixture.Packets(SyntheticBroadcastFixture.Bitmap(0),126000,259,ref cc).SelectMany(b=>b).ToArray();
var first=wire.ToArray();subtitleClock.Apply(first,0);var next=wire.ToArray();subtitleClock.Apply(next,1);
check(!first.SequenceEqual(next),"DVB pages, objects and display definitions get fresh versions across status/live boundaries");
var retry=wire.ToArray();subtitleClock.Apply(retry,1);check(retry.SequenceEqual(next),"repeated HLS segment requests reuse the same DVB version plan");
var probe=new LiveStreamProbe((_,_)=>Task.FromResult(json));await probe.Get("channel",CancellationToken.None);
check(probe.LastKnown("channel")?.Count==5&&probe.LastKnown("other",1)==null&&probe.LastKnown("channel",2)==null,"last-known track catalogue is isolated by source and programme");
}
}