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.
61 lines
1.8 KiB
Go
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
|
|
}
|