YouTube

Search: list

Returns a collection of search results that match the query parameters specified in the API request. By default, a search result set identifies matching video, channel, and playlist resources, but you can also configure queries to only retrieve a specific type of resource. Try it now or see an example.

Request

HTTP request

GET https://www.googleapis.com/youtube/v3/search

Parameters

The table below lists the parameters that this query supports. All of the parameters listed are query parameters.

Parameter name Value Description
Required parameters
part string The part parameter specifies a comma-separated list of one or more search resource properties that the API response will include. The part names that you can include in the parameter value are id and snippet.

If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a search result, the snippet property contains other properties that identify the result's title, description, and so forth. If you set part=snippet, the API response will also contain all of those nested properties.
Filters (specify 0 or 1 of the following parameters)
forContentOwner boolean This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.

The forContentOwner parameter restricts the search to only retrieve resources owned by the content owner specified by the onBehalfOfContentOwner parameter. The user must be authenticated using a CMS account linked to the specified content owner and onBehalfOfContentOwner must be provided.
forMine boolean This parameter can only be used in a properly authorized request. The forMine parameter restricts the search to only retrieve videos owned by the authenticated user. If you set this parameter to true, then the type parameter's value must also be set to video.
relatedToVideoId string The relatedToVideoId parameter retrieves a list of videos that are related to the video that the parameter value identifies. The parameter value must be set to a YouTube video ID and, if you are using this parameter, the type parameter must be set to video.
Optional parameters
channelId string The channelId parameter indicates that the API response should only contain resources created by the channel
channelType string The channelType parameter lets you restrict a search to a particular type of channel.

Acceptable values are:
  • any – Return all channels.
  • show – Only retrieve shows.
eventType string The eventType parameter restricts a search to broadcast events. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • completed – Only include completed broadcasts.
  • live – Only include active broadcasts.
  • upcoming – Only include upcoming broadcasts.
maxResults unsigned integer The maxResults parameter specifies the maximum number of items that should be returned in the result set. Acceptable values are 0 to 50, inclusive. The default value is 5.
onBehalfOfContentOwner string This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.

The onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.
order string The order parameter specifies the method that will be used to order resources in the API response. The default value is relevance.

Acceptable values are:
  • date – Resources are sorted in reverse chronological order based on the date they were created.
  • rating – Resources are sorted from highest to lowest rating.
  • relevance – Resources are sorted based on their relevance to the search query. This is the default value for this parameter.
  • title – Resources are sorted alphabetically by title.
  • videoCount – Channels are sorted in descending order of their number of uploaded videos.
  • viewCount – Resources are sorted from highest to lowest number of views.
pageToken string The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.
publishedAfter datetime The publishedAfter parameter indicates that the API response should only contain resources created after the specified time. The value is an RFC 3339 formatted date-time value (1970-01-01T00:00:00Z).
publishedBefore datetime The publishedBefore parameter indicates that the API response should only contain resources created before the specified time. The value is an RFC 3339 formatted date-time value (1970-01-01T00:00:00Z).
q string The q parameter specifies the query term to search for.
regionCode string The regionCode parameter instructs the API to return search results for the specified country. The parameter value is an ISO 3166-1 alpha-2 country code.
safeSearch string The safeSearch parameter indicates whether the search results should include restricted content as well as standard content.

Acceptable values are:
  • moderate – YouTube will filter some content from search results and, at the least, will filter content that is restricted in your locale. Based on their content, search results could be removed from search results or demoted in search results. This is the default parameter value.
  • none – YouTube will not filter the search result set.
  • strict – YouTube will try to exclude all restricted content from the search result set. Based on their content, search results could be removed from search results or demoted in search results.
topicId string The topicId parameter indicates that the API response should only contain resources associated with the specified topic. The value identifies a Freebase topic ID.
type string The type parameter restricts a search query to only retrieve a particular type of resource. The value is a comma-separated list of resource types. The default value is video,channel,playlist.

Acceptable values are:
  • channel
  • playlist
  • video
videoCaption string The videoCaption parameter indicates whether the API should filter video search results based on whether they have captions. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Do not filter results based on caption availability.
  • closedCaption – Only include videos that have captions.
  • none – Only include videos that do not have captions.
videoCategoryId string The videoCategoryId parameter filters video search results based on their category. If you specify a value for this parameter, you must also set the type parameter's value to video.
videoDefinition string The videoDefinition parameter lets you restrict a search to only include either high definition (HD) or standard definition (SD) videos. HD videos are available for playback in at least 720p, though higher resolutions, like 1080p, might also be available. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Return all videos, regardless of their resolution.
  • high – Only retrieve HD videos.
  • standard – Only retrieve videos in standard definition.
videoDimension string The videoDimension parameter lets you restrict a search to only retrieve 2D or 3D videos. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • 2d – Restrict search results to exclude 3D videos.
  • 3d – Restrict search results to only include 3D videos.
  • any – Include both 3D and non-3D videos in returned results. This is the default value.
videoDuration string The videoDuration parameter filters video search results based on their duration. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Do not filter video search results based on their duration. This is the default value.
  • long – Only include videos longer than 20 minutes.
  • medium – Only include videos that are between four and 20 minutes long (inclusive).
  • short – Only include videos that are less than four minutes long.
videoEmbeddable string The videoEmbeddable parameter lets you to restrict a search to only videos that can be embedded into a webpage. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Return all videos, embeddable or not.
  • true – Only retrieve embeddable videos.
videoLicense string The videoLicense parameter filters search results to only include videos with a particular license. YouTube lets video uploaders choose to attach either the Creative Commons license or the standard YouTube license to each of their videos. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Return all videos, regardless of which license they have, that match the query parameters.
  • creativeCommon – Only return videos that have a Creative Commons license. Users can reuse videos with this license in other videos that they create. Learn more.
  • youtube – Only return videos that have the standard YouTube license.
