Skip to content

Commit 5fa2cbb

Browse files
committed
Fix bug when media switches on the chromecast
There is a bug when the chromecast changes media application, and 'go-chromecast' woudl try and write to the 'mediaFinished' channel regardless of whether it was initialised or not. This is because of the poor design of the internals, the 'mediaFinished' is littered throughout the codebase but is only relevant to the 'load' command. This needs some cleaning up in a future refactor. For now just fix the bug by not writing to the channel if it hasn't been initialised. Updates: #70
1 parent d8f978d commit 5fa2cbb

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

application/application.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ func (a *Application) messageChanHandler() {
169169
}
170170
}
171171

172+
// TODO: Clean-up: these Media* methods are a hack around trying
173+
// to use the mediaFinished channel when it hasn't been properly
174+
// set up. This is happening because there is some instances where we don't
175+
// have any running media ('watch' command) but yet the 'mediaFinished'
176+
// is littered throughout the codebase since. This needs a redesign now that
177+
// we do things other than just loading and playing media files.
178+
func (a *Application) MediaStart() {
179+
a.mediaFinished = make(chan bool, 1)
180+
}
181+
182+
func (a *Application) MediaWait() {
183+
<-a.mediaFinished
184+
a.mediaFinished = nil
185+
}
186+
187+
func (a *Application) MediaFinished() {
188+
if a.mediaFinished == nil {
189+
return
190+
}
191+
a.mediaFinished <- true
192+
}
193+
172194
func (a *Application) recvMessages() {
173195
for msg := range a.recvMsgChan {
174196
requestID, err := jsonparser.GetInt([]byte(*msg.PayloadUtf8), "requestId")
@@ -186,19 +208,19 @@ func (a *Application) recvMessages() {
186208
messageType, _ := jsonparser.GetString(messageBytes, "type")
187209
switch messageType {
188210
case "LOAD_FAILED":
189-
a.mediaFinished <- true
211+
a.MediaFinished()
190212
case "MEDIA_STATUS":
191213
resp := cast.MediaStatusResponse{}
192214
if err := json.Unmarshal(messageBytes, &resp); err == nil {
193215
for _, status := range resp.Status {
194216
// The LoadingItemId is only set when there is a playlist and there
195217
// is an item being loaded to play next.
196218
if status.IdleReason == "FINISHED" && status.LoadingItemId == 0 {
197-
a.mediaFinished <- true
219+
a.MediaFinished()
198220
} else if status.IdleReason == "INTERRUPTED" && status.Media.ContentId == "" {
199221
// This can happen when we go "next" in a playlist when it
200222
// is playing the last track.
201-
a.mediaFinished <- true
223+
a.MediaFinished()
202224
}
203225
}
204226
}
@@ -214,7 +236,7 @@ func (a *Application) recvMessages() {
214236
// it because that currently isn't possible.
215237
for _, app := range resp.Status.Applications {
216238
if app.AppId != a.application.AppId {
217-
a.mediaFinished <- true
239+
a.MediaFinished()
218240
}
219241
a.application = &app
220242
}
@@ -276,6 +298,7 @@ func (a *Application) Update() error {
276298
if err == nil {
277299
break
278300
}
301+
a.log("error getting receiever status: %v", err)
279302
a.log("unable to get status from device; attempt %d/5, retrying...", i+1)
280303
time.Sleep(time.Second * 2)
281304
}
@@ -608,7 +631,7 @@ func (a *Application) Load(filenameOrUrl, contentType string, transcode, detach
608631
}
609632

610633
// NOTE: This isn't concurrent safe, but it doesn't need to be at the moment!
611-
a.mediaFinished = make(chan bool, 1)
634+
a.MediaStart()
612635

613636
// Send the command to the chromecast
614637
a.sendMediaRecv(&cast.LoadMediaCommand{
@@ -629,7 +652,7 @@ func (a *Application) Load(filenameOrUrl, contentType string, transcode, detach
629652
}
630653

631654
// Wait until we have been notified that the media has finished playing
632-
<-a.mediaFinished
655+
a.MediaWait()
633656
return nil
634657
}
635658

@@ -667,7 +690,9 @@ func (a *Application) QueueLoad(filenames []string, contentType string, transcod
667690
})
668691

669692
// Wait until we have been notified that the media has finished playing
670-
<-a.mediaFinished
693+
// TODO: This does nothing. This hasn't been initialised and just blocks
694+
// forever.
695+
a.MediaWait()
671696
return nil
672697
}
673698

@@ -752,7 +777,9 @@ func (a *Application) Slideshow(filenames []string, duration int, repeat bool) e
752777
if err := a.Next(); err != nil {
753778
return err
754779
}
755-
// Media has finished playing
780+
// Media has finished playing.
781+
// TODO: Hack, how to ensure this is always possible
782+
// to wait on.
756783
case <-a.mediaFinished:
757784
return nil
758785
}

0 commit comments

Comments
 (0)