node build fixed
This commit is contained in:
188
seanime-2.9.10/internal/mediaplayers/mpchc/commands.go
Normal file
188
seanime-2.9.10/internal/mediaplayers/mpchc/commands.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package mpchc
|
||||
|
||||
const (
|
||||
setVolumeCmd = -2
|
||||
seekCmd = -1
|
||||
quickOpenFileCmd = 969
|
||||
openFileCmd = 800
|
||||
openDVDBDCmd = 801
|
||||
openDeviceCmd = 802
|
||||
reopenFileCmd = 976
|
||||
moveToRecycleBinCmd = 24044
|
||||
saveACopyCmd = 805
|
||||
saveImageCmd = 806
|
||||
saveImageAutoCmd = 807
|
||||
saveThumbnailsCmd = 808
|
||||
loadSubtitleCmd = 809
|
||||
saveSubtitleCmd = 810
|
||||
closeCmd = 804
|
||||
propertiesCmd = 814
|
||||
exitCmd = 816
|
||||
playPauseCmd = 889
|
||||
playCmd = 887
|
||||
pauseCmd = 888
|
||||
stopCmd = 890
|
||||
framestepCmd = 891
|
||||
framestepBackCmd = 892
|
||||
goToCmd = 893
|
||||
increaseRateCmd = 895
|
||||
decreaseRateCmd = 894
|
||||
resetRateCmd = 896
|
||||
audioDelayPlus10MsCmd = 905
|
||||
audioDelayMinus10MsCmd = 906
|
||||
jumpForwardSmallCmd = 900
|
||||
jumpBackwardSmallCmd = 899
|
||||
jumpForwardMediumCmd = 902
|
||||
jumpBackwardMediumCmd = 901
|
||||
jumpForwardLargeCmd = 904
|
||||
jumpBackwardLargeCmd = 903
|
||||
jumpForwardKeyframeCmd = 898
|
||||
jumpBackwardKeyframeCmd = 897
|
||||
jumpToBeginningCmd = 996
|
||||
nextCmd = 922
|
||||
previousCmd = 921
|
||||
nextFileCmd = 920
|
||||
previousFileCmd = 919
|
||||
tunerScanCmd = 974
|
||||
quickAddFavoriteCmd = 975
|
||||
toggleCaptionAndMenuCmd = 817
|
||||
toggleSeekerCmd = 818
|
||||
toggleControlsCmd = 819
|
||||
toggleInformationCmd = 820
|
||||
toggleStatisticsCmd = 821
|
||||
toggleStatusCmd = 822
|
||||
toggleSubresyncBarCmd = 823
|
||||
togglePlaylistBarCmd = 824
|
||||
toggleCaptureBarCmd = 825
|
||||
toggleNavigationBarCmd = 33415
|
||||
toggleDebugShadersCmd = 826
|
||||
viewMinimalCmd = 827
|
||||
viewCompactCmd = 828
|
||||
viewNormalCmd = 829
|
||||
fullscreenCmd = 830
|
||||
fullscreenWithoutResChangeCmd = 831
|
||||
zoom50Cmd = 832
|
||||
zoom100Cmd = 833
|
||||
zoom200Cmd = 834
|
||||
zoomAutoFitCmd = 968
|
||||
zoomAutoFitLargerOnlyCmd = 4900
|
||||
nextARPreseCmd = 859
|
||||
vidFrmHalfCmd = 835
|
||||
vidFrmNormalCmd = 836
|
||||
vidFrmDoubleCmd = 837
|
||||
vidFrmStretchCmd = 838
|
||||
vidFrmInsideCmd = 839
|
||||
vidFrmZoom1Cmd = 841
|
||||
vidFrmZoom2Cmd = 842
|
||||
vidFrmOutsideCmd = 840
|
||||
vidFrmSwitchZoomCmd = 843
|
||||
alwaysOnTopCmd = 884
|
||||
pnsResetCmd = 861
|
||||
pnsIncSizeCmd = 862
|
||||
pnsIncWidthCmd = 864
|
||||
pnsIncHeightCmd = 866
|
||||
pnsDecSizeCmd = 863
|
||||
pnsDecWidthCmd = 865
|
||||
pnsDecHeightCmd = 867
|
||||
pnsCenterCmd = 876
|
||||
pnsLeftCmd = 868
|
||||
pnsRightCmd = 869
|
||||
pnsUpCmd = 870
|
||||
pnsDownCmd = 871
|
||||
pnsUpLeftCmd = 872
|
||||
pnsUpRightCmd = 873
|
||||
pnsDownLeftCmd = 874
|
||||
pnsDownRightCmd = 875
|
||||
pnsRotateXPlusCmd = 877
|
||||
pnsRotateXMinusCmd = 878
|
||||
pnsRotateYPlusCmd = 879
|
||||
pnsRotateYMinusCmd = 880
|
||||
pnsRotateZPlusCmd = 881
|
||||
pnsRotateZMinusCmd = 882
|
||||
volumeUpCmd = 907
|
||||
volumeDownCmd = 908
|
||||
volumeMuteCmd = 909
|
||||
volumeBoostIncreaseCmd = 970
|
||||
volumeBoostDecreaseCmd = 971
|
||||
volumeBoostMinCmd = 972
|
||||
volumeBoostMaxCmd = 973
|
||||
toggleCustomChannelMappingCmd = 993
|
||||
toggleNormalizationCmd = 994
|
||||
toggleRegainVolumeCmd = 995
|
||||
brightnessIncreaseCmd = 984
|
||||
brightnessDecreaseCmd = 985
|
||||
contrastIncreaseCmd = 986
|
||||
contrastDecreaseCmd = 987
|
||||
hueIncreaseCmd = 988
|
||||
hueDecreaseCmd = 989
|
||||
saturationIncreaseCmd = 990
|
||||
saturationDecreaseCmd = 991
|
||||
resetColorSettingsCmd = 992
|
||||
dvdTitleMenuCmd = 923
|
||||
dvdRootMenuCmd = 924
|
||||
dvdSubtitleMenuCmd = 925
|
||||
dvdAudioMenuCmd = 926
|
||||
dvdAngleMenuCmd = 927
|
||||
dvdChapterMenuCmd = 928
|
||||
dvdMenuLeftCmd = 929
|
||||
dvdMenuRightCmd = 930
|
||||
dvdMenuUpCmd = 931
|
||||
dvdMenuDownCmd = 932
|
||||
dvdMenuActivateCmd = 933
|
||||
dvdMenuBackCmd = 934
|
||||
dvdMenuLeaveCmd = 935
|
||||
bossKeyCmd = 944
|
||||
playerMenuShortCmd = 949
|
||||
playerMenuLongCmd = 950
|
||||
filtersMenuCmd = 951
|
||||
optionsCmd = 815
|
||||
nextAudioCmd = 952
|
||||
prevAudioCmd = 953
|
||||
nextSubtitleCmd = 954
|
||||
prevSubtitleCmd = 955
|
||||
onOffSubtitleCmd = 956
|
||||
reloadSubtitlesCmd = 2302
|
||||
downloadSubtitlesCmd = 812
|
||||
nextAudioOGMCmd = 957
|
||||
prevAudioOGMCmd = 958
|
||||
nextSubtitleOGMCmd = 959
|
||||
prevSubtitleOGMCmd = 960
|
||||
nextAngleDVDCmd = 961
|
||||
prevAngleDVDCmd = 962
|
||||
nextAudioDVDCmd = 963
|
||||
prevAudioDVDCmd = 964
|
||||
nextSubtitleDVDCmd = 965
|
||||
prevSubtitleDVDCmd = 966
|
||||
onOffSubtitleDVDCmd = 967
|
||||
tearingTestCmd = 32769
|
||||
remainingTimeCmd = 32778
|
||||
nextShaderPresetCmd = 57382
|
||||
prevShaderPresetCmd = 57384
|
||||
toggleDirect3DFullscreenCmd = 32779
|
||||
gotoPrevSubtitleCmd = 32780
|
||||
gotoNextSubtitleCmd = 32781
|
||||
shiftSubtitleLeftCmd = 32782
|
||||
shiftSubtitleRightCmd = 32783
|
||||
displayStatsCmd = 32784
|
||||
resetDisplayStatsCmd = 33405
|
||||
vsyncCmd = 33243
|
||||
enableFrameTimeCorrectionCmd = 33265
|
||||
accurateVsyncCmd = 33260
|
||||
decreaseVsyncOffsetCmd = 33246
|
||||
increaseVsyncOffsetCmd = 33247
|
||||
subtitleDelayMinusCmd = 24000
|
||||
subtitleDelayPlusCmd = 24001
|
||||
afterPlaybackExitCmd = 912
|
||||
afterPlaybackStandByCmd = 913
|
||||
afterPlaybackHibernateCmd = 914
|
||||
afterPlaybackShutdownCmd = 915
|
||||
afterPlaybackLogOffCmd = 916
|
||||
afterPlaybackLockCmd = 917
|
||||
afterPlaybackTurnOffTheMonitorCmd = 918
|
||||
afterPlaybackPlayNextFileInTheFolderCmd = 947
|
||||
toggleEDLWindowCmd = 846
|
||||
edlSetInCmd = 847
|
||||
edlSetOutCmd = 848
|
||||
edlNewClipCmd = 849
|
||||
edlSaveCmd = 860
|
||||
)
|
||||
139
seanime-2.9.10/internal/mediaplayers/mpchc/mpc_hc.go
Normal file
139
seanime-2.9.10/internal/mediaplayers/mpchc/mpc_hc.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package mpchc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type MpcHc struct {
|
||||
Host string
|
||||
Port int
|
||||
Path string
|
||||
Logger *zerolog.Logger
|
||||
}
|
||||
|
||||
func (api *MpcHc) url() string {
|
||||
return fmt.Sprintf("http://%s:%d", api.Host, api.Port)
|
||||
}
|
||||
|
||||
// Execute sends a command to MPC and returns the response.
|
||||
func (api *MpcHc) Execute(command int, data map[string]interface{}) (string, error) {
|
||||
url := fmt.Sprintf("%s/command.html?wm_command=%d", api.url(), command)
|
||||
|
||||
if data != nil {
|
||||
queryParams := neturl.Values{}
|
||||
for key, value := range data {
|
||||
queryParams.Add(key, fmt.Sprintf("%v", value))
|
||||
}
|
||||
url += "&" + queryParams.Encode()
|
||||
}
|
||||
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to execute command")
|
||||
return "", err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
// Check HTTP status code and errors
|
||||
statusCode := response.StatusCode
|
||||
if !((statusCode >= 200) && (statusCode <= 299)) {
|
||||
err = fmt.Errorf("http error code: %d\n", statusCode)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Get byte response and http status code
|
||||
byteArr, readErr := io.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
err = fmt.Errorf("error reading response: %s\n", readErr)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Write response
|
||||
res := string(byteArr)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func escapeInput(input string) string {
|
||||
if strings.HasPrefix(input, "http") {
|
||||
return neturl.QueryEscape(input)
|
||||
} else {
|
||||
input = filepath.FromSlash(input)
|
||||
return strings.ReplaceAll(neturl.QueryEscape(input), "+", "%20")
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAndPlay opens a video file in MPC.
|
||||
func (api *MpcHc) OpenAndPlay(filePath string) (string, error) {
|
||||
url := fmt.Sprintf("%s/browser.html?path=%s", api.url(), escapeInput(filePath))
|
||||
api.Logger.Trace().Str("url", url).Msg("mpc hc: Opening and playing")
|
||||
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to connect to MPC")
|
||||
return "", err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
// Check HTTP status code and errors
|
||||
statusCode := response.StatusCode
|
||||
if !((statusCode >= 200) && (statusCode <= 299)) {
|
||||
err = fmt.Errorf("http error code: %d\n", statusCode)
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to open and play")
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Get byte response and http status code
|
||||
byteArr, readErr := io.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
err = fmt.Errorf("error reading response: %s\n", readErr)
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to open and play")
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Write response
|
||||
res := string(byteArr)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetVariables retrieves player variables from MPC.
|
||||
func (api *MpcHc) GetVariables() (*Variables, error) {
|
||||
url := fmt.Sprintf("%s/variables.html", api.url())
|
||||
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
||||
return &Variables{}, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
// Check HTTP status code and errors
|
||||
statusCode := response.StatusCode
|
||||
if !((statusCode >= 200) && (statusCode <= 299)) {
|
||||
err = fmt.Errorf("http error code: %d\n", statusCode)
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
||||
return &Variables{}, err
|
||||
}
|
||||
|
||||
// Get byte response and http status code
|
||||
byteArr, readErr := io.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
err = fmt.Errorf("error reading response: %s\n", readErr)
|
||||
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
||||
return &Variables{}, err
|
||||
}
|
||||
|
||||
// Write response
|
||||
res := string(byteArr)
|
||||
vars := parseVariables(res)
|
||||
|
||||
return vars, nil
|
||||
}
|
||||
101
seanime-2.9.10/internal/mediaplayers/mpchc/mpc_hc_test.go
Normal file
101
seanime-2.9.10/internal/mediaplayers/mpchc/mpc_hc_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package mpchc
|
||||
|
||||
import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"seanime/internal/test_utils"
|
||||
"seanime/internal/util"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMpcHc_Start(t *testing.T) {
|
||||
test_utils.InitTestProvider(t, test_utils.MediaPlayer())
|
||||
|
||||
mpc := &MpcHc{
|
||||
Host: test_utils.ConfigData.Provider.MpcHost,
|
||||
Path: test_utils.ConfigData.Provider.MpcPath,
|
||||
Port: test_utils.ConfigData.Provider.MpcPort,
|
||||
Logger: util.NewLogger(),
|
||||
}
|
||||
|
||||
err := mpc.Start()
|
||||
assert.NoError(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestMpcHc_Play(t *testing.T) {
|
||||
test_utils.InitTestProvider(t, test_utils.MediaPlayer())
|
||||
|
||||
mpc := &MpcHc{
|
||||
Host: test_utils.ConfigData.Provider.MpcHost,
|
||||
Path: test_utils.ConfigData.Provider.MpcPath,
|
||||
Port: test_utils.ConfigData.Provider.MpcPort,
|
||||
Logger: util.NewLogger(),
|
||||
}
|
||||
|
||||
err := mpc.Start()
|
||||
assert.NoError(t, err)
|
||||
|
||||
res, err := mpc.OpenAndPlay("E:\\ANIME\\Violet.Evergarden.The.Movie.1080p.Dual.Audio.BDRip.10.bits.DD.x265-EMBER.mkv")
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Log(res)
|
||||
|
||||
}
|
||||
|
||||
func TestMpcHc_GetVariables(t *testing.T) {
|
||||
test_utils.InitTestProvider(t, test_utils.MediaPlayer())
|
||||
|
||||
mpc := &MpcHc{
|
||||
Host: test_utils.ConfigData.Provider.MpcHost,
|
||||
Path: test_utils.ConfigData.Provider.MpcPath,
|
||||
Port: test_utils.ConfigData.Provider.MpcPort,
|
||||
Logger: util.NewLogger(),
|
||||
}
|
||||
|
||||
err := mpc.Start()
|
||||
assert.NoError(t, err)
|
||||
|
||||
res, err := mpc.GetVariables()
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
spew.Dump(res)
|
||||
|
||||
}
|
||||
|
||||
func TestMpcHc_Seek(t *testing.T) {
|
||||
test_utils.InitTestProvider(t, test_utils.MediaPlayer())
|
||||
|
||||
mpc := &MpcHc{
|
||||
Host: test_utils.ConfigData.Provider.MpcHost,
|
||||
Path: test_utils.ConfigData.Provider.MpcPath,
|
||||
Port: test_utils.ConfigData.Provider.MpcPort,
|
||||
Logger: util.NewLogger(),
|
||||
}
|
||||
|
||||
err := mpc.Start()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = mpc.OpenAndPlay("E:\\ANIME\\[SubsPlease] Bocchi the Rock! (01-12) (1080p) [Batch]\\[SubsPlease] Bocchi the Rock! - 01v2 (1080p) [ABDDAE16].mkv")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = mpc.Pause()
|
||||
|
||||
time.Sleep(400 * time.Millisecond)
|
||||
|
||||
err = mpc.Seek(100000)
|
||||
assert.NoError(t, err)
|
||||
|
||||
time.Sleep(400 * time.Millisecond)
|
||||
|
||||
err = mpc.Pause()
|
||||
|
||||
vars, err := mpc.GetVariables()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spew.Dump(vars)
|
||||
|
||||
}
|
||||
57
seanime-2.9.10/internal/mediaplayers/mpchc/start.go
Normal file
57
seanime-2.9.10/internal/mediaplayers/mpchc/start.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package mpchc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"seanime/internal/util"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (api *MpcHc) getExecutableName() string {
|
||||
if len(api.Path) > 0 {
|
||||
if strings.Contains(api.Path, "64") {
|
||||
return "mpc-hc64.exe"
|
||||
} else {
|
||||
return strings.Replace(api.Path, "C:\\Program Files\\MPC-HC\\", "", 1)
|
||||
}
|
||||
}
|
||||
return "mpc-hc64.exe"
|
||||
}
|
||||
|
||||
func (api *MpcHc) GetExecutablePath() string {
|
||||
|
||||
if len(api.Path) > 0 {
|
||||
return api.Path
|
||||
}
|
||||
|
||||
return "C:\\Program Files\\MPC-HC\\mpc-hc64.exe"
|
||||
}
|
||||
|
||||
func (api *MpcHc) isRunning(executable string) bool {
|
||||
cmd := util.NewCmd("tasklist")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.Contains(string(output), executable)
|
||||
}
|
||||
|
||||
func (api *MpcHc) Start() error {
|
||||
name := api.getExecutableName()
|
||||
exe := api.GetExecutablePath()
|
||||
if api.isRunning(name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := util.NewCmd(exe)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
api.Logger.Error().Err(err).Msg("mpc-hc: Error starting MPC-HC")
|
||||
return fmt.Errorf("error starting MPC-HC: %w", err)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
return nil
|
||||
}
|
||||
58
seanime-2.9.10/internal/mediaplayers/mpchc/status.go
Normal file
58
seanime-2.9.10/internal/mediaplayers/mpchc/status.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package mpchc
|
||||
|
||||
import "strconv"
|
||||
|
||||
func (api *MpcHc) Play() (err error) {
|
||||
_, err = api.Execute(playCmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (api *MpcHc) Pause() (err error) {
|
||||
_, err = api.Execute(pauseCmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (api *MpcHc) TogglePlay() (err error) {
|
||||
_, err = api.Execute(playPauseCmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (api *MpcHc) Stop() (err error) {
|
||||
_, err = api.Execute(stopCmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (api *MpcHc) ToggleFullScreen() (err error) {
|
||||
_, err = api.Execute(fullscreenCmd, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Seek position in ms
|
||||
func (api *MpcHc) Seek(pos int) (err error) {
|
||||
_, err = api.Execute(seekCmd, map[string]interface{}{"position": millisecondsToDuration(pos)})
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
func millisecondsToDuration(ms int) string {
|
||||
if ms <= 0 {
|
||||
return "00:00:00"
|
||||
}
|
||||
|
||||
duration := ms / 1000
|
||||
hours := duration / 3600
|
||||
duration %= 3600
|
||||
|
||||
minutes := duration / 60
|
||||
duration %= 60
|
||||
|
||||
return padStart(strconv.Itoa(hours), 2, "0") + ":" + padStart(strconv.Itoa(minutes), 2, "0") + ":" + padStart(strconv.Itoa(duration), 2, "0")
|
||||
}
|
||||
|
||||
func padStart(s string, length int, pad string) string {
|
||||
for len(s) < length {
|
||||
s = pad + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
68
seanime-2.9.10/internal/mediaplayers/mpchc/variables.go
Normal file
68
seanime-2.9.10/internal/mediaplayers/mpchc/variables.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package mpchc
|
||||
|
||||
import (
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Variables struct {
|
||||
Version string `json:"version"`
|
||||
File string `json:"file"`
|
||||
FilePath string `json:"filepath"`
|
||||
FileDir string `json:"filedir"`
|
||||
Size string `json:"size"`
|
||||
State int `json:"state"`
|
||||
StateString string `json:"statestring"`
|
||||
Position float64 `json:"position"`
|
||||
PositionString string `json:"positionstring"`
|
||||
Duration float64 `json:"duration"`
|
||||
DurationString string `json:"durationstring"`
|
||||
VolumeLevel float64 `json:"volumelevel"`
|
||||
Muted bool `json:"muted"`
|
||||
}
|
||||
|
||||
func parseVariables(variablePageHtml string) *Variables {
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(variablePageHtml))
|
||||
if err != nil {
|
||||
// Handle error
|
||||
return &Variables{}
|
||||
}
|
||||
|
||||
fields := make(map[string]string)
|
||||
|
||||
doc.Find("p").Each(func(_ int, s *goquery.Selection) {
|
||||
id, exists := s.Attr("id")
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
text := s.Text()
|
||||
fields[id] = text
|
||||
})
|
||||
|
||||
return &Variables{
|
||||
Version: fields["version"],
|
||||
File: fields["file"],
|
||||
FilePath: fields["filepath"],
|
||||
FileDir: fields["filedir"],
|
||||
Size: fields["size"],
|
||||
State: parseInt(fields["state"]),
|
||||
StateString: fields["statestring"],
|
||||
Position: parseFloat(fields["position"]),
|
||||
PositionString: fields["positionstring"],
|
||||
Duration: parseFloat(fields["duration"]),
|
||||
DurationString: fields["durationstring"],
|
||||
VolumeLevel: parseFloat(fields["volumelevel"]),
|
||||
Muted: fields["muted"] != "0",
|
||||
}
|
||||
}
|
||||
|
||||
func parseInt(value string) int {
|
||||
intValue, _ := strconv.Atoi(value)
|
||||
return intValue
|
||||
}
|
||||
|
||||
func parseFloat(value string) float64 {
|
||||
floatValue, _ := strconv.ParseFloat(value, 64)
|
||||
return floatValue
|
||||
}
|
||||
Reference in New Issue
Block a user