videoSyndicated string The videoSyndicated parameter lets you to restrict a search to only videos that can be played outside youtube.com. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Return all videos, syndicated or not.
  • true – Only retrieve syndicated videos.
videoType string The videoType parameter lets you restrict a search to a particular type of videos. If you specify a value for this parameter, you must also set the type parameter's value to video.

Acceptable values are:
  • any – Return all videos.
  • episode – Only retrieve episodes of shows.
  • movie – Only retrieve movies.

Request body

Do not provide a request body when calling this method.

Response

If successful, this method returns a response body with the following structure:

{
  "kind": "youtube#searchListResponse",
  "etag": etag,
  "nextPageToken": string,
  "prevPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    search Resource
  ]
}

Properties

The following table defines the properties that appear in a search result:

Property name Value Description
kind string Identifies the API resource's type. The value will be youtube#searchListResponse.
etag etag The Etag of this resource.
nextPageToken string The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set.
prevPageToken string The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set.
pageInfo object The pageInfo object encapsulates paging information for the result set.
pageInfo.totalResults integer The total number of results in the result set.
pageInfo.resultsPerPage integer The number of results included in the API response.
items[] list A list of results that match the search criteria.

Examples

Note: The code samples below may not represent all supported programming languages. See the client libraries documentation for a list of supported languages.

Apps Script #1

This function searches for videos related to the keyword 'dogs'. The video IDs and titles of the search results are logged to Apps Script's log.

Note that this sample limits the results to 25. To return more results, pass additional parameters as documented here: https://developers.google.com/youtube/v3/docs/search/list
/**
 * This function searches for videos related to the keyword 'dogs'. The video IDs and titles
 * of the search results are logged to Apps Script's log.
 *
 * Note that this sample limits the results to 25. To return more results, pass
 * additional parameters as documented here:
 *   https://developers.google.com/youtube/v3/docs/search/list
 */
function searchByKeyword() {
  var results = YouTube.Search.list('id,snippet', {q: 'dogs', maxResults: 25});
  for(var i in results.items) {
    var item = results.items[i];
    Logger.log('[%s] Title: %s', item.id.videoId, item.snippet.title);
  }
}

Apps Script #2

This function searches for videos that are associated with a particular Freebase topic, logging their video IDs and titles to the Apps Script log. This example uses the topic ID for Google Apps Script.

Note that this sample limits the results to 25. To return more results, pass additional parameters as documented here: https://developers.google.com/youtube/v3/docs/search/list
/**
 * This function searches for videos that are associated with a particular Freebase
 * topic, logging their video IDs and titles to the Apps Script log. This example uses
 * the topic ID for Google Apps Script.
 *
 * Note that this sample limits the results to 25. To return more results, pass
 * additional parameters as documented here:
 *   https://developers.google.com/youtube/v3/docs/search/list
 */
function searchByTopic() {
  var mid = '/m/0gjf126';
  var results = YouTube.Search.list('id,snippet', {topicId: mid, maxResults: 25});
  for(var i in results.items) {
    var item = results.items[i];
    Logger.log('[%s] Title: %s', item.id.videoId, item.snippet.title);
  }
}

Go #1

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

This example uses the Go client library.

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"

	"code.google.com/p/google-api-go-client/googleapi/transport"
	"code.google.com/p/google-api-go-client/youtube/v3"
)

var (
	query      = flag.String("query", "Google", "Search term")
	maxResults = flag.Int64("max-results", 25, "Max YouTube results")
)

const developerKey = "YOUR DEVELOPER KEY"

func main() {
	flag.Parse()

	client := &http.Client{
		Transport: &transport.APIKey{Key: developerKey},
	}

	service, err := youtube.New(client)
	if err != nil {
		log.Fatalf("Error creating new YouTube client: %v", err)
	}

	// Make the API call to YouTube.
	call := service.Search.List("id,snippet").
		Q(*query).
		MaxResults(*maxResults)
	response, err := call.Do()
	if err != nil {
		log.Fatalf("Error making search API call: %v", err)
	}

	// Group video, channel, and playlist results in separate lists.
	videos := make(map[string]string)
	channels := make(map[string]string)
	playlists := make(map[string]string)

	// Iterate through each item and add it to the correct list.
	for _, item := range response.Items {
		switch item.Id.Kind {
		case "youtube#video":
			videos[item.Id.VideoId] = item.Snippet.Title
		case "youtube#channel":
			channels[item.Id.ChannelId] = item.Snippet.Title
		case "youtube#playlist":
			playlists[item.Id.PlaylistId] = item.Snippet.Title
		}
	}

	printIDs("Videos", videos)
	printIDs("Channels", channels)
	printIDs("Playlists", playlists)
}

// Print the ID and title of each result in a list as well as a name that
// identifies the list. For example, print the word section name "Videos"
// above a list of video search results, followed by the video ID and title
// of each matching video.
func printIDs(sectionName string, matches map[string]string) {
	fmt.Printf("%v:\n", sectionName)
	for id, title := range matches {
		fmt.Printf("[%v] %v\n", id, title)
	}
	fmt.Printf("\n\n")
}

Go #2

The code sample below calls the API's search.list method to retrieve search results associated with a particular Freebase topic.

This example uses the Go client library.

package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"

	"code.google.com/p/google-api-go-client/googleapi/transport"
	"code.google.com/p/google-api-go-client/youtube/v3"
)

