port mptv2 logic

This commit is contained in:
mykola2312 2025-08-23 13:41:08 +03:00
parent a82e78fdc7
commit 77dd8744b9

113
main.go
View file

@ -11,6 +11,7 @@ import (
"os/exec" "os/exec"
"regexp" "regexp"
"strings" "strings"
"time"
"golang.org/x/net/html" "golang.org/x/net/html"
) )
@ -19,7 +20,7 @@ type MPVRequest struct {
Command []string `json:"command"` Command []string `json:"command"`
} }
type MPVResponsePlayback struct { type MPVResponsePlayback struct {
Data float32 `json:"data"` Data float64 `json:"data"`
} }
type MPV struct { type MPV struct {
@ -72,7 +73,7 @@ func (mpv *MPV) ExecuteIPC(req *MPVRequest) ([]byte, error) {
return resBytes[:n], nil return resBytes[:n], nil
} }
func (mpv *MPV) InquirePlayback() (float32, error) { func (mpv *MPV) InquirePlayback() (float64, error) {
resBytes, err := mpv.ExecuteIPC(&MPVRequest{ resBytes, err := mpv.ExecuteIPC(&MPVRequest{
Command: []string{"get_property", "playback-time"}, Command: []string{"get_property", "playback-time"},
}) })
@ -131,31 +132,111 @@ func ParseWebMedia(url string) (string, error) {
re := regexp.MustCompile(`url:.*'(.*)'`) re := regexp.MustCompile(`url:.*'(.*)'`)
if match := re.FindAllStringSubmatch(streamChannels, 1); match != nil { if match := re.FindAllStringSubmatch(streamChannels, 1); match != nil {
fmt.Println(match)
return match[0][1], nil return match[0][1], nil
} else { } else {
return "", fmt.Errorf("regex failed") return "", fmt.Errorf("regex failed")
} }
} }
var testUrl string const MPTV_SPAWN_GRACE = 5 * time.Second
const MPTV_INQUIRE_INTERVAL = time.Second
const MPTV_MAX_ATTEMPTS = 1
var web string
var socketPath string
func main() { func main() {
flag.StringVar(&testUrl, "test-url", "", "test url") flag.StringVar(&web, "web", "", "web media")
flag.StringVar(&socketPath, "sock", "", "where to place socket")
flag.Parse() flag.Parse()
// mpv := NewMPV(testUrl, "/tmp/mptv3.sock") streamUrl, err := ParseWebMedia(web)
// mpv.Spawn() if err != nil {
// defer mpv.Stop() fmt.Fprintf(os.Stderr, "failed to get stream: %s\n", err)
return
}
// for { mpv := NewMPV(streamUrl, socketPath)
// time.Sleep(time.Second * 2) if err = mpv.Spawn(); err != nil {
// _, err := mpv.InquirePlayback() fmt.Fprintln(os.Stderr, err)
return
}
time.Sleep(MPTV_SPAWN_GRACE)
// fmt.Println(err) playback := 0.0
// } lastPlayback := 0.0
attempt := 0
stream, err := ParseWebMedia(testUrl) for {
fmt.Println(stream, err) fmt.Printf("playback %f lastPlayback %f attempt %d\n", playback, lastPlayback, attempt)
// inquire
playback, err = mpv.InquirePlayback()
if err != nil {
// dead mpv, restart
streamUrl, err = ParseWebMedia(web)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to get stream: %s\n", err)
// dont exit loop here since web request may fail due internet outage
}
mpv = NewMPV(streamUrl, socketPath)
if err = mpv.Spawn(); err != nil {
// failed to spawn mpv this time? fatal
fmt.Fprintln(os.Stderr, err)
return
}
// reset values
playback = 0.0
lastPlayback = 0.0
attempt = 0
// skip this cycle
time.Sleep(MPTV_SPAWN_GRACE)
continue
}
if lastPlayback == 0.0 {
// first init of last playback, dont count as attempt
lastPlayback = playback
} else if playback == lastPlayback {
// playback stuck, increment attempt
attempt += 1
if attempt > MPTV_MAX_ATTEMPTS {
// attempts exceeded, shoot in the head old mpv
mpv.Stop()
// respawn mpv
streamUrl, err = ParseWebMedia(web)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to get stream: %s\n", err)
// dont exit loop here since web request may fail due internet outage
}
mpv = NewMPV(streamUrl, socketPath)
if err = mpv.Spawn(); err != nil {
// failed to spawn mpv this time? fatal
fmt.Fprintln(os.Stderr, err)
return
}
// reset values
playback = 0.0
lastPlayback = 0.0
attempt = 0
// skip this cycle
time.Sleep(MPTV_SPAWN_GRACE)
continue
}
} else {
// playback doesnt match last playback that was already initalized - we're good
lastPlayback = playback
attempt = 0
}
// new cycle
time.Sleep(MPTV_INQUIRE_INTERVAL)
}
} }