Null-DRM-Official/apps/modules/rte/steps.go
404errordeveloper 2fa8f2435f Initial commit: Null DRM Official
Capture, decrypt, and restream toolkit with compiled-in app modules
(RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www.
BBC module.yaml is published (clear streams); other module values stay local.
2026-10-06 00:25:35 +02:00

61 lines
1.8 KiB
Go

package rte
import (
"fmt"
"regexp"
"time"
"drmdecryption/adb"
"drmdecryption/uiflow"
)
// tapChipThenPlay is this app's navigation idiom: on the Live tab, tap the
// channel chip, then the large hero Play button that appears. If the hero button
// is already on screen, tap it directly.
func (a *App) tapChipThenPlay(c *adb.Client, ch Channel) error {
playPats := uiflow.CompileRes(ch.PlayDesc)
chipPats := uiflow.CompileRes(ch.ChipDesc)
nodes, err := c.DumpUI(a.CacheDir())
if err != nil {
return err
}
if cand := a.findHeroPlay(nodes, playPats); cand != nil {
fmt.Printf("[*] tap Play @ %d,%d\n", cand.CX(), cand.CY())
return c.Tap(cand.CX(), cand.CY())
}
chip := adb.FindSmallest(nodes, chipPats)
if chip == nil {
chip, err = c.WaitFor(a.CacheDir(), nil, chipPats, time.Duration(a.cfg.Timeouts.ChipWait))
if err != nil {
return fmt.Errorf("chip not found: %w", err)
}
}
fmt.Printf("[*] tap chip @ %d,%d\n", chip.CX(), chip.CY())
_ = c.Tap(chip.CX(), chip.CY())
time.Sleep(time.Duration(a.cfg.Timeouts.AfterChip))
deadline := time.Now().Add(time.Duration(a.cfg.Timeouts.PlayWait))
for time.Now().Before(deadline) {
nodes, err = c.DumpUI(a.CacheDir())
if err == nil {
if cand := a.findHeroPlay(nodes, playPats); cand != nil {
fmt.Printf("[*] tap Play @ %d,%d\n", cand.CX(), cand.CY())
return c.Tap(cand.CX(), cand.CY())
}
}
time.Sleep(700 * time.Millisecond)
}
return fmt.Errorf("Play button did not appear")
}
// findHeroPlay accepts a Play match only if it is big enough to be the hero
// button rather than a small list-item play icon.
func (a *App) findHeroPlay(nodes []adb.Node, playPats []*regexp.Regexp) *adb.Node {
cand := adb.FindLargest(nodes, nil, playPats)
if cand == nil || cand.Area() < a.cfg.HeroMinArea {
return nil
}
return cand
}