var (
	query      = flag.String("query", "Google", "Freebase search term")
	maxResults = flag.Int64("max-results", 25, "Max YouTube results")
	resultType = flag.String("type", "channel", "YouTube result type: video, playlist, or channel")
)

const developerKey = "YOUR DEVELOPER KEY HERE"
const freebaseSearchURL = "https://www.googleapis.com/freebase/v1/search?%s"

// Notable is struct for unmarshalling JSON values from the API.
type Notable struct {
	Name string
	ID   string
}

// FreebaseTopic is struct for unmarshalling JSON values from the API.
type FreebaseTopic struct {
	Mid     string
	ID      string
	Name    string
	Notable Notable
	Lang    string
	Score   float64
}

// FreebaseResponse is struct for unmarshalling JSON values from the Freebase API.
type FreebaseResponse struct {
	Status string
	Result []FreebaseTopic
}

func main() {
	flag.Parse()

	topicID, err := getTopicID(*query)
	if err != nil {
		log.Fatalf("Cannot fetch topic ID from Freebase: %v", err)
	}

	err = youtubeSearch(topicID)
	if err != nil {
		log.Fatalf("Cannot make YouTube API call: %v", err)
	}
}

// getTopicID queries Freebase with the given string. It then prompts the user
// to select a topic, then returns the selected topic so that the topic can be
// used to search YouTube for videos, channels or playlists.
func getTopicID(topic string) (string, error) {
	urlParams := url.Values{
		"query": []string{topic},
		"key":   []string{developerKey},
	}

	apiURL := fmt.Sprintf(freebaseSearchURL, urlParams.Encode())

	resp, err := http.Get(apiURL)
	if err != nil {
		return "", err
	} else if resp.StatusCode != http.StatusOK {
		errorMsg := fmt.Sprintf("Received HTTP status code %v using developer key: %v",
			resp.StatusCode, developerKey)
		return "", errors.New(errorMsg)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var data FreebaseResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		return "", nil
	}

	if len(data.Result) == 0 {
		return "", errors.New("No matching terms were found in Freebase.")
	}

	// Print a list of topics for the user to select.
	fmt.Println("The following topics were found:")
	for index, topic := range data.Result {
		if topic.Notable.Name == "" {
			topic.Notable.Name = "Unknown"
		}
		fmt.Printf("   %2d. %s (%s)\r\n", index+1, topic.Name, topic.Notable.Name)
	}

	prompt := fmt.Sprintf("Enter a topic number to find related YouTube %s [1-%v]: ",
		*resultType, len(data.Result))
	selection, err := readInt(prompt, 1, len(data.Result))
	if err != nil {
		return "", nil
	}
	choice := data.Result[selection-1]
	return choice.Mid, nil
}

// readInt reads an integer from standard input and verifies that the value
// is between the allowed min and max values (inclusive).
func readInt(prompt string, min int, max int) (int, error) {
	// Loop until we have a valid input.
	for {
		fmt.Print(prompt)
		var i int
		_, err := fmt.Fscan(os.Stdin, &i)
		if err != nil {
			return 0, err
		}
		if i < min || i > max {
			fmt.Println("Invalid input.")
			continue
		}
		return i, nil
	}
}

// youtubeSearch searches YouTube for the topic given in the query flag and
// prints the results. This function takes a mid parameter, which specifies
// a value retrieved using the Freebase API.
func youtubeSearch(mid string) error {
	client := &http.Client{
		Transport: &transport.APIKey{Key: developerKey},
	}

	service, err := youtube.New(client)
	if err != nil {
		return err
	}

	// Make the API call to YouTube.
	call := service.Search.List("id,snippet").
		TopicId(mid).
		Type(*resultType).
		MaxResults(*maxResults)
	response, err := call.Do()
	if err != nil {
		return err
	}

	// Iterate through each item and output it.
	for _, item := range response.Items {
		itemID := ""
		switch item.Id.Kind {
		case "youtube#video":
			itemID = item.Id.VideoId
		case "youtube#channel":
			itemID = item.Id.ChannelId
		case "youtube#playlist":
			itemID = item.Id.PlaylistId
		}
		fmt.Printf("%v (%v)\r\n", item.Snippet.Title, itemID)
	}
	return nil
}

Java #1

This example uses the Java client library.

/*
 * Copyright (c) 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.api.services.samples.youtube.cmdline.data;

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
 * Print a list of videos matching a search term.
 *
 * @author Jeremy Walker
 */
public class Search {

    /**
     * Define a global variable that identifies the name of a file that
     * contains the developer's API key.
     */
    private static final String PROPERTIES_FILENAME = "youtube.properties";

    private static final long NUMBER_OF_VIDEOS_RETURNED = 25;

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube;

    /**
     * Initialize a YouTube object to search for videos on YouTube. Then
     * display the name and thumbnail image of each video in the result set.
     *
     * @param args command line args.
     */
    public static void main(String[] args) {
        // Read the developer key from the properties file.
        Properties properties = new Properties();
        try {
            InputStream in = Search.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
            properties.load(in);

        } catch (IOException e) {
            System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
                    + " : " + e.getMessage());
            System.exit(1);
        }

        try {
            // This object is used to make YouTube Data API requests. The last
            // argument is required, but since we don't need anything
            // initialized when the HttpRequest is initialized, we override
            // the interface and provide a no-op function.
            youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
                public void initialize(HttpRequest request) throws IOException {
                }
            }).setApplicationName("youtube-cmdline-search-sample").build();

            // Prompt the user to enter a query term.
            String queryTerm = getInputQuery();

            // Define the API request for retrieving search results.
            YouTube.Search.List search = youtube.search().list("id,snippet");

            // Set your developer key from the Google Developers Console for
            // non-authenticated requests. See:
            // https://console.developers.google.com/
            String apiKey = properties.getProperty("youtube.apikey");
            search.setKey(apiKey);
            search.setQ(queryTerm);

            // Restrict the search results to only include videos. See:
            // https://developers.google.com/youtube/v3/docs/search/list#type
            search.setType("video");

            // To increase efficiency, only retrieve the fields that the
            // application uses.
            search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
            search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);

            // Call the API and print results.
            SearchListResponse searchResponse = search.execute();
            List<SearchResult> searchResultList = searchResponse.getItems();
            if (searchResultList != null) {
                prettyPrint(searchResultList.iterator(), queryTerm);
            }
        } catch (GoogleJsonResponseException e) {
            System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
                    + e.getDetails().getMessage());
        } catch (IOException e) {
            System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a query term and return the user-specified term.
     */
    private static String getInputQuery() throws IOException {

        String inputQuery = "";

        System.out.print("Please enter a search term: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        inputQuery = bReader.readLine();

        if (inputQuery.length() < 1) {
            // Use the string "YouTube Developers Live" as a default.
            inputQuery = "YouTube Developers Live";
        }
        return inputQuery;
    }

    /*
     * Prints out all results in the Iterator. For each result, print the
     * title, video ID, and thumbnail.
     *
     * @param iteratorSearchResults Iterator of SearchResults to print
     *
     * @param query Search query (String)
     */
    private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {

        System.out.println("\n=============================================================");
        System.out.println(
                "   First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\".");
        System.out.println("=============================================================\n");

        if (!iteratorSearchResults.hasNext()) {
            System.out.println(" There aren't any results for your query.");
        }

        while (iteratorSearchResults.hasNext()) {

            SearchResult singleVideo = iteratorSearchResults.next();
            ResourceId rId = singleVideo.getId();

            // Confirm that the result represents a video. Otherwise, the
            // item will not contain a video ID.
            if (rId.getKind().equals("youtube#video")) {
                Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();

                System.out.println(" Video Id" + rId.getVideoId());
                System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
                System.out.println(" Thumbnail: " + thumbnail.getUrl());
                System.out.println("\n-------------------------------------------------------------\n");
            }
        }
    }
}

Java #2

This example uses the Java client library.

/*
 * Copyright (c) 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.api.services.samples.youtube.cmdline.data;

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This application demonstrates a semantic YouTube search that prompts the
 * user to enter a search term and select a topic related to that term. The
 * class calls the Freebase API to get a topic ID, then passes that id along
 * with another user query term to the YouTube APIs. The result is a list of
 * videos based on a semantic search.
 *
 * @author Jeremy Walker
 */
public class Topics {

    /**
     * Define a global variable that identifies the name of a file that
     * contains the developer's API key.
     */
    private static final String PROPERTIES_FILENAME = "youtube.properties";

    /**
     * Define a global variable that specifies the maximum number of videos
     * that an API response can contain.
     */
    private static final long NUMBER_OF_VIDEOS_RETURNED = 5;

    /**
     * Define a global variable that specifies the maximum number of topics
     * that an API response can contain.
     */
    private static final long NUMBER_OF_TOPICS_RETURNED = 5;

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube;

    /**
     * Execute a search request that starts by calling the Freebase API to
     * retrieve a topic ID matching a user-provided term. Then initialize a
     * YouTube object to search for YouTube videos and call the YouTube Data
     * API's youtube.search.list method to retrieve a list of videos associated
     * with the selected Freebase topic and with another search query term,
     * which the user also enters. Finally, display the titles, video IDs, and
     * thumbnail images for the first five videos in the YouTube Data API
     * response.
     *
     * @param args This application does not use command line arguments.
     */
    public static void main(String[] args) {
        // Read the developer key from the properties file.
        Properties properties = new Properties();
        try {
            InputStream in = Topics.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
            properties.load(in);

        } catch (IOException e) {
            System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
                    + " : " + e.getMessage());
            System.exit(1);
        }


        try {
            // Retrieve a Freebase topic ID based on a user-entered query term.
            String topicsId = getTopicId();
            if (topicsId.length() < 1) {
                System.out.println("No topic id will be applied to your search.");
            }

            // Prompt the user to enter a search query term. This term will be
            // used to retrieve YouTube search results related to the topic
            // selected above.
            String queryTerm = getInputQuery("search");

            // This object is used to make YouTube Data API requests. The last
            // argument is required, but since we don't need anything
            // initialized when the HttpRequest is initialized, we override
            // the interface and provide a no-op function.
            youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
                public void initialize(HttpRequest request) throws IOException {
                }
            })
            .setApplicationName("youtube-cmdline-search-sample")
            .build();

            YouTube.Search.List search = youtube.search().list("id,snippet");

            // Set your developer key from the Google Developers Console for
            // non-authenticated requests. See:
            // https://console.developers.google.com/
            String apiKey = properties.getProperty("youtube.apikey");
            search.setKey(apiKey);
            search.setQ(queryTerm);
            if (topicsId.length() > 0) {
                search.setTopicId(topicsId);
            }

            // Restrict the search results to only include videos. See:
            // https://developers.google.com/youtube/v3/docs/search/list#type
            search.setType("video");

            // To increase efficiency, only retrieve the fields that the
            // application uses.
            search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
            search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
            SearchListResponse searchResponse = search.execute();

            List<SearchResult> searchResultList = searchResponse.getItems();

            if (searchResultList != null) {
                prettyPrint(searchResultList.iterator(), queryTerm, topicsId);
            } else {
                System.out.println("There were no results for your query.");
            }
        } catch (GoogleJsonResponseException e) {
            System.err.println("There was a service error: " + e.getDetails().getCode() +
                    " : " + e.getDetails().getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
            e.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a search term and return the user's input.
     *
     * @param searchCategory This value is displayed to the user to clarify the information that the application is requesting.
     */
    private static String getInputQuery(String searchCategory) throws IOException {

        String inputQuery = "";

        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));

        do {
            System.out.print("Please enter a " + searchCategory + " term: ");
            inputQuery = bReader.readLine();
        } while (inputQuery.length() < 1);

        return inputQuery;
    }

    /**
     * Retrieve Freebase topics that match a user-provided query term. Then
     * prompt the user to select a topic and return its topic ID.
     */
    private static String getTopicId() throws IOException {

        // The application will return an empty string if no matching topic ID
        // is found or no results are available.
        String topicsId = "";

        // Prompt the user to enter a query term for finding Freebase topics.
        String topicQuery = getInputQuery("topics");

        // The Freebase Java library does not provide search functionality, so
        // the application needs to call directly against the URL. This code
        // constructs the proper URL, then uses jackson classes to convert the
        // JSON response into a Java object. You can learn more about the
        // Freebase search calls at: http://wiki.freebase.com/wiki/ApiSearch.
        HttpClient httpclient = new DefaultHttpClient();
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("query", topicQuery));
        params.add(new BasicNameValuePair("limit", Long.toString(NUMBER_OF_TOPICS_RETURNED)));

        String serviceURL = "https://www.googleapis.com/freebase/v1/search";
        String url = serviceURL + "?" + URLEncodedUtils.format(params, "UTF-8");

        HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
        HttpEntity entity = httpResponse.getEntity();

        if (entity != null) {
            InputStream instream = entity.getContent();
            try {

                // Convert the JSON to an object. This code does not do an
                // exact map from JSON to POJO (Plain Old Java object), but
                // you could create additional classes and use them with the
                // mapper.readValue() function to get that exact mapping.
                ObjectMapper mapper = new ObjectMapper();
                JsonNode rootNode = mapper.readValue(instream, JsonNode.class);

                // Confirm that the HTTP request was handled successfully by
                // checking the API response's HTTP response code.
                if (rootNode.get("status").asText().equals("200 OK")) {
                    // In the API response, the "result" field contains the
                    // list of needed results.
                    ArrayNode arrayNodeResults = (ArrayNode) rootNode.get("result");
                    // Prompt the user to select a topic from the list of API
                    // results.
                    topicsId = getUserChoice(arrayNodeResults);
                }
            } finally {
                instream.close();
            }
        }
        return topicsId;
    }

    /**
     * Output results from the Freebase topic search to the user, prompt the
     * user to select a topic, and return the appropriate topic ID.
     *
     * @param freebaseResults ArrayNode This object contains the search results.
     */
    private static String getUserChoice(ArrayNode freebaseResults) throws IOException {

        String freebaseId = "";

        if (freebaseResults.size() < 1) {
            return freebaseId;
        }

        // Print a list of topics retrieved from Freebase.
        for (int i = 0; i < freebaseResults.size(); i++) {
            JsonNode node = freebaseResults.get(i);
            System.out.print(" " + i + " = " + node.get("name").asText());
            if (node.get("notable") != null) {
                System.out.print(" (" + node.get("notable").get("name").asText() + ")");
            }
            System.out.println("");
        }

        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        String inputChoice;

        // Prompt the user to select a topic.
        do {
            System.out.print("Choose the number of the Freebase Node: ");
            inputChoice = bReader.readLine();
        } while (!isValidIntegerSelection(inputChoice, freebaseResults.size()));

        // Return the topic ID needed for the API request that retrieves
        // YouTube search results.
        JsonNode node = freebaseResults.get(Integer.parseInt(inputChoice));
        freebaseId = node.get("mid").asText();
        return freebaseId;
    }

    /**
     * Confirm that the string represents a valid, positive integer, that is
     * less than or equal to 999,999,999. (Since the API will not return a
     * billion results for a query, any integer that the user enters will need
     * to be less than that to be valid, anyway.)
     *
     * @param input The string to test.
     * @param max   The integer must be less then this maximum number.
     */
    public static boolean isValidIntegerSelection(String input, int max) {
        if (input.length() > 9)
            return false;

        boolean validNumber = false;
        // Only accept positive numbers with a maximum of nine digits.
        Pattern intsOnly = Pattern.compile("^\\d{1,9}$");
        Matcher makeMatch = intsOnly.matcher(input);

        if (makeMatch.find()) {
            int number = Integer.parseInt(makeMatch.group());
            if ((number >= 0) && (number < max)) {
                validNumber = true;
            }
        }
        return validNumber;
    }

    /*
     * Prints out all results in the Iterator. For each result, print the
     * title, video ID, and thumbnail.
     *
     * @param iteratorSearchResults Iterator of SearchResults to print
     * @param query Search query (String)
     */
    private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query, String topicsId) {

        System.out.println("\n=============================================================");
        System.out.println("   First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\" with Topics id: " + topicsId + ".");
        System.out.println("=============================================================\n");

        if (!iteratorSearchResults.hasNext()) {
            System.out.println(" There aren't any results for your query.");
        }

        while (iteratorSearchResults.hasNext()) {

            SearchResult singleVideo = iteratorSearchResults.next();
            ResourceId rId = singleVideo.getId();

            // Confirm that the result represents a video. Otherwise, the
            // item will not contain a video ID.
            if (rId.getKind().equals("youtube#video")) {
                Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();

                System.out.println(" Video Id" + rId.getVideoId());
                System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
                System.out.println(" Thumbnail: " + thumbnail.getUrl());
                System.out.println("\n-------------------------------------------------------------\n");
            }
        }
    }
}

JavaScript

The JavaScript code below executes a YouTube search for the specified query term and then populates a DOM element with the API response. Again, you need to update the client ID in the auth.js file to run this code.

This example uses the JavaScript client library.

// After the API loads, call a function to enable the search box.
function handleAPILoaded() {
  $('#search-button').attr('disabled', false);
}

// Search for a specified string.
function search() {
  var q = $('#query').val();
  var request = gapi.client.youtube.search.list({
    q: q,
    part: 'snippet'
  });

  request.execute(function(response) {
    var str = JSON.stringify(response.result);
    $('#search-container').html('<pre>' + str + '</pre>');
  });
}

.NET

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

This example uses the .NET client library.

/*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;

namespace Google.Apis.YouTube.Samples
{
  /// <summary>
  /// YouTube Data API v3 sample: search by keyword.
  /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
  /// See https://code.google.com/p/google-api-dotnet-client/wiki/GettingStarted
  ///
  /// Set ApiKey to the API key value from the APIs & auth > Registered apps tab of
  ///   https://cloud.google.com/console
  /// Please ensure that you have enabled the YouTube Data API for your project.
  /// </summary>
  internal class Search
  {
    [STAThread]
    static void Main(string[] args)
    {
      Console.WriteLine("YouTube Data API: Search");
      Console.WriteLine("========================");

      try
      {
        new Search().Run().Wait();
      }
      catch (AggregateException ex)
      {
        foreach (var e in ex.InnerExceptions)
        {
          Console.WriteLine("Error: " + e.Message);
        }
      }

      Console.WriteLine("Press any key to continue...");
      Console.ReadKey();
    }

    private async Task Run()
    {
      var youtubeService = new YouTubeService(new BaseClientService.Initializer()
      {
        ApiKey = "REPLACE_ME",
        ApplicationName = this.GetType().ToString()
      });

      var searchListRequest = youtubeService.Search.List("snippet");
      searchListRequest.Q = "Google"; // Replace with your search term.
      searchListRequest.MaxResults = 50;

      // Call the search.list method to retrieve results matching the specified query term.
      var searchListResponse = await searchListRequest.ExecuteAsync();

      List<string> videos = new List<string>();
      List<string> channels = new List<string>();
      List<string> playlists = new List<string>();

      // Add each result to the appropriate list, and then display the lists of
      // matching videos, channels, and playlists.
      foreach (var searchResult in searchListResponse.Items)
      {
        switch (searchResult.Id.Kind)
        {
          case "youtube#video":
            videos.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.VideoId));
            break;

          case "youtube#channel":
            channels.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.ChannelId));
            break;

          case "youtube#playlist":
            playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.PlaylistId));
            break;
        }
      }

      Console.WriteLine(String.Format("Videos:\n{0}\n", string.Join("\n", videos)));
      Console.WriteLine(String.Format("Channels:\n{0}\n", string.Join("\n", channels)));
      Console.WriteLine(String.Format("Playlists:\n{0}\n", string.Join("\n", playlists)));
    }
  }
}

PHP

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

This example uses the PHP client library.

<?php

$htmlBody = <<<END
<form method="GET">
  <div>
    Search Term: <input type="search" id="q" name="q" placeholder="Enter Search Term">
  </div>
  <div>
    Max Results: <input type="number" id="maxResults" name="maxResults" min="1" max="50" step="1" value="25">
  </div>
  <input type="submit" value="Search">
</form>
END;

// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
if ($_GET['q'] && $_GET['maxResults']) {
  // Call set_include_path() as needed to point to your client library.
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';

  /*
   * Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
   * Google Developers Console <https://console.developers.google.com/>
   * Please ensure that you have enabled the YouTube Data API for your project.
   */
  $DEVELOPER_KEY = 'REPLACE_ME';

  $client = new Google_Client();
  $client->setDeveloperKey($DEVELOPER_KEY);

  // Define an object that will be used to make all API requests.
  $youtube = new Google_Service_YouTube($client);

  try {
    // Call the search.list method to retrieve results matching the specified
    // query term.
    $searchResponse = $youtube->search->listSearch('id,snippet', array(
      'q' => $_GET['q'],
      'maxResults' => $_GET['maxResults'],
    ));

    $videos = '';
    $channels = '';
    $playlists = '';

    // Add each result to the appropriate list, and then display the lists of
    // matching videos, channels, and playlists.
    foreach ($searchResponse['items'] as $searchResult) {
      switch ($searchResult['id']['kind']) {
        case 'youtube#video':
          $videos .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['videoId']);
          break;
        case 'youtube#channel':
          $channels .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['channelId']);
          break;
        case 'youtube#playlist':
          $playlists .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['playlistId']);
          break;
      }
    }

    $htmlBody .= <<<END
    <h3>Videos</h3>
    <ul>$videos</ul>
    <h3>Channels</h3>
    <ul>$channels</ul>
    <h3>Playlists</h3>
    <ul>$playlists</ul>
END;
  } catch (Google_ServiceException $e) {
    $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  } catch (Google_Exception $e) {
    $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  }
}
?>

<!doctype html>
<html>
  <head>
    <title>YouTube Search</title>
  </head>
  <body>
    <?=$htmlBody?>
  </body>
</html>

Python #1

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

This example uses the Python client library.

#!/usr/bin/python

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser


# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
#   https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

def youtube_search(options):
  youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
    developerKey=DEVELOPER_KEY)

  # Call the search.list method to retrieve results matching the specified
  # query term.
  search_response = youtube.search().list(
    q=options.q,
    part="id,snippet",
    maxResults=options.max_results
  ).execute()

  videos = []
  channels = []
  playlists = []

  # Add each result to the appropriate list, and then display the lists of
  # matching videos, channels, and playlists.
  for search_result in search_response.get("items", []):
    if search_result["id"]["kind"] == "youtube#video":
      videos.append("%s (%s)" % (search_result["snippet"]["title"],
                                 search_result["id"]["videoId"]))
    elif search_result["id"]["kind"] == "youtube#channel":
      channels.append("%s (%s)" % (search_result["snippet"]["title"],
                                   search_result["id"]["channelId"]))
    elif search_result["id"]["kind"] == "youtube#playlist":
      playlists.append("%s (%s)" % (search_result["snippet"]["title"],
                                    search_result["id"]["playlistId"]))

  print "Videos:\n", "\n".join(videos), "\n"
  print "Channels:\n", "\n".join(channels), "\n"
  print "Playlists:\n", "\n".join(playlists), "\n"


if __name__ == "__main__":
  argparser.add_argument("--q", help="Search term", default="Google")
  argparser.add_argument("--max-results", help="Max results", default=25)
  args = argparser.parse_args()

  try:
    youtube_search(args)
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)

Python #2

The code sample below calls the API's search.list method to retrieve search results associated with a particular Freebase topic.

This example uses the Python client library.

#!/usr/bin/python

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser

import json
import urllib


# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
#   https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
FREEBASE_SEARCH_URL = "https://www.googleapis.com/freebase/v1/search?%s"

def get_topic_id(options):
  # Retrieve a list of Freebase topics associated with the provided query term.
  freebase_params = dict(query=options.query, key=DEVELOPER_KEY)
  freebase_url = FREEBASE_SEARCH_URL % urllib.urlencode(freebase_params)
  freebase_response = json.loads(urllib.urlopen(freebase_url).read())

  if len(freebase_response["result"]) == 0:
    exit("No matching terms were found in Freebase.")

  # Display the list of matching Freebase topics.
  mids = []
  index = 1
  print "The following topics were found:"
  for result in freebase_response["result"]:
    mids.append(result["mid"])
    print "  %2d. %s (%s)" % (index, result.get("name", "Unknown"),
      result.get("notable", {}).get("name", "Unknown"))
    index += 1

  # Display a prompt for the user to select a topic and return the topic ID
  # of the selected topic.
  mid = None
  while mid is None:
    index = raw_input("Enter a topic number to find related YouTube %ss: " %
      options.type)
    try:
      mid = mids[int(index) - 1]
    except ValueError:
      pass
  return mid


def youtube_search(mid, options):
  youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
  developerKey=DEVELOPER_KEY)

  # Call the search.list method to retrieve results associated with the
  # specified Freebase topic.
  search_response = youtube.search().list(
    topicId=mid,
    type=options.type,
    part="id,snippet",
    maxResults=options.max_results
  ).execute()

  # Print the title and ID of each matching resource.
  for search_result in search_response.get("items", []):
    if search_result["id"]["kind"] == "youtube#video":
      print "%s (%s)" % (search_result["snippet"]["title"],
        search_result["id"]["videoId"])
    elif search_result["id"]["kind"] == "youtube#channel":
      print "%s (%s)" % (search_result["snippet"]["title"],
        search_result["id"]["channelId"])
    elif search_result["id"]["kind"] == "youtube#playlist":
      print "%s (%s)" % (search_result["snippet"]["title"],
        search_result["id"]["playlistId"])


if __name__ == "__main__":
  argparser.add_argument("--query", help="Freebase search term", default="Google")
  argparser.add_argument("--max-results", help="Max YouTube results",
    default=25)
  argparser.add_argument("--type",
    help="YouTube result type: video, playlist, or channel", default="channel")
  args = argparser.parse_args()

  mid = get_topic_id(args)
  try:
    youtube_search(mid, args)
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)

Python App Engine #1

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

import os
import urllib
import webapp2
import jinja2

from apiclient.discovery import build
from optparse import OptionParser

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'])

# Set DEVELOPER_KEY to the "API key" value from the "Access" tab of the
# Google APIs Console http://code.google.com/apis/console#access
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

class MainHandler(webapp2.RequestHandler):
   
   def get(self):
        if DEVELOPER_KEY == "REPLACE_ME":
          self.response.write("""You must set up a project and get an API key
                                 to run this project.  Please visit 
				 <landing page> to do so."""
        else:
          youtube = build(
            YOUTUBE_API_SERVICE_NAME, 
            YOUTUBE_API_VERSION, 
            developerKey=DEVELOPER_KEY)
          search_response = youtube.search().list(
            q="Hello",
            part="id,snippet",
            maxResults=5
          ).execute()
        
          videos = []
          channels = []
          playlists = []
        
          for search_result in search_response.get("items", []):
            if search_result["id"]["kind"] == "youtube#video":
                videos.append("%s (%s)" % (search_result["snippet"]["title"], 
                  search_result["id"]["videoId"]))
            elif search_result["id"]["kind"] == "youtube#channel":
                channels.append("%s (%s)" % (search_result["snippet"]["title"], 
                  search_result["id"]["channelId"]))
            elif search_result["id"]["kind"] == "youtube#playlist":
                playlists.append("%s (%s)" % (search_result["snippet"]["title"], 
                  search_result["id"]["playlistId"]))
        
          template_values = {
           'videos': videos,
           'channels': channels,
           'playlists': playlists
          }
       
	  self.response.headers['Content-type'] = 'text/plain' 
          template = JINJA_ENVIRONMENT.get_template('index.html')
          self.response.write(template.render(template_values))
        
app = webapp2.WSGIApplication([
  ('/.*', MainHandler),
], debug=True)

Python App Engine #2

The code sample below calls the API's search.list method to retrieve search results associated with a particular Freebase topic.

import os
import urllib
import webapp2
import jinja2

from apiclient.discovery import build
from optparse import OptionParser

import json

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'])

REGISTRATION_INSTRUCTIONS = """
    You must set up a project and get an API key to run this code. Please see
    the instructions for creating a project and a key at <a
    href="https://developers.google.com/youtube/registering_an_application"
    >https://developers.google.com/youtube/registering_an_application</a>.
    <br><br>
    Make sure that you have enabled the YouTube Data API (v3) and the Freebase
    API for your project."""

# Set API_KEY to the "API key" value from the "Access" tab of the
# Google APIs Console http://code.google.com/apis/console#access
# Please ensure that you have enabled the YouTube Data API and Freebase API
# for your project.
API_KEY = "REPLACE_ME"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
FREEBASE_SEARCH_URL = "https://www.googleapis.com/freebase/v1/search?%s"
QUERY_TERM = "dog"

class MainHandler(webapp2.RequestHandler):

  def get(self):
    if API_KEY == 'REPLACE_ME':
      self.response.write(REGISTRATION_INSTRUCTIONS)
    else:
      # Present a list of Freebase topic IDs for the query term
      self.list_topics(QUERY_TERM)

  def list_topics(self, QUERY_TERM):
    # Retrieve a list of Freebase topics associated with the query term
    freebase_params = dict(query=QUERY_TERM, key=API_KEY)
    freebase_url = FREEBASE_SEARCH_URL % urllib.urlencode(freebase_params)
    freebase_response = json.loads(urllib.urlopen(freebase_url).read())

    if len(freebase_response["result"]) == 0:
      exit("No matching terms were found in Freebase.")

    # Create a page that shows a select box listing the topics.
    # When the user selects a topic and submits the form, the
    # 'post' method below will handle the form submission and
    # retrieve videos for the selected topic.
    select_topic_page = ('''
        <html>
          <body>
            <p>The following topics were found:</p>
            <form method="post">
              <select name="topic">
    ''')
    for result in freebase_response["result"]:
      select_topic_page += ('<option value="' + result["mid"] + '">' +
                            result.get("name", "Unknown") + '</option>')

    select_topic_page += '''
              </select>
              <p><input type="submit" /></p>
            </form>
          </body>
        </html>
    '''

    # Display the HTML page listing the topic choices.
    self.response.out.write(select_topic_page)

  def post(self):
    topic_id = self.request.get('topic')

    # Service for calling the YouTube API
    youtube = build(YOUTUBE_API_SERVICE_NAME,
                    YOUTUBE_API_VERSION,
                    developerKey=API_KEY)

    # Execute the search request using default query term and retrieved topic.
    search_response = youtube.search().list(
      part = 'id,snippet',
      type = 'video',
      topicId = topic_id
    ).execute()

    videos = []

    for search_result in search_response.get("items", []):
      videos.append(search_result)

    template_values = {
      'videos': videos
    }

    self.response.headers['Content-type'] = 'text/html'
    template = JINJA_ENVIRONMENT.get_template('index.html')
    self.response.write(template.render(template_values))

app = webapp2.WSGIApplication([
  ('/.*', MainHandler),
], debug=True)

Ruby

The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.

This example uses the Ruby client library.

#!/usr/bin/ruby

require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'trollop'

# Set DEVELOPER_KEY to the API key value from the APIs & auth > Credentials
# tab of
# Google Developers Console <https://console.developers.google.com/>
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = 'REPLACE_ME'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'

def get_service
  client = Google::APIClient.new(
    :key => DEVELOPER_KEY,
    :authorization => nil,
    :application_name => $PROGRAM_NAME,
    :application_version => '1.0.0'
  )
  youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)

  return client, youtube
end

def main
  opts = Trollop::options do
    opt :q, 'Search term', :type => String, :default => 'Google'
    opt :max_results, 'Max results', :type => :int, :default => 25
  end

  client, youtube = get_service

  begin
    # Call the search.list method to retrieve results matching the specified
    # query term.
    search_response = client.execute!(
      :api_method => youtube.search.list,
      :parameters => {
        :part => 'snippet',
        :q => opts[:q],
        :maxResults => opts[:max_results]
      }
    )

    videos = []
    channels = []
    playlists = []

    # Add each result to the appropriate list, and then display the lists of
    # matching videos, channels, and playlists.
    search_response.data.items.each do |search_result|
      case search_result.id.kind
        when 'youtube#video'
          videos << "#{search_result.snippet.title} (#{search_result.id.videoId})"
        when 'youtube#channel'
          channels << "#{search_result.snippet.title} (#{search_result.id.channelId})"
        when 'youtube#playlist'
          playlists << "#{search_result.snippet.title} (#{search_result.id.playlistId})"
      end
    end

    puts "Videos:\n", videos, "\n"
    puts "Channels:\n", channels, "\n"
    puts "Playlists:\n", playlists, "\n"
  rescue Google::APIClient::TransmissionError => e
    puts e.result.body
  end
end

main

Errors

The table below identifies error messages that the API could return in response to a call to this method. Please see the error message documentation for more detail.

Error type Error detail Description
badRequest (400) invalidSearchFilter The request contains an invalid combination of search filters and/or restrictions. Note that you must set the type parameter to video if you set a value for the eventType, videoCaption, videoCategoryId, videoDefinition, videoDimension, videoDuration, videoEmbeddable, videoLicense, videoSyndicated, or videoType parameters.
badRequest (400) invalidVideoId The relatedToVideo parameter specified an invalid video ID.

Try it!

Use the API Explorer to call this method on live data and see the API request and response.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.