use state machine to manage player state

This commit is contained in:
aynakeya
2025-08-07 01:09:07 +08:00
parent 3aebdb00f9
commit 5a699a1e2e
9 changed files with 105 additions and 50 deletions

View File

@@ -29,7 +29,7 @@ var EventsMapping = map[event.EventId]any{
PlayerPlayingUpdate: PlayerPlayingUpdateEvent{}, PlayerPlayingUpdate: PlayerPlayingUpdateEvent{},
PlayerPropertyPauseUpdate: PlayerPropertyPauseUpdateEvent{}, PlayerPropertyPauseUpdate: PlayerPropertyPauseUpdateEvent{},
PlayerPropertyPercentPosUpdate: PlayerPropertyPercentPosUpdateEvent{}, PlayerPropertyPercentPosUpdate: PlayerPropertyPercentPosUpdateEvent{},
PlayerPropertyIdleActiveUpdate: PlayerPropertyIdleActiveUpdateEvent{}, PlayerPropertyStateUpdate: PlayerPropertyStateUpdateEvent{},
PlayerPropertyTimePosUpdate: PlayerPropertyTimePosUpdateEvent{}, PlayerPropertyTimePosUpdate: PlayerPropertyTimePosUpdateEvent{},
PlayerPropertyDurationUpdate: PlayerPropertyDurationUpdateEvent{}, PlayerPropertyDurationUpdate: PlayerPropertyDurationUpdateEvent{},
PlayerPropertyVolumeUpdate: PlayerPropertyVolumeUpdateEvent{}, PlayerPropertyVolumeUpdate: PlayerPropertyVolumeUpdateEvent{},

View File

@@ -21,10 +21,10 @@ type PlayerPropertyPercentPosUpdateEvent struct {
PercentPos float64 PercentPos float64
} }
const PlayerPropertyIdleActiveUpdate = "update.player.property.idle_active" const PlayerPropertyStateUpdate = "update.player.property.state"
type PlayerPropertyIdleActiveUpdateEvent struct { type PlayerPropertyStateUpdateEvent struct {
IsIdle bool State model.PlayerState
} }
const PlayerPropertyTimePosUpdate = "update.player.property.time_pos" const PlayerPropertyTimePosUpdate = "update.player.property.time_pos"

View File

@@ -4,3 +4,27 @@ type AudioDevice struct {
Name string Name string
Description string Description string
} }
type PlayerState int
const (
PlayerStatePlaying PlayerState = iota
PlayerStateLoading
PlayerStateIdle
)
func (s PlayerState) NextState(next PlayerState) PlayerState {
if s == PlayerStatePlaying {
return next
}
if s == PlayerStateIdle {
return next
}
if s == PlayerStateLoading {
if next != PlayerStatePlaying {
return PlayerStateLoading
}
return next
}
return next
}

5
go.mod
View File

