diff --git a/ProxyFormUnit.fmx b/ProxyFormUnit.fmx index 7feff27..ca61c4d 100644 --- a/ProxyFormUnit.fmx +++ b/ProxyFormUnit.fmx @@ -2,7 +2,7 @@ object MainForm: TMainForm Left = 0 Top = 0 Caption = 'Ceton HDHomeRun Proxy' - ClientHeight = 782 + ClientHeight = 762 ClientWidth = 466 Fill.Kind = Solid Position = ScreenCenter @@ -17,18 +17,18 @@ object MainForm: TMainForm object VertScrollBox1: TVertScrollBox Align = Contents Size.Width = 466.000000000000000000 - Size.Height = 782.000000000000000000 + Size.Height = 762.000000000000000000 Size.PlatformDefault = False TabOrder = 3 - Viewport.Width = 466.000000000000000000 - Viewport.Height = 782.000000000000000000 + Viewport.Width = 450.000000000000000000 + Viewport.Height = 762.000000000000000000 object gbGroup: TGroupBox Align = Top Padding.Left = 15.000000000000000000 Padding.Top = 20.000000000000000000 Padding.Right = 10.000000000000000000 Position.Y = 141.000000000000000000 - Size.Width = 466.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 280.000000000000000000 Size.PlatformDefault = False StyleLookup = 'gbGroupStyle1' @@ -49,7 +49,7 @@ object MainForm: TMainForm Align = Client Enabled = False Margins.Bottom = 35.000000000000000000 - Size.Width = 441.000000000000000000 + Size.Width = 425.000000000000000000 Size.Height = 225.000000000000000000 Size.PlatformDefault = False TabOrder = 2 @@ -59,12 +59,12 @@ object MainForm: TMainForm DefaultItemStyles.GroupFooterStyle = '' ShowCheckboxes = True OnChangeCheck = lbChannelsChangeCheck - Viewport.Width = 437.000000000000000000 + Viewport.Width = 421.000000000000000000 Viewport.Height = 221.000000000000000000 end object btnRefreshChannels: TButton Anchors = [akRight, akBottom] - Position.X = 351.000000000000000000 + Position.X = 335.000000000000000000 Position.Y = 250.000000000000000000 Size.Width = 106.000000000000000000 Size.Height = 22.000000000000000000 @@ -85,7 +85,7 @@ object MainForm: TMainForm end object gbSettings: TGroupBox Align = Top - Size.Width = 466.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 141.000000000000000000 Size.PlatformDefault = False StyleLookup = 'gbGroupStyle1' @@ -145,7 +145,7 @@ object MainForm: TMainForm Touch.InteractiveGestures = [LongTap, DoubleTap] TabOrder = 7 ItemHeight = 19.000000000000000000 - ItemIndex = 0 + ItemIndex = -1 Position.X = 210.000000000000000000 Position.Y = 49.000000000000000000 Size.Width = 231.000000000000000000 @@ -172,8 +172,9 @@ object MainForm: TMainForm Padding.Top = 20.000000000000000000 Padding.Right = 10.000000000000000000 Padding.Bottom = 10.000000000000000000 + PopupMenu = DebugMenu Position.Y = 429.000000000000000000 - Size.Width = 466.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 311.000000000000000000 Size.PlatformDefault = False StyleLookup = 'gbGroupStyle1' @@ -186,7 +187,7 @@ object MainForm: TMainForm FooterAppearanceClassName = 'TListHeaderObjects' EditMode = True Align = Client - Size.Width = 441.000000000000000000 + Size.Width = 425.000000000000000000 Size.Height = 281.000000000000000000 Size.PlatformDefault = False TabOrder = 1 @@ -197,7 +198,7 @@ object MainForm: TMainForm Cursor = crVSplit MinSize = 20.000000000000000000 Position.Y = 421.000000000000000000 - Size.Width = 466.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 8.000000000000000000 Size.PlatformDefault = False end @@ -206,58 +207,59 @@ object MainForm: TMainForm Cursor = crVSplit MinSize = 20.000000000000000000 Position.Y = 740.000000000000000000 - Size.Width = 466.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 8.000000000000000000 Size.PlatformDefault = False end - object GroupBox1: TGroupBox + object gbDebug: TGroupBox Align = Top Position.Y = 748.000000000000000000 - Size.Width = 435.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 141.000000000000000000 Size.PlatformDefault = False StyleLookup = 'gbGroupStyle1' Text = 'Debug' - Visible = False TabOrder = 1 - object eDebugIP: TEdit - Touch.InteractiveGestures = [LongTap, DoubleTap] - TabOrder = 0 - Position.X = 37.000000000000000000 - Position.Y = 24.000000000000000000 - Size.Width = 129.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - end object Label5: TLabel Position.X = 16.000000000000000000 Position.Y = 27.000000000000000000 - Size.Width = 17.000000000000000000 + Size.Width = 89.000000000000000000 Size.Height = 17.000000000000000000 Size.PlatformDefault = False - Text = 'IP:' - TabOrder = 1 + Text = 'Channel:' + TabOrder = 0 end - object btnDebugDiscoveryRequest: TButton - Position.X = 16.000000000000000000 - Position.Y = 56.000000000000000000 + object btnGetVideoSample: TButton + Position.X = 168.000000000000000000 + Position.Y = 24.000000000000000000 Size.Width = 121.000000000000000000 Size.Height = 22.000000000000000000 Size.PlatformDefault = False + TabOrder = 1 + Text = 'Get Video Sample' + OnClick = btnGetVideoSampleClick + end + object seChannel: TSpinBox + Touch.InteractiveGestures = [LongTap, DoubleTap] TabOrder = 2 - Text = 'Discovery Request' - OnClick = btnDebugDiscoveryRequestClick + Cursor = crIBeam + Max = 10000.000000000000000000 + RepeatClick = True + Position.X = 69.000000000000000000 + Position.Y = 24.000000000000000000 + Size.Width = 89.000000000000000000 + Size.Height = 22.000000000000000000 + Size.PlatformDefault = False end end - object Splitter3: TSplitter + object DebugSplitter: TSplitter Align = Top Cursor = crVSplit MinSize = 20.000000000000000000 - Position.Y = 748.000000000000000000 - Size.Width = 435.000000000000000000 + Position.Y = 889.000000000000000000 + Size.Width = 450.000000000000000000 Size.Height = 8.000000000000000000 Size.PlatformDefault = False - Visible = False end end object StyleBook1: TStyleBook @@ -311,4 +313,12 @@ object MainForm: TMainForm Left = 104 Top = 432 end + object DebugMenu: TPopupMenu + Left = 216 + Top = 368 + object MenuItem1: TMenuItem + Text = 'Enable Debug' + OnClick = MenuItem1Click + end + end end diff --git a/ProxyFormUnit.pas b/ProxyFormUnit.pas index d2ce7b2..95f1586 100644 --- a/ProxyFormUnit.pas +++ b/ProxyFormUnit.pas @@ -38,6 +38,8 @@ interface FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.ListView, + FMX.SpinBox, + FMX.Menus, REST.json, REST.Client, @@ -82,14 +84,16 @@ TMainForm = class(TForm, IServiceConfigEvents) Label3: TLabel; eHDHRListenHTTPPort: TEdit; Label4: TLabel; - GroupBox1: TGroupBox; - Splitter3: TSplitter; - eDebugIP: TEdit; + gbDebug: TGroupBox; + DebugSplitter: TSplitter; Label5: TLabel; - btnDebugDiscoveryRequest: TButton; + btnGetVideoSample: TButton; lblSelectedChannels: TLabel; ceCetonListenIP: TComboEdit; ceHDHRListenIP: TComboEdit; + seChannel: TSpinBox; + DebugMenu: TPopupMenu; + MenuItem1: TMenuItem; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure lbChannelsChangeCheck(Sender: TObject); @@ -101,7 +105,8 @@ TMainForm = class(TForm, IServiceConfigEvents) procedure btnRefreshChannelsClick(Sender: TObject); procedure eHDHRListenHTTPPortChangeTracking(Sender: TObject); procedure ceHDHRListenIPChangeTracking(Sender: TObject); - procedure btnDebugDiscoveryRequestClick(Sender: TObject); + procedure btnGetVideoSampleClick(Sender: TObject); + procedure MenuItem1Click(Sender: TObject); private { Private declarations } fConfigManager: IServiceConfigManager; @@ -208,6 +213,9 @@ procedure TChannelListBoxItem.FreeStyle; procedure TMainForm.FormCreate(Sender: TObject); begin + gbDebug.Visible := FindCmdLineSwitch('debug'); + DebugSplitter.Visible := gbDebug.Visible; + fConfigManager := ProxyServiceModule.ConfigManager; fConfigManager.AddListener(Self); @@ -533,20 +541,6 @@ procedure TMainForm.ceHDHRListenIPChangeTracking(Sender: TObject); end; end; -procedure TMainForm.btnDebugDiscoveryRequestClick(Sender: TObject); -var - lDiscovery: TDiscoveryData; - lBytes: TBytes; -begin - lDiscovery.DeviceType := HDHOMERUN_DEVICE_TYPE_TUNER; - lDiscovery.DeviceID := HDHOMERUN_DEVICE_ID_WILDCARD; - - lBytes := TPacket.FromDiscovery(True, lDiscovery).ToBytes; - - ProxyServerModule.DiscoveryServer.SendBuffer(eDebugIP.Text, HDHR_DISCOVERY_PORT, TIdBytes(lBytes)); -// ProxyServerModule.DiscoveryServer.Broadcast(TIdBytes(lBytes), HDHR_DISCOVERY_PORT); -end; - procedure TMainForm.UpdateChannelCount; var i, lChannelCount: Integer; @@ -638,4 +632,53 @@ function TMainForm.ExtractIP(const aComboEdit: TComboEdit): String; end; end; +procedure TMainForm.btnGetVideoSampleClick(Sender: TObject); +var + lStream: TCetonVideoStream; + lStopWatch: TStopWatch; + lBuffer: array[0..8191] of Byte; + lSize: Integer; + lFS: TFileStream; + lChannel: TChannelMapItem; + lFilename: String; +begin + lFilename := 'Sample.ts'; + + lChannel := TChannelMapItem.Create; + try + if Client.TryGetChannel(Round(seChannel.Value), lChannel) then + begin + lFilename := Format('SampleCh%dP%d.ts', [lChannel.Channel, lChannel.ItemProgram]); + end; + finally + lChannel.Free; + end; + + lFS := TFile.Create(ExtractFilePath(ParamStr(0))+lFilename); + try + lStream := TCetonVideoStream.Create(Client, -1, Round(seChannel.Value), False); + try + lStopWatch := TStopWatch.StartNew; + while lStopWatch.ElapsedMilliseconds <= 6000 do + begin + lSize := lStream.Read(lBuffer, SizeOf(lBuffer)); + if lSize = 0 then + Break; + + lFS.WriteBuffer(lBuffer, lSize); + end; + finally + lStream.Free; + end; + finally + lFS.Free; + end; +end; + +procedure TMainForm.MenuItem1Click(Sender: TObject); +begin + gbDebug.Visible := True; + DebugSplitter.Visible := True; +end; + end. diff --git a/ceton/Ceton.pas b/ceton/Ceton.pas index 9434459..6825592 100644 --- a/ceton/Ceton.pas +++ b/ceton/Ceton.pas @@ -318,7 +318,7 @@ TCetonVideoStream = class(TStream) function ConverterRead(const aBuf: PByte; const aSize: Integer): Integer; function ConverterWrite(const aBuf: PByte; const aSize: Integer): Integer; public - constructor Create(const aClient: TCetonClient; const aTuner: Integer; const aChannel: Integer); reintroduce; + constructor Create(const aClient: TCetonClient; const aTuner: Integer; const aChannel: Integer; const aRemux: Boolean = True); reintroduce; destructor Destroy; override; function Read(var Buffer; Count: Longint): Longint; override; @@ -1362,7 +1362,7 @@ function TCetonVideoStream.ConverterWrite(const aBuf: PByte; end; constructor TCetonVideoStream.Create(const aClient: TCetonClient; - const aTuner: Integer; const aChannel: Integer); + const aTuner: Integer; const aChannel: Integer; const aRemux: Boolean); var lChannel: TChannelMapItem; begin @@ -1373,17 +1373,20 @@ constructor TCetonVideoStream.Create(const aClient: TCetonClient; fClient.StartStream(aTuner, aChannel, fViewer); - lChannel := TChannelMapItem.Create; - try - if fClient.TryGetChannel(aChannel, lChannel) then - begin - fConverter := TVideoConverter.Create; - fConverter.OnRead := ConverterRead; - fConverter.OnWrite := ConverterWrite; - fConverter.ProgramFilter := lChannel.ItemProgram; + if aRemux then + begin + lChannel := TChannelMapItem.Create; + try + if fClient.TryGetChannel(aChannel, lChannel) then + begin + fConverter := TVideoConverter.Create; + fConverter.OnRead := ConverterRead; + fConverter.OnWrite := ConverterWrite; + fConverter.ProgramFilter := lChannel.ItemProgram; + end; + finally + lChannel.Free; end; - finally - lChannel.Free; end; end;