First skill - can't get mycroft to play SomaFM MP3 URL

I’m a first-time skill maker and a relative newbie to Python. But I wanted to create a simple skill to learn more about how to build Mycroft skills. My thought was a simple play command for playing SomaFM streams.

I’ve seen a number of radio playing skills but rather than try to get those working, I want to create a simple skill to learn.

So I used mycroft-msk to create a basic skill. I followed/reviewed the code of similar skills like news, and followed a Common Playback Framework tutorial on Mycroft’s site. The resulting skill seems to be valid, and works as expected with 1 omission: Mycroft goes to play the MP3 URL and makes no sound at all.

I was following a more complex skill’s capabilities, because when I install that skill I see Mycroft does stream SomaFM if I speak the right command: GitHub - hughwilliams94/radio-browser-skill: Find and play radio streams using Mycroft

But then I found all sorts of skills doing this simple task all sorts of different ways. The CPF documentation doesn’t seem helpful to me…

So I’m hoping the community of skill builders can help me out. Here’s my skill: GitHub - kbridger/somafm-player-skill: Plays somafm streams

Here’s the logs when I trigger the skill successfully

 23:30:37.332 | INFO     | 203218 | Playback Control Skill | Resolving Player for: salad
 23:30:44.102 | INFO     | 203218 | Playback Control Skill | Playing with: somafm-player-skill
 23:30:44.187 | INFO     | 203218 | SomafmPlayer | Playing from: https://ice4.somafm.com/groovesalad-128-mp3
 23:30:44.230 | INFO     | 203218 | Playback Control Skill | Audio service status: {}

What happens is Mycroft speaks as expected, and then silence. No audio. I am almost certain that it isn’t related to Mycroft but rather my skill, because I was able to get this working with some other skills.

Any advice on how to properly get Mycroft to stream SomaFM? Should it be a CPF skill? Am I not using that correctly? Help and insight appreciated!

I added a lot of self.log.log() calls so as to better understand what the code is doing.

-Mike Mac

I went through the logging video here: Logging - Mycroft AI I’ve got all sorts of logs working and I can see that everything is working from my skill side. But I think the URL is being passed to the Mycroft code and I’m not sure what’s happening in there.

I switched to debug mode in the CLI, and see nothing being output. I’m not sure how to trace things back through the code but will be trying that next. Basically I see

20:01:27.514 | INFO     | 603909 | Playback Control Skill | Audio service status: {}

and I want to understand if this is usual, how to output more about what’s going on in the Mycroft code so I can follow the flow of info.

I’ve confirmed that mycroft.conf has mpg123 as the MP3 player, and that playing the URL from the same terminal does play it properly.

So how do I dig into what’s going on in the Mycroft code? Is it just following the python rabbit hole?

I’m in the same boat.

So I add/massage some log messages in the common playback skill:

$ pwd
/opt/mycroft/skills/mycroft-playback-control.mycroftai
$ diff __init__.py __init__.py.orig
104d103
<         self.log.info("handle_next(): Moving to next track")
109d107
<         self.log.info("handle_prev(): Moving to previous track")
114d111
<         self.log.info("handle_pause(): Pausing audio")
119d115
<         self.log.info("handle_play(): Playing audio")
126c122
<         self.log.info('stop(): Audio service status: '
---
>         self.log.info('Audio service status: '
161c157
<         self.log.info("play(): Resolving Player for: "+phrase)
---
>         self.log.info("Resolving Player for: "+phrase)
235c231
<             self.log.info("_play_query_timeout(): CommonPlay Resolution: {}".format(search_phrase))
---
>             self.log.debug("CommonPlay Resolution: {}".format(search_phrase))
237c233
<                 self.log.info("_play_query_timeout(): {} using {}".format(handler["conf"],
---
>                 self.log.debug("    {} using {}".format(handler["conf"],
248c244
<                     self.log.info("_play_query_timeout(): Skills tied, choosing randomly")
---
>                     self.log.info("Skills tied, choosing randomly")
250c246
<                     self.log.info("_play_query_timeout(): Skills: " +
---
>                     self.log.debug("Skills: " +
259c255
<                 self.log.info("_play_query_timeout(): Playing with: {}".format(selected["skill_id"]))
---
>                 self.log.info("Playing with: {}".format(selected["skill_id"]))
268c264
<                 self.log.info("_play_query_timeout(): No matches")
---
>                 self.log.info("   No matches")

It’s a start, I plan to refine over the next week or so.

Hope this helps.

-Mike Mac