@@ -43,6 +43,7 @@ require (
github.com/BurntSushi/toml v1.5.0 // indirect github.com/BurntSushi/toml v1.5.0 // indirect
github.com/PuerkitoBio/goquery v1.10.3 // indirect github.com/PuerkitoBio/goquery v1.10.3 // indirect
github.com/XiaoMengXinX/Music163Api-Go v0.1.30 // indirect github.com/XiaoMengXinX/Music163Api-Go v0.1.30 // indirect
github.com/abadojack/whatlanggo v1.0.1 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/cascadia v1.3.3 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/aynakeya/deepcolor v1.0.3 // indirect github.com/aynakeya/deepcolor v1.0.3 // indirect
@@ -58,7 +59,7 @@ require (
github.com/go-text/render v0.2.0 // indirect github.com/go-text/render v0.2.0 // indirect
github.com/go-text/typesetting v0.2.1 // indirect github.com/go-text/typesetting v0.2.1 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.5.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
github.com/jinzhu/copier v0.4.0 // indirect github.com/jinzhu/copier v0.4.0 // indirect
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
@@ -80,7 +81,7 @@ require (
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
golang.org/x/net v0.42.0 // indirect golang.org/x/net v0.42.0 // indirect
golang.org/x/text v0.27.0 // indirect golang.org/x/text v0.27.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

13
go.sum
View File

@@ -11,6 +11,8 @@ github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiU
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y= github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
github.com/XiaoMengXinX/Music163Api-Go v0.1.30 h1:MqRItDFtX1J0JTlFtwN2RwjsYMA7/g/+cTjcOJXy19s= github.com/XiaoMengXinX/Music163Api-Go v0.1.30 h1:MqRItDFtX1J0JTlFtwN2RwjsYMA7/g/+cTjcOJXy19s=
github.com/XiaoMengXinX/Music163Api-Go v0.1.30/go.mod h1:kLU/CkLxKnEJFCge0URvQ0lHt6ImoG1/2aVeNbgV2RQ= github.com/XiaoMengXinX/Music163Api-Go v0.1.30/go.mod h1:kLU/CkLxKnEJFCge0URvQ0lHt6ImoG1/2aVeNbgV2RQ=
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
github.com/adrg/libvlc-go/v3 v3.1.6 h1:Cm22w6xNMDdzYCW8koHgAvjonYm4xbPP5TrlVTtMdl4= github.com/adrg/libvlc-go/v3 v3.1.6 h1:Cm22w6xNMDdzYCW8koHgAvjonYm4xbPP5TrlVTtMdl4=
github.com/adrg/libvlc-go/v3 v3.1.6/go.mod h1:xJK0YD8cyMDejnrTFQinStE6RYCV1nlfS8KmqTpszSc= github.com/adrg/libvlc-go/v3 v3.1.6/go.mod h1:xJK0YD8cyMDejnrTFQinStE6RYCV1nlfS8KmqTpszSc=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
@@ -70,8 +72,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE= github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE=
@@ -80,8 +82,8 @@ github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M= github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw= github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
github.com/k0kubun/pp/v3 v3.4.1 h1:1WdFZDRRqe8UsR61N/2RoOZ3ziTEqgTPVqKrHeb779Y= github.com/k0kubun/pp/v3 v3.5.0 h1:iYNlYA5HJAJvkD4ibuf9c8y6SHM0QFhaBuCqm1zHp0w=
github.com/k0kubun/pp/v3 v3.4.1/go.mod h1:+SiNiqKnBfw1Nkj82Lh5bIeKQOAkPy6Xw9CAZUZ8npI= github.com/k0kubun/pp/v3 v3.5.0/go.mod h1:5lzno5ZZeEeTV/Ky6vs3g6d1U3WarDrH8k240vMtGro=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -237,8 +239,9 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -2,6 +2,7 @@ package gui
import ( import (
"AynaLivePlayer/core/events" "AynaLivePlayer/core/events"
"AynaLivePlayer/core/model"
"AynaLivePlayer/global" "AynaLivePlayer/global"
"AynaLivePlayer/gui/component" "AynaLivePlayer/gui/component"
"AynaLivePlayer/gui/gutil" "AynaLivePlayer/gui/gutil"
@@ -84,9 +85,9 @@ func registerPlayControllerHandler() {
PlayController.Progress.Refresh() PlayController.Progress.Refresh()
})) }))
global.EventManager.RegisterA(events.PlayerPropertyIdleActiveUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *event.Event) { global.EventManager.RegisterA(events.PlayerPropertyStateUpdate, "gui.player.controller.idle_active", gutil.ThreadSafeHandler(func(event *event.Event) {
isIdle := event.Data.(events.PlayerPropertyIdleActiveUpdateEvent).IsIdle state := event.Data.(events.PlayerPropertyStateUpdateEvent).State
if isIdle { if state == model.PlayerStateIdle || state == model.PlayerStateLoading {
PlayController.Progress.Value = 0 PlayController.Progress.Value = 0
PlayController.Progress.Max = 0 PlayController.Progress.Max = 0
//PlayController.Title.SetText("Title") //PlayController.Title.SetText("Title")
@@ -178,7 +179,6 @@ func registerPlayControllerHandler() {
PlayController.Cover.Resource = pic.Resource PlayController.Cover.Resource = pic.Resource
gutil.RunInFyneThread(PlayController.Cover.Refresh) gutil.RunInFyneThread(PlayController.Cover.Refresh)
} }
}() }()
} }
})) }))

View File

