You are currently viewing Youtube search as a Console Service Endpoint in SUSI.AI

Youtube search as a Console Service Endpoint in SUSI.AI

SUSI.AI now has the ability to search and play any song or video directly in the webclient and the speaker. When a user asks for a query regarding playing a song, the clients sends a search request to the server. In this post I will discuss about the server side implementation of the Youtube search. Every time a request is made by any client, the client sends a query request to the server in the form of a json object. For more on the working on the webclient side can be seen here.

The endpoint for youtube search is  http://api.susi.ai/susi/console.json and an example query for this can be as shown below:

http: //api.susi.ai/susi/console.json?q=SELECT * FROM youtube WHERE query='tschunk'%

 

This endpoint case is handled by the ConsoleService.java file on susi server here. The codeblock given below from ConsoleService.java is responsible for our youtube service.

dbAccess.put(Pattern.compile("SELECT +?(.*?) +?FROM +?youtube +?WHERE +?query ??= ??'(.*?)' ??;"), (flow, matcher) - > {

  SusiThought json = new SusiThought();

  Pattern videoPattern = Pattern.compile("\"/watch\\?v=.*? aria-describedby");

  Pattern keyPattern = Pattern.compile("\"/watch\\?v=(.*?)\"");

  Pattern titlePattern = Pattern.compile("title=\"(.*?)\"");

  try {

    String query = matcher.group(2);

    String serviceURL = "https://www.youtube.com/results?search_query=" + query;


    String s = new String(HttpClient.load(serviceURL), "UTF-8");

    JSONArray a = new JSONArray();

    //System.out.println(s);

    Matcher m = videoPattern.matcher(s);

    while (m.find()) {

      String fragment = m.group(0);

      Matcher keyMatcher = keyPattern.matcher(fragment);

      JSONObject j = null;

      if (keyMatcher.find()) {

        String key = keyMatcher.group(1);

        if (key.indexOf('&') < 0) {

          Matcher titleMatcher = titlePattern.matcher(fragment);

          if (titleMatcher.find()) {

            String title = titleMatcher.group(1);

            j = new JSONObject(true);

            j.put("title", title);

            j.put("youtube", key);

          }

        }

      }

      if (j != null) a.put(j);

    }

    json.setQuery(query);

    json.setData(a);

  } catch (Throwable e) {

    e.printStackTrace();

    // probably a time-out or a json error

  }

  return json;

});

 

From this code we can see that whenever a call is made at the above endpoint the above code is executed. First of all the query parameter is extracted from the url, which contains the value of the search term which will be search on youtube. Then three pattern variable are defined namely videoPattern, keyPattern and titlePattern. These are java pattern objects which are used to compile and search for a particular pattern in the file. More on java pattern and matcher can be read here. Lets try to understand each one of them.

Video Pattern

Pattern videoPattern = Pattern.compile("\"/watch\\?v=.*? aria-describedby");

 

This pattern is used to search for all sections with the aria-describedby . The aria-describedby attribute is used to indicate the IDs of the elements that describe the object. More on aria-describedby can be found here.

Key Pattern

Pattern keyPattern = Pattern.compile("\"/watch\\?v=(.*?)\"");

 

This pattern is used to search for all links with the search term ‘watch’ and extract the video ID of each video from the search result. This video ID is unique for every video and its corresponding video can be played directly with this syntax url below:

https: //www.youtube.com/watch?v=<video id here>

 

Title Pattern

Pattern keyPattern = Pattern.compile("\"/watch\\?v=(.*?)\"");

 

This pattern is used to search for all links with the term ‘title’ which contains the title of the video.

Resources

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.