A small local media playlist: an OCP skill¶
In a nutshell
You build an OVOSCommonPlaybackSkill that serves a short, fixed local playlist through OCP's @ocp_search provider mechanism.
When you'd want this: "play the office playlist" should hand back a short, fixed list of local audio files. It should need no external search or streaming service.
Prerequisite: the base class and decorator ship with ovos-workshop. Matching "play …"
requests requires the OCP pipeline stage. Check it is installed (pip show
ovos-ocp-pipeline-plugin) and in your intents.pipeline, the same way
Your First Skill checks for Padatious. See OCP Pipeline.
from ovos_utils.ocp import MediaType, PlaybackType
from ovos_workshop.decorators.ocp import ocp_search
from ovos_workshop.skills.common_play import OVOSCommonPlaybackSkill
PLAYLIST = [
{
"title": "Morning Briefing",
"uri": "file:///opt/office-media/morning-briefing.mp3",
"length": 180,
},
{
"title": "Lobby Loop",
"uri": "file:///opt/office-media/lobby-loop.mp3",
"length": 600,
},
]
class OfficePlaylistSkill(OVOSCommonPlaybackSkill):
def __init__(self, *args, **kwargs):
super().__init__(*args, supported_media=[MediaType.MUSIC], **kwargs)
self.skill_icon = "" # optional path/URI to an icon shown in OCP's UI
@ocp_search()
def search_office_playlist(self, phrase, media_type=MediaType.GENERIC):
# self.voc_match() lets a skill claim narrow phrases confidently;
# everything else gets a low, generic confidence
confident = self.voc_match(phrase, "office_playlist")
for track in PLAYLIST:
if confident or track["title"].lower() in phrase.lower():
yield {
"title": track["title"],
"uri": track["uri"],
"media_type": MediaType.MUSIC,
"playback": PlaybackType.AUDIO,
"match_confidence": 90 if confident else 40,
"length": track["length"],
}
locale/en-us/vocab/office_playlist.voc:
Moving parts¶
MediaTypeandPlaybackTypeare enums imported fromovos_utils.ocp. Results are plain dicts, not a dedicated result class. Mandatory keys areuri,title,media_type,playback,match_confidence(0-100), withartist,album,image,length(seconds) optional. Full field table: OCP Skills.@ocp_search()(imported fromovos_workshop.decorators.ocp) marks a method as a search provider. OCP queries every OCP skill in parallel across the bus (a single skill's own@ocp_searchmethods run sequentially) and keeps the best-confidence result across all installed OCP skills. A search method mayreturna list oryieldresults incrementally.supported_media(passed tosuper().__init__()) tells OCP whichMediaTypes this skill should even be asked about.self.voc_match(phrase, "office_playlist")reuses the same vocabulary mechanism as intents to give a confident match a high score, while still falling back to a loose substring check.- OCP Skills also documents
self.extend_timeout()(ask OCP to wait longer for a slow search). It notes that new integrations not needing the full skill lifecycle may prefer aMediaProviderplugin instead. See that page's opening warning.
Full production example (archived, source only)
ovos-skill-somafm is a full modern OCP skill: @ocp_search, @ocp_featured_media, register_ocp_keyword, and results built as Playlist/MediaEntry objects instead of plain dicts. ovos-skill-news applies the same pattern for MediaType.NEWS. Both repos are archived. Their MediaProvider plugin replacements are what a new deployment should install; see Music & Radio.
Read next: Skill Cookbook Related: OCP Skills · Converse-driven game loop · Common Query Framework