@@ -21,25 +21,39 @@ func Stop() {
func handlePlayNext() { func handlePlayNext() {
log := global.Logger.WithPrefix("Controller") log := global.Logger.WithPrefix("Controller")
isIdle := false playerState := model.PlayerStatePlaying
global.EventManager.RegisterA( global.EventManager.RegisterA(
events.PlayerPropertyIdleActiveUpdate, events.PlayerPropertyStateUpdate,
"internal.controller.playcontrol.idleplaynext", "internal.controller.playcontrol.idleplaynext",
func(event *event.Event) { func(event *event.Event) {
data := event.Data.(events.PlayerPropertyIdleActiveUpdateEvent) data := event.Data.(events.PlayerPropertyStateUpdateEvent)
isIdle = data.IsIdle log.Debug("[MPV PlayControl] update player to state", playerState, "->", data.State)
if data.IsIdle { playerState = data.State
if playerState == model.PlayerStateIdle {
log.Info("mpv went idle, try play next") log.Info("mpv went idle, try play next")
global.EventManager.CallA(events.PlayerPlayNextCmd, global.EventManager.CallA(events.PlayerPlayNextCmd,
events.PlayerPlayNextCmdEvent{}) events.PlayerPlayNextCmdEvent{})
} }
}) })
global.EventManager.RegisterA(
events.PlayerPropertyStateUpdate,
"internal.controller.playcontrol.clear_when_idle", func(event *event.Event) {
data := event.Data.(events.PlayerPropertyStateUpdateEvent)
// if is idle, remove playing media
if data.State == model.PlayerStateIdle {
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{
Media: model.Media{},
Removed: true,
})
}
})
global.EventManager.RegisterA( global.EventManager.RegisterA(
events.PlaylistInsertUpdate(model.PlaylistIDPlayer), events.PlaylistInsertUpdate(model.PlaylistIDPlayer),
"internal.controller.playcontrol.playnext_when_insert.player", "internal.controller.playcontrol.playnext_when_insert.player",
func(event *event.Event) { func(event *event.Event) {
if isIdle && config.General.PlayNextOnFail { if playerState == model.PlayerStateIdle {
global.EventManager.CallA(events.PlayerPlayNextCmd, global.EventManager.CallA(events.PlayerPlayNextCmd,
events.PlayerPlayNextCmdEvent{}) events.PlayerPlayNextCmdEvent{})
} }
@@ -49,7 +63,7 @@ func handlePlayNext() {
events.PlaylistInsertUpdate(model.PlaylistIDSystem), events.PlaylistInsertUpdate(model.PlaylistIDSystem),
"internal.controller.playcontrol.playnext_when_insert.system", "internal.controller.playcontrol.playnext_when_insert.system",
func(event *event.Event) { func(event *event.Event) {
if isIdle && config.General.PlayNextOnFail { if playerState == model.PlayerStateIdle {
global.EventManager.CallA(events.PlayerPlayNextCmd, global.EventManager.CallA(events.PlayerPlayNextCmd,
events.PlayerPlayNextCmdEvent{}) events.PlayerPlayNextCmdEvent{})
} }
@@ -82,8 +96,9 @@ func handlePlayNext() {
events.PlayerPlayErrorUpdate, events.PlayerPlayErrorUpdate,
"internal.controller.playcontrol.playnext_on_error", "internal.controller.playcontrol.playnext_on_error",
func(event *event.Event) { func(event *event.Event) {
if isIdle && config.General.PlayNextOnFail { if config.General.PlayNextOnFail {
global.EventManager.CallA(events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{}) global.EventManager.CallA(events.PlayerPlayNextCmd, events.PlayerPlayNextCmdEvent{})
return
} }
}) })

View File

@@ -95,6 +95,7 @@ func StopPlayer() {
var prevPercentPos float64 = 0 var prevPercentPos float64 = 0
var prevTimePos float64 = 0 var prevTimePos float64 = 0
var currentState = model.PlayerStateIdle
var mpvPropertyHandler = map[string]func(value any){ var mpvPropertyHandler = map[string]func(value any){
"pause": func(value any) { "pause": func(value any) {
@@ -123,20 +124,20 @@ var mpvPropertyHandler = map[string]func(value any){
}, },
"idle-active": func(value any) { "idle-active": func(value any) {
var data events.PlayerPropertyIdleActiveUpdateEvent var data events.PlayerPropertyStateUpdateEvent
if value == nil { if value == nil {
data.IsIdle = true data.State = model.PlayerStateIdle
} else { } else {
data.IsIdle = value.(bool) if value.(bool) {
data.State = model.PlayerStateIdle
} else {
data.State = model.PlayerStatePlaying
}
} }
// if is idle, remove playing media log.Debugf("mpv state update %v + %v = %v", currentState, data.State, currentState.NextState(data.State))
if data.IsIdle { currentState = currentState.NextState(data.State)
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{ data.State = currentState
Media: model.Media{}, global.EventManager.CallA(events.PlayerPropertyStateUpdate, data)
Removed: true,
})
}
global.EventManager.CallA(events.PlayerPropertyIdleActiveUpdate, data)
}, },
"time-pos": func(value any) { "time-pos": func(value any) {
@@ -190,15 +191,28 @@ func registerHandler() {
func registerCmdHandler() { func registerCmdHandler() {
global.EventManager.RegisterA(events.PlayerPlayCmd, "player.play", func(evnt *event.Event) { global.EventManager.RegisterA(events.PlayerPlayCmd, "player.play", func(evnt *event.Event) {
currentState = currentState.NextState(model.PlayerStateLoading)
global.EventManager.CallA(
events.PlayerPropertyStateUpdate,
events.PlayerPropertyStateUpdateEvent{
State: currentState,
})
mediaInfo := evnt.Data.(events.PlayerPlayCmdEvent).Media.Info mediaInfo := evnt.Data.(events.PlayerPlayCmdEvent).Media.Info
media := evnt.Data.(events.PlayerPlayCmdEvent).Media
if m, err := miaosic.GetMediaInfo(media.Info.Meta); err == nil {
media.Info = m
}
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{
Media: media,
Removed: false,
})
log.Infof("[MPV Player] Play media %s", mediaInfo.Title) log.Infof("[MPV Player] Play media %s", mediaInfo.Title)
mediaUrls, err := miaosic.GetMediaUrl(mediaInfo.Meta, miaosic.QualityAny) mediaUrls, err := miaosic.GetMediaUrl(mediaInfo.Meta, miaosic.QualityAny)
if err != nil || len(mediaUrls) == 0 { if err != nil || len(mediaUrls) == 0 {
log.Warn("[MPV PlayControl] get media url failed ", mediaInfo.Meta.ID(), err) log.Warn("[MPV PlayControl] get media url failed ", mediaInfo.Meta.ID(), err)
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{ if err := libmpv.Command([]string{"stop"}); err != nil {
Media: evnt.Data.(events.PlayerPlayCmdEvent).Media, log.Error("[MPV PlayControl] failed to stop", err)
Removed: false, }
})
global.EventManager.CallA( global.EventManager.CallA(
events.PlayerPlayErrorUpdate, events.PlayerPlayErrorUpdate,
events.PlayerPlayErrorUpdateEvent{ events.PlayerPlayErrorUpdateEvent{
@@ -224,14 +238,6 @@ func registerCmdHandler() {
return return
} }
} }
media := evnt.Data.(events.PlayerPlayCmdEvent).Media
if m, err := miaosic.GetMediaInfo(media.Info.Meta); err == nil {
media.Info = m
}
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{
Media: media,
Removed: false,
})
log.Debugf("mpv command loadfile %s %s", mediaInfo.Title, mediaUrl.Url) log.Debugf("mpv command loadfile %s %s", mediaInfo.Title, mediaUrl.Url)
cmd := []string{"loadfile", mediaUrl.Url} cmd := []string{"loadfile", mediaUrl.Url}
if cfg.DisplayMusicCover && media.Info.Cover.Url != "" { if cfg.DisplayMusicCover && media.Info.Cover.Url != "" {
@@ -254,6 +260,12 @@ func registerCmdHandler() {
}) })
return return
} }
currentState = currentState.NextState(model.PlayerStatePlaying)
global.EventManager.CallA(
events.PlayerPropertyStateUpdate,
events.PlayerPropertyStateUpdateEvent{
State: currentState,
})
global.EventManager.CallA(events.PlayerPropertyTimePosUpdate, events.PlayerPropertyTimePosUpdateEvent{ global.EventManager.CallA(events.PlayerPropertyTimePosUpdate, events.PlayerPropertyTimePosUpdateEvent{
TimePos: 0, TimePos: 0,
}) })

View File

@@ -133,8 +133,8 @@ func StopPlayer() {
func registerEvents() { func registerEvents() {
// 播放结束事件 // 播放结束事件
_, err := eventManager.Attach(vlc.MediaPlayerEndReached, func(e vlc.Event, userData interface{}) { _, err := eventManager.Attach(vlc.MediaPlayerEndReached, func(e vlc.Event, userData interface{}) {
global.EventManager.CallA(events.PlayerPropertyIdleActiveUpdate, events.PlayerPropertyIdleActiveUpdateEvent{ global.EventManager.CallA(events.PlayerPropertyStateUpdate, events.PlayerPropertyStateUpdateEvent{
IsIdle: true, State: model.PlayerStateIdle,
}) })
global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{ global.EventManager.CallA(events.PlayerPlayingUpdate, events.PlayerPlayingUpdateEvent{
Media: model.Media{}, Media: model.Media{},
@@ -300,8 +300,8 @@ func registerCmdHandler() {
global.EventManager.CallA(events.PlayerPropertyPercentPosUpdate, events.PlayerPropertyPercentPosUpdateEvent{ global.EventManager.CallA(events.PlayerPropertyPercentPosUpdate, events.PlayerPropertyPercentPosUpdateEvent{
PercentPos: 0, PercentPos: 0,
}) })
global.EventManager.CallA(events.PlayerPropertyIdleActiveUpdate, events.PlayerPropertyIdleActiveUpdateEvent{ global.EventManager.CallA(events.PlayerPropertyStateUpdate, events.PlayerPropertyStateUpdateEvent{
IsIdle: false, State: model.PlayerStatePlaying,
}) })
}) })