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.
This commit is contained in:
commit
2fa8f2435f
121 changed files with 17802 additions and 0 deletions
100
apps/pkg/capture/score.go
Normal file
100
apps/pkg/capture/score.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
package capture
|
||||
|
||||
import "strings"
|
||||
|
||||
// ScoreCfg ranks candidate URLs seen by the MITM so a schedule/EPG/analytics URL
|
||||
// is never mistaken for a stream manifest. Providers supply their own hosts and
|
||||
// noise needles; this package ships only format-level scoring.
|
||||
type ScoreCfg struct {
|
||||
// Deny: any match scores the URL out entirely.
|
||||
Deny []string `yaml:"deny"`
|
||||
// Hosts: known-good manifest hosts for this provider.
|
||||
Hosts []string `yaml:"hosts"`
|
||||
// HostBonus is added when a Hosts entry matches (default 50).
|
||||
HostBonus int `yaml:"host_bonus"`
|
||||
}
|
||||
|
||||
// DefaultScoreCfg is the provider-neutral baseline: catalog/analytics shapes that
|
||||
// are never a manifest for anyone.
|
||||
func DefaultScoreCfg() ScoreCfg {
|
||||
return ScoreCfg{
|
||||
Deny: []string{
|
||||
"schedules", "bylistingtime", "maxlistings", "bycallsign",
|
||||
"/feed.", "playback_config", "config.json",
|
||||
},
|
||||
HostBonus: 50,
|
||||
}
|
||||
}
|
||||
|
||||
// Merge overlays a provider's hosts and extra deny needles on the baseline.
|
||||
func (s ScoreCfg) Merge(other ScoreCfg) ScoreCfg {
|
||||
out := s
|
||||
out.Deny = append(append([]string{}, s.Deny...), other.Deny...)
|
||||
out.Hosts = append(append([]string{}, s.Hosts...), other.Hosts...)
|
||||
if other.HostBonus != 0 {
|
||||
out.HostBonus = other.HostBonus
|
||||
}
|
||||
if out.HostBonus == 0 {
|
||||
out.HostBonus = 50
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Score rates a URL as a live manifest. Zero or negative means "not a manifest".
|
||||
func (s ScoreCfg) Score(u string) int {
|
||||
lu := strings.ToLower(u)
|
||||
path := lu
|
||||
if i := strings.Index(path, "?"); i >= 0 {
|
||||
path = path[:i]
|
||||
}
|
||||
for _, bad := range s.Deny {
|
||||
if bad != "" && strings.Contains(lu, strings.ToLower(bad)) {
|
||||
return -100
|
||||
}
|
||||
}
|
||||
score := 0
|
||||
bonus := s.HostBonus
|
||||
if bonus == 0 {
|
||||
bonus = 50
|
||||
}
|
||||
for _, host := range s.Hosts {
|
||||
if host != "" && strings.Contains(lu, strings.ToLower(host)) {
|
||||
score += bonus
|
||||
break
|
||||
}
|
||||
}
|
||||
// Format-level signals — true for any provider.
|
||||
if strings.Contains(path, "playlist-hls") || strings.Contains(path, "playlist.m3u8") {
|
||||
score += 40
|
||||
}
|
||||
if strings.Contains(path, "chunklist") {
|
||||
score += 10
|
||||
}
|
||||
if strings.HasSuffix(path, ".m3u8") {
|
||||
score += 5
|
||||
}
|
||||
if strings.HasSuffix(path, ".mpd") || strings.Contains(path, "manifest.mpd") {
|
||||
score += 30
|
||||
}
|
||||
if strings.Contains(path, ".isml") || strings.Contains(path, "/manifest") {
|
||||
score += 20
|
||||
}
|
||||
return score
|
||||
}
|
||||
|
||||
// ProxyArgs renders this config as flags for the on-device MITM, which runs on
|
||||
// the phone and cannot read an app module's values file itself.
|
||||
func (s ScoreCfg) ProxyArgs() []string {
|
||||
out := []string{}
|
||||
for _, h := range s.Hosts {
|
||||
if h != "" {
|
||||
out = append(out, "-score-host", h)
|
||||
}
|
||||
}
|
||||
for _, d := range s.Deny {
|
||||
if d != "" {
|
||||
out = append(out, "-score-deny", d)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue