Play from youtube skill

So I’m guessing this never got fixed?

As far as I can tell there isn’t currently a functional YouTube skill.

There are a few out in the wild, but none that have been officially reviewed so not in the Marketplace at the moment.

I haven’t tried any of these myself nor looked at the code, so can’t vouch for them, but if you are happy to install from untested Skills, the best bet is probably:

and for desktop users wanting to actually watch the video:

We also have a brand new one coming that uses our new GUI Framework. So that will work for the Mark II and Plasma users:

I’m trying to get YouTube working on a headless Picroft and as far as I can tell not one of those works.

I imagine it should be fairly straightforward to output a video stream to ffmpeg and have it transcode or otherwise strip out just the audio. Admittedly that does mean I need to learn how Python classes work!

1 Like

I put together a skill to play audio from youtube:

Feedback welcome in that thread or on gitlab.

2 Likes

Just looking for a skill doing EXACTLY this.

It works great so far.

1 Like

Hey guys,

do you have some issue with youtube skills to recently ? Can’t load music since 2 days, it’s telling me that no result have been found , maybe youtube update something ?

I am having a similar issue with my Kodi-skill, it is no longer returning youtube links either so something has changed.

Acutally trying to debug it (lol first time I’m seeing python script). It seem that if you change skill to load only one music it’s working. So I think that the issue is with youtube-dl who can scrap youtube video because maybe youtube has made some changes

Looks like the playlist ID is formatted differently. The regex is failing in my kodi-skill.
These no longer work for me…

all_video_links = re.findall(r'href=\"\/watch\?v=(.{11})', html.decode())
all_playlist_results = re.findall(r'href=\"\/playlist\?list\=(.{34})', html.decode())

These do work…

all_video_links = re.findall(r'/watch\?v=(.{11})', html.decode())
all_playlist_results = re.findall(r'list\=(.{18})', html.decode())

Not sure this is any help to anyone but me but thought I would put it out there. I am going to dig in when I get some time.

I tried to download Jarbais plugin but the github seem no longer maintained, do you have a fork ?

Anyone having any luck with youtube… having same issue with youtube skill stopped working few days ago … saying “no results found”

1 Like

Same issue here. Was using Mcdruid plugin and since few days it’s ‘no result found’ :confused:

There are several youtube skills scattered throughout the community. What skill(s) are having issues. From my own testing it looks like the regex is failing on most of these due to a change in youtube. I have seen a similar issue with my Kodi-skill that I am correcting.
image
@mcdruid may be able to assist with their skill.

1 Like

this is what i found in @mcdruid yoiutube skill

for vid in vids:
if not re.match(’/watch?v=\w{11}’, vid[‘href’]):
LOG.debug('no media: ’ + vid[‘href’])
continue

the whole section

Attempt to find the first result matching the query string

def search_youtube(self, search_term):
    tracklist = []
    res = requests.get(search_url + search_term)
    # TODO: check status code etc...
    html = res.content
    soup = BeautifulSoup(html, 'html.parser')
    vids = soup.findAll(attrs={'class':'yt-uix-tile-link'})

    for vid in vids:
        if not re.match('/watch\?v=\w{11}', vid['href']):
          LOG.debug('no media: ' + vid['href'])
          continue

        self.vid_url = vid['href']
        self.vid_name = vid.string
        self.stream_url = self.get_stream_url(self.vid_url)
        LOG.debug('Found stream URL: ' + self.vid_url)
        LOG.debug('Media title: ' + self.vid_name)
        tracklist.append(self.stream_url)
        self.mediaplayer.add_list(tracklist)
        self.audio_state = 'playing'
        self.speak_dialog('now.playing', {'content': self.vid_name} )
        wait_while_speaking()
        self.mediaplayer.play()
        return

my bots arnt singing to me while i work on them…lol…

issue is with this line…

vids = soup.findAll(attrs={'class':'yt-uix-tile-link'})

This class no longer exists.

@mcdruid has been MIA for a bit. Not sure if he will respond or not. If I get adventurous maybe I will see if I can get his skill working. I have an idea what needs to be done.
image

It looks like youtube have completely changed the way they’re returning results.

Searching the HTML for the yt-uix-tile-link class doesn’t look like it’s going to work any more.

As far as I can see, they may now be returning a chunk of json which is rendered client side.

So we may need to look at parsing that instead.

Or, perhaps you can send a different User Agent and get plain HTML back… not sure.

Parsing the json is probably a better approach anyway.

I’ll have a look at this but don’t have a lot of time to work on it at the moment.

Pull Requests welcome at https://gitlab.com/mcdruid/mycroft-youtube-audio :slight_smile:

@mcdruid, Glad to see you are still active, I don’t have a gitlab account but have been doing a bit of playing around. There may be an issue with yt-downloader too but I am unsure since I think i have maxed out my google quota with testing :wink: I have been playing with your code and changed your search_youtube routine to this code and it seams to return valid results.


    def search_youtube(self, search_term):
        tracklist = []
        res = requests.get(search_url + search_term)
        # TODO: check status code etc...
        html = res.content
        soup = BeautifulSoup(html, 'html.parser')
        all_vid_id = re.findall(r'/watch\?v=(.{11})', str(soup))
        if len(all_vid_id) >= 1:
            for vid_id in all_vid_id:
                vid_url = "/watch?v=" + str(vid_id)
                self.stream_url = self.get_stream_url(vid_url)
                LOG.debug('Found stream URL: ' + self.stream_url)
                tracklist.append(self.stream_url)
            LOG.info(str(tracklist))
            self.mediaplayer.add_list(tracklist)
            vid_name = str(search_term)
            self.audio_state = 'playing'
            self.speak_dialog('now.playing', {'content': vid_name})
            wait_while_speaking()
            self.mediaplayer.play()
            return
        else:
            # We didn't find any playable results
            self.speak_dialog('not.found')
            wait_while_speaking()
            LOG.debug('Could not find any results with the query term: ' + search_term)