54 |
55 | ```
56 | # Retrieve playlists for a specified channel
57 | go run playlists.go oauth.go errors.go --channelId=UC_x5XG1OV2P6uZZ5FSM9Ttw
58 |
59 | # Retrieve authenticated user's playlists
60 | go run playlists.go oauth.go errors.go --mine=true
61 | ```
62 |
63 | ### [Retrieve my uploads](/go/my_uploads.go)
64 |
65 | Methods: youtube.channels.list, youtube.playlistItems.list
66 | Description: This code sample calls the API's playlistItems.list method to retrieve a list of
67 | videos uploaded to the channel associated with the request. The code also calls the channels.list
68 | method with the mine parameter set to true to retrieve the playlist ID that identifies
69 | the channel's uploaded videos.
70 |
71 | ### [Search by keyword](/go/search_by_keyword.go)
72 |
73 | Method: youtube.search.list
74 | Description: This code sample calls the API's search.list method to retrieve search results associated
75 | with a particular keyword.
76 |
77 | ### [Upload a video](/go/upload_video.go)
78 |
79 | Method: youtube.videos.insert
80 | Description: This code sample calls the API's videos.insert method to upload a video to the channel
81 | associated with the request.
82 |
--------------------------------------------------------------------------------
/go/client_secrets.json.sample:
--------------------------------------------------------------------------------
1 | {
2 | "installed": {
3 | "client_id": "YOUR_CLIENT_ID_HERE",
4 | "client_secret": "YOUR_CLIENT_SECRET_HERE",
5 | "redirect_uris": ["http://localhost:8080/oauth2callback"],
6 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
7 | "token_uri": "https://accounts.google.com/o/oauth2/token"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/go/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | )
6 |
7 | func handleError(err error, message string) {
8 | if message == "" {
9 | message = "Error making API call"
10 | }
11 | if err != nil {
12 | log.Fatalf(message + ": %v", err.Error())
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/go/my_uploads.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 |
7 | "google.golang.org/api/youtube/v3"
8 | )
9 |
10 | // Retrieve playlistItems in the specified playlist
11 | func playlistItemsList(service *youtube.Service, part string, playlistId string, pageToken string) *youtube.PlaylistItemListResponse {
12 | call := service.PlaylistItems.List(part)
13 | call = call.PlaylistId(playlistId)
14 | if pageToken != "" {
15 | call = call.PageToken(pageToken)
16 | }
17 | response, err := call.Do()
18 | handleError(err, "")
19 | return response
20 | }
21 |
22 | // Retrieve resource for the authenticated user's channel
23 | func channelsListMine(service *youtube.Service, part string) *youtube.ChannelListResponse {
24 | call := service.Channels.List(part)
25 | call = call.Mine(true)
26 | response, err := call.Do()
27 | handleError(err, "")
28 | return response
29 | }
30 |
31 | func main() {
32 | client := getClient(youtube.YoutubeReadonlyScope)
33 | service, err := youtube.New(client)
34 |
35 | if err != nil {
36 | log.Fatalf("Error creating YouTube client: %v", err)
37 | }
38 |
39 | response := channelsListMine(service, "contentDetails")
40 |
41 | for _, channel := range response.Items {
42 | playlistId := channel.ContentDetails.RelatedPlaylists.Uploads
43 |
44 | // Print the playlist ID for the list of uploaded videos.
45 | fmt.Printf("Videos in list %s\r\n", playlistId)
46 |
47 | nextPageToken := ""
48 | for {
49 | // Retrieve next set of items in the playlist.
50 | playlistResponse := playlistItemsList(service, "snippet", playlistId, nextPageToken)
51 |
52 | for _, playlistItem := range playlistResponse.Items {
53 | title := playlistItem.Snippet.Title
54 | videoId := playlistItem.Snippet.ResourceId.VideoId
55 | fmt.Printf("%v, (%v)\r\n", title, videoId)
56 | }
57 |
58 | // Set the token to retrieve the next page of results
59 | // or exit the loop if all results have been retrieved.
60 | nextPageToken = playlistResponse.NextPageToken
61 | if nextPageToken == "" {
62 | break
63 | }
64 | fmt.Println()
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/go/playlists.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "log"
7 |
8 | "google.golang.org/api/youtube/v3"
9 | )
10 |
11 | var (
12 | method = flag.String("method", "list", "The API method to execute. (List is the only method that this sample currently supports.")
13 |
14 | channelId = flag.String("channelId", "", "Retrieve playlists for this channel. Value is a YouTube channel ID.")
15 | hl = flag.String("hl", "", "Retrieve localized resource metadata for the specified application language.")
16 | maxResults = flag.Int64("maxResults", 5, "The maximum number of playlist resources to include in the API response.")
17 | mine = flag.Bool("mine", false, "List playlists for authenticated user's channel. Default: false.")
18 | onBehalfOfContentOwner = flag.String("onBehalfOfContentOwner", "", "Indicates that the request's auth credentials identify a user authorized to act on behalf of the specified content owner.")
19 | pageToken = flag.String("pageToken", "", "Token that identifies a specific page in the result set that should be returned.")
20 | part = flag.String("part", "snippet", "Comma-separated list of playlist resource parts that API response will include.")
21 | playlistId = flag.String("playlistId", "", "Retrieve information about this playlist.")
22 | )
23 |
24 | func playlistsList(service *youtube.Service, part string, channelId string, hl string, maxResults int64, mine bool, onBehalfOfContentOwner string, pageToken string, playlistId string) *youtube.PlaylistListResponse {
25 | call := service.Playlists.List(part)
26 | if channelId != "" {
27 | call = call.ChannelId(channelId)
28 | }
29 | if hl != "" {
30 | call = call.Hl(hl)
31 | }
32 | call = call.MaxResults(maxResults)
33 | if mine != false {
34 | call = call.Mine(true)
35 | }
36 | if onBehalfOfContentOwner != "" {
37 | call = call.OnBehalfOfContentOwner(onBehalfOfContentOwner)
38 | }
39 | if pageToken != "" {
40 | call = call.PageToken(pageToken)
41 | }
42 | if playlistId != "" {
43 | call = call.Id(playlistId)
44 | }
45 | response, err := call.Do()
46 | handleError(err, "")
47 | return response
48 | }
49 |
50 | func main() {
51 | flag.Parse()
52 |
53 | if *channelId == "" && *mine == false && *playlistId == "" {
54 | log.Fatalf("You must either set a value for the channelId or playlistId flag or set the mine flag to 'true'.")
55 | }
56 | client := getClient(youtube.YoutubeReadonlyScope)
57 |
58 | service, err := youtube.New(client)
59 | if err != nil {
60 | log.Fatalf("Error creating YouTube client: %v", err)
61 | }
62 |
63 | response := playlistsList(service, "snippet,contentDetails", *channelId, *hl, *maxResults, *mine, *onBehalfOfContentOwner, *pageToken, *playlistId)
64 |
65 | for _, playlist := range response.Items {
66 | playlistId := playlist.Id
67 | playlistTitle := playlist.Snippet.Title
68 |
69 | // Print the playlist ID and title for the playlist resource.
70 | fmt.Println(playlistId, ": ", playlistTitle)
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/go/search_by_keyword.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "log"
7 | "net/http"
8 |
9 | "google.golang.org/api/googleapi/transport"
10 | "google.golang.org/api/youtube/v3"
11 | )
12 |
13 | var (
14 | query = flag.String("query", "Google", "Search term")
15 | maxResults = flag.Int64("max-results", 25, "Max YouTube results")
16 | )
17 |
18 | const developerKey = "YOUR DEVELOPER KEY"
19 |
20 | func main() {
21 | flag.Parse()
22 |
23 | client := &http.Client{
24 | Transport: &transport.APIKey{Key: developerKey},
25 | }
26 |
27 | service, err := youtube.New(client)
28 | if err != nil {
29 | log.Fatalf("Error creating new YouTube client: %v", err)
30 | }
31 |
32 | // Make the API call to YouTube.
33 | call := service.Search.List("id,snippet").
34 | Q(*query).
35 | MaxResults(*maxResults)
36 | response, err := call.Do()
37 | handleError(err, "")
38 |
39 | // Group video, channel, and playlist results in separate lists.
40 | videos := make(map[string]string)
41 | channels := make(map[string]string)
42 | playlists := make(map[string]string)
43 |
44 | // Iterate through each item and add it to the correct list.
45 | for _, item := range response.Items {
46 | switch item.Id.Kind {
47 | case "youtube#video":
48 | videos[item.Id.VideoId] = item.Snippet.Title
49 | case "youtube#channel":
50 | channels[item.Id.ChannelId] = item.Snippet.Title
51 | case "youtube#playlist":
52 | playlists[item.Id.PlaylistId] = item.Snippet.Title
53 | }
54 | }
55 |
56 | printIDs("Videos", videos)
57 | printIDs("Channels", channels)
58 | printIDs("Playlists", playlists)
59 | }
60 |
61 | // Print the ID and title of each result in a list as well as a name that
62 | // identifies the list. For example, print the word section name "Videos"
63 | // above a list of video search results, followed by the video ID and title
64 | // of each matching video.
65 | func printIDs(sectionName string, matches map[string]string) {
66 | fmt.Printf("%v:\n", sectionName)
67 | for id, title := range matches {
68 | fmt.Printf("[%v] %v\n", id, title)
69 | }
70 | fmt.Printf("\n\n")
71 | }
72 |
--------------------------------------------------------------------------------
/go/upload_video.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "log"
7 | "os"
8 | "strings"
9 |
10 | "google.golang.org/api/youtube/v3"
11 | )
12 |
13 | var (
14 | filename = flag.String("filename", "", "Name of video file to upload")
15 | title = flag.String("title", "Test Title", "Video title")
16 | description = flag.String("description", "Test Description", "Video description")
17 | category = flag.String("category", "22", "Video category")
18 | keywords = flag.String("keywords", "", "Comma separated list of video keywords")
19 | privacy = flag.String("privacy", "unlisted", "Video privacy status")
20 | )
21 |
22 | func main() {
23 | flag.Parse()
24 |
25 | if *filename == "" {
26 | log.Fatalf("You must provide a filename of a video file to upload")
27 | }
28 |
29 | client := getClient(youtube.YoutubeUploadScope)
30 |
31 | service, err := youtube.New(client)
32 | if err != nil {
33 | log.Fatalf("Error creating YouTube client: %v", err)
34 | }
35 |
36 | upload := &youtube.Video{
37 | Snippet: &youtube.VideoSnippet{
38 | Title: *title,
39 | Description: *description,
40 | CategoryId: *category,
41 | },
42 | Status: &youtube.VideoStatus{PrivacyStatus: *privacy},
43 | }
44 |
45 | // The API returns a 400 Bad Request response if tags is an empty string.
46 | if strings.Trim(*keywords, "") != "" {
47 | upload.Snippet.Tags = strings.Split(*keywords, ",")
48 | }
49 |
50 | call := service.Videos.Insert("snippet,status", upload)
51 |
52 | file, err := os.Open(*filename)
53 | defer file.Close()
54 | if err != nil {
55 | log.Fatalf("Error opening %v: %v", *filename, err)
56 | }
57 |
58 | response, err := call.Media(file).Do()
59 | handleError(err, "")
60 | fmt.Printf("Upload successful! Video ID: %v\n", response.Id)
61 | }
62 |
--------------------------------------------------------------------------------
/java/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.google.api.services.samples.youtube.cmdline
6 | samples
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | youtube-api-cmdline-samples
11 | http://maven.apache.org
12 |
13 |
14 | v3-rev182-1.22.0
15 | v1-rev63-1.22.0
16 | v1-rev10-1.22.0
17 | 1.20.0
18 | 1.20.0
19 | UTF-8
20 |
21 |
22 |
23 |
24 | google-api-services
25 | http://google-api-client-libraries.appspot.com/mavenrepo
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | com.google.apis
34 | google-api-services-youtube
35 | ${project.youtube.version}
36 |
37 |
38 |
39 |
40 | com.google.apis
41 | google-api-services-youtubeAnalytics
42 | ${project.youtube.analytics.version}
43 |
44 |
45 |
46 |
47 | com.google.apis
48 | google-api-services-youtubereporting
49 | ${project.youtube.reporting.version}
50 |
51 |
52 |
53 |
54 | org.codehaus.jackson
55 | jackson-mapper-asl
56 | 1.9.4
57 |
58 |
59 |
60 | com.google.http-client
61 | google-http-client-jackson2
62 | ${project.http.version}
63 |
64 |
65 |
66 | com.google.oauth-client
67 | google-oauth-client-jetty
68 | ${project.oauth.version}
69 |
70 |
71 |
72 | com.google.collections
73 | google-collections
74 | 1.0
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | maven-compiler-plugin
84 | 3.6.0
85 |
86 | 1.6
87 | 1.6
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/java/src/main/java/com/google/api/services/samples/youtube/cmdline/Auth.java:
--------------------------------------------------------------------------------
1 | package com.google.api.services.samples.youtube.cmdline;
2 |
3 | import com.google.api.client.auth.oauth2.Credential;
4 | import com.google.api.client.auth.oauth2.StoredCredential;
5 | import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
6 | import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
7 | import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
8 | import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
9 | import com.google.api.client.http.HttpTransport;
10 | import com.google.api.client.http.javanet.NetHttpTransport;
11 | import com.google.api.client.json.JsonFactory;
12 | import com.google.api.client.json.jackson2.JacksonFactory;
13 | import com.google.api.client.util.store.DataStore;
14 | import com.google.api.client.util.store.FileDataStoreFactory;
15 |
16 | import java.io.File;
17 | import java.io.IOException;
18 | import java.io.InputStreamReader;
19 | import java.io.Reader;
20 | import java.util.List;
21 |
22 | /**
23 | * Shared class used by every sample. Contains methods for authorizing a user and caching credentials.
24 | */
25 | public class Auth {
26 |
27 | /**
28 | * Define a global instance of the HTTP transport.
29 | */
30 | public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
31 |
32 | /**
33 | * Define a global instance of the JSON factory.
34 | */
35 | public static final JsonFactory JSON_FACTORY = new JacksonFactory();
36 |
37 | /**
38 | * This is the directory that will be used under the user's home directory where OAuth tokens will be stored.
39 | */
40 | private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
41 |
42 | /**
43 | * Authorizes the installed application to access user's protected data.
44 | *
45 | * @param scopes list of scopes needed to run youtube upload.
46 | * @param credentialDatastore name of the credential datastore to cache OAuth tokens
47 | */
48 | public static Credential authorize(List scopes, String credentialDatastore) throws IOException {
49 |
50 | // Load client secrets.
51 | Reader clientSecretReader = new InputStreamReader(Auth.class.getResourceAsStream("/client_secrets.json"));
52 | GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
53 |
54 | // Checks that the defaults have been replaced (Default = "Enter X here").
55 | if (clientSecrets.getDetails().getClientId().startsWith("Enter")
56 | || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
57 | System.out.println(
58 | "Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
59 | + "into src/main/resources/client_secrets.json");
60 | System.exit(1);
61 | }
62 |
63 | // This creates the credentials datastore at ~/.oauth-credentials/${credentialDatastore}
64 | FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
65 | DataStore datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
66 |
67 | GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
68 | HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
69 | .build();
70 |
71 | // Build the local server and bind it to port 8080
72 | LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();
73 |
74 | // Authorize.
75 | return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/java/src/main/java/com/google/api/services/samples/youtube/cmdline/live/DeleteLiveChatMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 |
15 | package com.google.api.services.samples.youtube.cmdline.live;
16 |
17 | import com.google.api.client.auth.oauth2.Credential;
18 | import com.google.api.client.googleapis.json.GoogleJsonResponseException;
19 | import com.google.api.services.samples.youtube.cmdline.Auth;
20 | import com.google.api.services.youtube.YouTube;
21 | import com.google.api.services.youtube.YouTubeScopes;
22 | import com.google.common.collect.Lists;
23 | import java.io.IOException;
24 | import java.util.List;
25 |
26 | /**
27 | * Delets a message from a live broadcast, using OAuth 2.0 to authorize API requests.
28 | *
29 | * @author Jim Rogers
30 | */
31 | public class DeleteLiveChatMessage {
32 |
33 | /**
34 | * Define a global instance of a Youtube object, which will be used
35 | * to make YouTube Data API requests.
36 | */
37 | private static YouTube youtube;
38 |
39 | /**
40 | * Deletes a message from a live broadcast.
41 | *
42 | * @param args The message id to delete (required) followed by the videoId (optional). If the
43 | * videoId is given, live chat messages will be retrieved from the chat associated with this
44 | * video. If the videoId is not specified, the signed in user's current live broadcast will be
45 | * used instead.
46 | */
47 | public static void main(String[] args) {
48 | // Get the message id to delete
49 | if (args.length == 0) {
50 | System.err.println("No message id specified");
51 | System.exit(1);
52 | }
53 | String messageId = args[0];
54 |
55 | // This OAuth 2.0 access scope allows for write access to the authenticated user's account.
56 | List scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_FORCE_SSL);
57 |
58 | try {
59 | // Authorize the request.
60 | Credential credential = Auth.authorize(scopes, "deletelivechatmessage");
61 |
62 | // This object is used to make YouTube Data API requests.
63 | youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
64 | .setApplicationName("youtube-cmdline-deletechatmessages-sample").build();
65 |
66 | // Delete the message from live chat
67 | YouTube.LiveChatMessages.Delete liveChatDelete =
68 | youtube.liveChatMessages().delete(messageId);
69 | liveChatDelete.execute();
70 | System.out.println("Deleted message id " + messageId);
71 | } catch (GoogleJsonResponseException e) {
72 | System.err
73 | .println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : "
74 | + e.getDetails().getMessage());
75 | e.printStackTrace();
76 | } catch (IOException e) {
77 | System.err.println("IOException: " + e.getMessage());
78 | e.printStackTrace();
79 | } catch (Throwable t) {
80 | System.err.println("Throwable: " + t.getMessage());
81 | t.printStackTrace();
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/java/src/main/java/com/google/api/services/samples/youtube/cmdline/live/ListStreams.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 |
15 | package com.google.api.services.samples.youtube.cmdline.live;
16 |
17 | import com.google.api.client.auth.oauth2.Credential;
18 | import com.google.api.client.googleapis.json.GoogleJsonResponseException;
19 | import com.google.api.services.samples.youtube.cmdline.Auth;
20 | import com.google.api.services.youtube.YouTube;
21 | import com.google.api.services.youtube.model.LiveStream;
22 | import com.google.api.services.youtube.model.LiveStreamListResponse;
23 | import com.google.common.collect.Lists;
24 |
25 | import java.io.IOException;
26 | import java.util.List;
27 |
28 | /**
29 | * Retrieve a list of a channel's streams, using OAuth 2.0 to authorize
30 | * API requests.
31 | *
32 | * @author Ibrahim Ulukaya
33 | */
34 | public class ListStreams {
35 |
36 | /**
37 | * Define a global instance of a Youtube object, which will be used
38 | * to make YouTube Data API requests.
39 | */
40 | private static YouTube youtube;
41 |
42 | /**
43 | * List streams for the user's channel.
44 | */
45 | public static void main(String[] args) {
46 |
47 | // This OAuth 2.0 access scope allows for read-only access to the
48 | // authenticated user's account, but not other types of account access.
49 | List scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.readonly");
50 |
51 | try {
52 | // Authorize the request.
53 | Credential credential = Auth.authorize(scopes, "liststreams");
54 |
55 | // This object is used to make YouTube Data API requests.
56 | youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
57 | .setApplicationName("youtube-cmdline-liststreams-sample")
58 | .build();
59 |
60 | // Create a request to list liveStream resources.
61 | YouTube.LiveStreams.List livestreamRequest = youtube.liveStreams().list("id,snippet");
62 |
63 | // Modify results to only return the user's streams.
64 | livestreamRequest.setMine(true);
65 |
66 | // Execute the API request and return the list of streams.
67 | LiveStreamListResponse returnedListResponse = livestreamRequest.execute();
68 | List returnedList = returnedListResponse.getItems();
69 |
70 | // Print information from the API response.
71 | System.out.println("\n================== Returned Streams ==================\n");
72 | for (LiveStream stream : returnedList) {
73 | System.out.println(" - Id: " + stream.getId());
74 | System.out.println(" - Title: " + stream.getSnippet().getTitle());
75 | System.out.println(" - Description: " + stream.getSnippet().getDescription());
76 | System.out.println(" - Published At: " + stream.getSnippet().getPublishedAt());
77 | System.out.println("\n-------------------------------------------------------------\n");
78 | }
79 |
80 | } catch (GoogleJsonResponseException e) {
81 | System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : "
82 | + e.getDetails().getMessage());
83 | e.printStackTrace();
84 |
85 | } catch (IOException e) {
86 | System.err.println("IOException: " + e.getMessage());
87 | e.printStackTrace();
88 | } catch (Throwable t) {
89 | System.err.println("Throwable: " + t.getMessage());
90 | t.printStackTrace();
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/java/src/main/resources/client_secrets.json:
--------------------------------------------------------------------------------
1 | {
2 | "installed": {
3 | "client_id": "Enter your client id here",
4 | "client_secret": "Enter your client secret here"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/java/src/main/resources/sample-video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youtube/api-samples/07263305b59a7c3275bc7e925f9ce6cabf774022/java/src/main/resources/sample-video.mp4
--------------------------------------------------------------------------------
/java/src/main/resources/watermark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/youtube/api-samples/07263305b59a7c3275bc7e925f9ce6cabf774022/java/src/main/resources/watermark.jpg
--------------------------------------------------------------------------------
/java/src/main/resources/youtube.properties:
--------------------------------------------------------------------------------
1 | # Replace this with an API key available at
2 | # https://console.developers.google.com/project/_/apiui/credential
3 | youtube.apikey=YOUR_SIMPLE_API_KEY_HERE
4 |
--------------------------------------------------------------------------------
/javascript/analytics_codelab.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Helvetica, sans-serif;
3 | }
4 |
5 | .pre-auth {
6 | display: none;
7 | }
8 |
9 | .post-auth {
10 | display: none;
11 | }
12 |
13 | #chart {
14 | width: 500px;
15 | height: 300px;
16 | margin-bottom: 1em;
17 | }
18 |
19 | #video-list {
20 | padding-left: 1em;
21 | list-style-type: none;
22 | }
23 | #video-list > li {
24 | cursor: pointer;
25 | }
26 | #video-list > li:hover {
27 | color: blue;
28 | }
29 |
--------------------------------------------------------------------------------
/javascript/analytics_codelab.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Google I/O YouTube Codelab
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
This application requires access to your YouTube account.
13 | Please authorize to continue.
14 |
15 |
16 |
17 |
18 |
Choose a Video:
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/javascript/auth.js:
--------------------------------------------------------------------------------
1 | // The client ID is obtained from the {{ Google Cloud Console }}
2 | // at {{ https://cloud.google.com/console }}.
3 | // If you run this code from a server other than http://localhost,
4 | // you need to register your own client ID.
5 | var OAUTH2_CLIENT_ID = '__YOUR_CLIENT_ID__';
6 | var OAUTH2_SCOPES = [
7 | 'https://www.googleapis.com/auth/youtube'
8 | ];
9 |
10 | // Upon loading, the Google APIs JS client automatically invokes this callback.
11 | googleApiClientReady = function() {
12 | gapi.auth.init(function() {
13 | window.setTimeout(checkAuth, 1);
14 | });
15 | }
16 |
17 | // Attempt the immediate OAuth 2.0 client flow as soon as the page loads.
18 | // If the currently logged-in Google Account has previously authorized
19 | // the client specified as the OAUTH2_CLIENT_ID, then the authorization
20 | // succeeds with no user intervention. Otherwise, it fails and the
21 | // user interface that prompts for authorization needs to display.
22 | function checkAuth() {
23 | gapi.auth.authorize({
24 | client_id: OAUTH2_CLIENT_ID,
25 | scope: OAUTH2_SCOPES,
26 | immediate: true
27 | }, handleAuthResult);
28 | }
29 |
30 | // Handle the result of a gapi.auth.authorize() call.
31 | function handleAuthResult(authResult) {
32 | if (authResult && !authResult.error) {
33 | // Authorization was successful. Hide authorization prompts and show
34 | // content that should be visible after authorization succeeds.
35 | $('.pre-auth').hide();
36 | $('.post-auth').show();
37 | loadAPIClientInterfaces();
38 | } else {
39 | // Make the #login-link clickable. Attempt a non-immediate OAuth 2.0
40 | // client flow. The current function is called when that flow completes.
41 | $('#login-link').click(function() {
42 | gapi.auth.authorize({
43 | client_id: OAUTH2_CLIENT_ID,
44 | scope: OAUTH2_SCOPES,
45 | immediate: false
46 | }, handleAuthResult);
47 | });
48 | }
49 | }
50 |
51 | // Load the client interfaces for the YouTube Analytics and Data APIs, which
52 | // are required to use the Google APIs JS client. More info is available at
53 | // https://developers.google.com/api-client-library/javascript/dev/dev_jscript#loading-the-client-library-and-the-api
54 | function loadAPIClientInterfaces() {
55 | gapi.client.load('youtube', 'v3', function() {
56 | handleAPILoaded();
57 | });
58 | }
59 |
--------------------------------------------------------------------------------
/javascript/my_uploads.css:
--------------------------------------------------------------------------------
1 | .paging-button {
2 | visibility: hidden;
3 | }
4 |
5 | .button-container {
6 | clear: both;
7 | }
8 |
--------------------------------------------------------------------------------
/javascript/my_uploads.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My Uploads
5 |
6 |
7 |
8 |
9 | This application requires access to your YouTube account.
10 | Please authorize to continue.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/javascript/my_uploads.js:
--------------------------------------------------------------------------------
1 | // Define some variables used to remember state.
2 | var playlistId, nextPageToken, prevPageToken;
3 |
4 | // After the API loads, call a function to get the uploads playlist ID.
5 | function handleAPILoaded() {
6 | requestUserUploadsPlaylistId();
7 | }
8 |
9 | // Call the Data API to retrieve the playlist ID that uniquely identifies the
10 | // list of videos uploaded to the currently authenticated user's channel.
11 | function requestUserUploadsPlaylistId() {
12 | // See https://developers.google.com/youtube/v3/docs/channels/list
13 | var request = gapi.client.youtube.channels.list({
14 | mine: true,
15 | part: 'contentDetails'
16 | });
17 | request.execute(function(response) {
18 | playlistId = response.result.items[0].contentDetails.relatedPlaylists.uploads;
19 | requestVideoPlaylist(playlistId);
20 | });
21 | }
22 |
23 | // Retrieve the list of videos in the specified playlist.
24 | function requestVideoPlaylist(playlistId, pageToken) {
25 | $('#video-container').html('');
26 | var requestOptions = {
27 | playlistId: playlistId,
28 | part: 'snippet',
29 | maxResults: 10
30 | };
31 | if (pageToken) {
32 | requestOptions.pageToken = pageToken;
33 | }
34 | var request = gapi.client.youtube.playlistItems.list(requestOptions);
35 | request.execute(function(response) {
36 | // Only show pagination buttons if there is a pagination token for the
37 | // next or previous page of results.
38 | nextPageToken = response.result.nextPageToken;
39 | var nextVis = nextPageToken ? 'visible' : 'hidden';
40 | $('#next-button').css('visibility', nextVis);
41 | prevPageToken = response.result.prevPageToken
42 | var prevVis = prevPageToken ? 'visible' : 'hidden';
43 | $('#prev-button').css('visibility', prevVis);
44 |
45 | var playlistItems = response.result.items;
46 | if (playlistItems) {
47 | $.each(playlistItems, function(index, item) {
48 | displayResult(item.snippet);
49 | });
50 | } else {
51 | $('#video-container').html('Sorry you have no uploaded videos');
52 | }
53 | });
54 | }
55 |
56 | // Create a listing for a video.
57 | function displayResult(videoSnippet) {
58 | var title = videoSnippet.title;
59 | var videoId = videoSnippet.resourceId.videoId;
60 | $('#video-container').append('
' + title + ' - ' + videoId + '
');
61 | }
62 |
63 | // Retrieve the next page of videos in the playlist.
64 | function nextPage() {
65 | requestVideoPlaylist(playlistId, nextPageToken);
66 | }
67 |
68 | // Retrieve the previous page of videos in the playlist.
69 | function previousPage() {
70 | requestVideoPlaylist(playlistId, prevPageToken);
71 | }
72 |
--------------------------------------------------------------------------------
/javascript/nodejs-quickstart.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var readline = require('readline');
3 | var {google} = require('googleapis');
4 | var OAuth2 = google.auth.OAuth2;
5 |
6 | // If modifying these scopes, delete your previously saved credentials
7 | // at ~/.credentials/youtube-nodejs-quickstart.json
8 | var SCOPES = ['https://www.googleapis.com/auth/youtube.readonly'];
9 | var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
10 | process.env.USERPROFILE) + '/.credentials/';
11 | var TOKEN_PATH = TOKEN_DIR + 'youtube-nodejs-quickstart.json';
12 |
13 | // Load client secrets from a local file.
14 | fs.readFile('client_secret.json', function processClientSecrets(err, content) {
15 | if (err) {
16 | console.log('Error loading client secret file: ' + err);
17 | return;
18 | }
19 | // Authorize a client with the loaded credentials, then call the YouTube API.
20 | authorize(JSON.parse(content), getChannel);
21 | });
22 |
23 | /**
24 | * Create an OAuth2 client with the given credentials, and then execute the
25 | * given callback function.
26 | *
27 | * @param {Object} credentials The authorization client credentials.
28 | * @param {function} callback The callback to call with the authorized client.
29 | */
30 | function authorize(credentials, callback) {
31 | var clientSecret = credentials.installed.client_secret;
32 | var clientId = credentials.installed.client_id;
33 | var redirectUrl = credentials.installed.redirect_uris[0];
34 | var oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl);
35 |
36 | // Check if we have previously stored a token.
37 | fs.readFile(TOKEN_PATH, function(err, token) {
38 | if (err) {
39 | getNewToken(oauth2Client, callback);
40 | } else {
41 | oauth2Client.credentials = JSON.parse(token);
42 | callback(oauth2Client);
43 | }
44 | });
45 | }
46 |
47 | /**
48 | * Get and store new token after prompting for user authorization, and then
49 | * execute the given callback with the authorized OAuth2 client.
50 | *
51 | * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
52 | * @param {getEventsCallback} callback The callback to call with the authorized
53 | * client.
54 | */
55 | function getNewToken(oauth2Client, callback) {
56 | var authUrl = oauth2Client.generateAuthUrl({
57 | access_type: 'offline',
58 | scope: SCOPES
59 | });
60 | console.log('Authorize this app by visiting this url: ', authUrl);
61 | var rl = readline.createInterface({
62 | input: process.stdin,
63 | output: process.stdout
64 | });
65 | rl.question('Enter the code from that page here: ', function(code) {
66 | rl.close();
67 | oauth2Client.getToken(code, function(err, token) {
68 | if (err) {
69 | console.log('Error while trying to retrieve access token', err);
70 | return;
71 | }
72 | oauth2Client.credentials = token;
73 | storeToken(token);
74 | callback(oauth2Client);
75 | });
76 | });
77 | }
78 |
79 | /**
80 | * Store token to disk be used in later program executions.
81 | *
82 | * @param {Object} token The token to store to disk.
83 | */
84 | function storeToken(token) {
85 | try {
86 | fs.mkdirSync(TOKEN_DIR);
87 | } catch (err) {
88 | if (err.code != 'EEXIST') {
89 | throw err;
90 | }
91 | }
92 | fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
93 | if (err) throw err;
94 | console.log('Token stored to ' + TOKEN_PATH);
95 | });
96 | }
97 |
98 | /**
99 | * Lists the names and IDs of up to 10 files.
100 | *
101 | * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
102 | */
103 | function getChannel(auth) {
104 | var service = google.youtube('v3');
105 | service.channels.list({
106 | auth: auth,
107 | part: 'snippet,contentDetails,statistics',
108 | forUsername: 'GoogleDevelopers'
109 | }, function(err, response) {
110 | if (err) {
111 | console.log('The API returned an error: ' + err);
112 | return;
113 | }
114 | var channels = response.data.items;
115 | if (channels.length == 0) {
116 | console.log('No channel found.');
117 | } else {
118 | console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
119 | 'it has %s views.',
120 | channels[0].id,
121 | channels[0].snippet.title,
122 | channels[0].statistics.viewCount);
123 | }
124 | });
125 | }
126 |
--------------------------------------------------------------------------------
/javascript/playlist_updates.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Playlist Updates
5 |
6 |
7 |
This application requires access to your YouTube account.
8 | Please authorize to continue.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Playlist:
18 |
19 |
20 | No Videos
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/javascript/playlist_updates.js:
--------------------------------------------------------------------------------
1 | // Define some variables used to remember state.
2 | var playlistId, channelId;
3 |
4 | // After the API loads, call a function to enable the playlist creation form.
5 | function handleAPILoaded() {
6 | enableForm();
7 | }
8 |
9 | // Enable the form for creating a playlist.
10 | function enableForm() {
11 | $('#playlist-button').attr('disabled', false);
12 | }
13 |
14 | // Create a private playlist.
15 | function createPlaylist() {
16 | var request = gapi.client.youtube.playlists.insert({
17 | part: 'snippet,status',
18 | resource: {
19 | snippet: {
20 | title: 'Test Playlist',
21 | description: 'A private playlist created with the YouTube API'
22 | },
23 | status: {
24 | privacyStatus: 'private'
25 | }
26 | }
27 | });
28 | request.execute(function(response) {
29 | var result = response.result;
30 | if (result) {
31 | playlistId = result.id;
32 | $('#playlist-id').val(playlistId);
33 | $('#playlist-title').html(result.snippet.title);
34 | $('#playlist-description').html(result.snippet.description);
35 | } else {
36 | $('#status').html('Could not create playlist');
37 | }
38 | });
39 | }
40 |
41 | // Add a video ID specified in the form to the playlist.
42 | function addVideoToPlaylist() {
43 | addToPlaylist($('#video-id').val());
44 | }
45 |
46 | // Add a video to a playlist. The "startPos" and "endPos" values let you
47 | // start and stop the video at specific times when the video is played as
48 | // part of the playlist. However, these values are not set in this example.
49 | function addToPlaylist(id, startPos, endPos) {
50 | var details = {
51 | videoId: id,
52 | kind: 'youtube#video'
53 | }
54 | if (startPos != undefined) {
55 | details['startAt'] = startPos;
56 | }
57 | if (endPos != undefined) {
58 | details['endAt'] = endPos;
59 | }
60 | var request = gapi.client.youtube.playlistItems.insert({
61 | part: 'snippet',
62 | resource: {
63 | snippet: {
64 | playlistId: playlistId,
65 | resourceId: details
66 | }
67 | }
68 | });
69 | request.execute(function(response) {
70 | $('#status').html('
By uploading a video, you certify that you own all rights to the content or that you are authorized by the owner to make the content publicly available on YouTube, and that it otherwise complies with the YouTube Terms of Service located at http://www.youtube.com/t/terms
116 | My Uploads
117 |
118 |
119 | =$htmlBody?>
120 |
121 |
122 |
--------------------------------------------------------------------------------
/php/quickstart.php:
--------------------------------------------------------------------------------
1 | setAuthConfigFile('client_secret.json');
21 | // Set to valid redirect URI for your project.
22 | $client->setRedirectUri('http://localhost');
23 |
24 | $client->addScope(Google_Service_YouTube::YOUTUBE_READONLY);
25 | $client->setAccessType('offline');
26 |
27 | // Load previously authorized credentials from a file.
28 | $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
29 | if (file_exists($credentialsPath)) {
30 | $accessToken = file_get_contents($credentialsPath);
31 | } else {
32 | // Request authorization from the user.
33 | $authUrl = $client->createAuthUrl();
34 | printf("Open the following link in your browser:\n%s\n", $authUrl);
35 | print 'Enter verification code: ';
36 | $authCode = trim(fgets(STDIN));
37 |
38 | // Exchange authorization code for an access token.
39 | $accessToken = $client->authenticate($authCode);
40 |
41 | // Store the credentials to disk.
42 | if(!file_exists(dirname($credentialsPath))) {
43 | mkdir(dirname($credentialsPath), 0700, true);
44 | }
45 | file_put_contents($credentialsPath, $accessToken);
46 | printf("Credentials saved to %s\n", $credentialsPath);
47 | }
48 | $client->setAccessToken($accessToken);
49 |
50 | // Refresh the token if it's expired.
51 | if ($client->isAccessTokenExpired()) {
52 | $client->refreshToken($client->getRefreshToken());
53 | file_put_contents($credentialsPath, $client->getAccessToken());
54 | }
55 | return $client;
56 | }
57 |
58 | /**
59 | * Expands the home directory alias '~' to the full path.
60 | * @param string $path the path to expand.
61 | * @return string the expanded path.
62 | */
63 | function expandHomeDirectory($path) {
64 | $homeDirectory = getenv('HOME');
65 | if (empty($homeDirectory)) {
66 | $homeDirectory = getenv("HOMEDRIVE") . getenv("HOMEPATH");
67 | }
68 | return str_replace('~', realpath($homeDirectory), $path);
69 | }
70 |
71 | // Define an object that will be used to make all API requests.
72 | $client = getClient();
73 | $service = new Google_Service_YouTube($client);
74 |
75 | if (isset($_GET['code'])) {
76 | if (strval($_SESSION['state']) !== strval($_GET['state'])) {
77 | die('The session state did not match.');
78 | }
79 |
80 | $client->authenticate($_GET['code']);
81 | $_SESSION['token'] = $client->getAccessToken();
82 | header('Location: ' . $redirect);
83 | }
84 |
85 | if (isset($_SESSION['token'])) {
86 | $client->setAccessToken($_SESSION['token']);
87 | }
88 |
89 | if (!$client->getAccessToken()) {
90 | print("no access token, whaawhaaa");
91 | exit;
92 | }
93 |
94 | // Call channels.list to retrieve information
95 |
96 | function channelsListByUsername($service, $part, $params) {
97 | $params = array_filter($params);
98 | $response = $service->channels->listChannels(
99 | $part,
100 | $params
101 | );
102 |
103 | $description = sprintf(
104 | 'This channel\'s ID is %s. Its title is %s, and it has %s views.',
105 | $response['items'][0]['id'],
106 | $response['items'][0]['snippet']['title'],
107 | $response['items'][0]['statistics']['viewCount']);
108 | print $description . "\n";
109 | }
110 |
111 | channelsListByUsername($service, 'snippet,contentDetails,statistics', array('forUsername' => 'GoogleDevelopers'));
112 | ?>
113 |
--------------------------------------------------------------------------------
/php/search.php:
--------------------------------------------------------------------------------
1 |
19 |
20 | Search Term:
21 |
22 |
23 | Max Results:
24 |
25 |
26 |
27 | END;
28 |
29 | // This code will execute if the user entered a search query in the form
30 | // and submitted the form. Otherwise, the page displays the form above.
31 | if (isset($_GET['q']) && isset($_GET['maxResults'])) {
32 | /*
33 | * Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
34 | * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
35 | * Please ensure that you have enabled the YouTube Data API for your project.
36 | */
37 | $DEVELOPER_KEY = 'REPLACE_ME';
38 |
39 | $client = new Google_Client();
40 | $client->setDeveloperKey($DEVELOPER_KEY);
41 |
42 | // Define an object that will be used to make all API requests.
43 | $youtube = new Google_Service_YouTube($client);
44 |
45 | $htmlBody = '';
46 | try {
47 |
48 | // Call the search.list method to retrieve results matching the specified
49 | // query term.
50 | $searchResponse = $youtube->search->listSearch('id,snippet', array(
51 | 'q' => $_GET['q'],
52 | 'maxResults' => $_GET['maxResults'],
53 | ));
54 |
55 | $videos = '';
56 | $channels = '';
57 | $playlists = '';
58 |
59 | // Add each result to the appropriate list, and then display the lists of
60 | // matching videos, channels, and playlists.
61 | foreach ($searchResponse['items'] as $searchResult) {
62 | switch ($searchResult['id']['kind']) {
63 | case 'youtube#video':
64 | $videos .= sprintf('
10 | {% endfor %}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/python_appengine/user_uploads/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | import urllib
3 | import webapp2
4 | import jinja2
5 |
6 | from apiclient.discovery import build
7 | from optparse import OptionParser
8 |
9 | import json
10 |
11 | JINJA_ENVIRONMENT = jinja2.Environment(
12 | loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
13 | extensions=['jinja2.ext.autoescape'])
14 |
15 | REGISTRATION_INSTRUCTIONS = """
16 | You must set up a project and get an API key to run this code. Please see
17 | the instructions for creating a project and a key at https://developers.google.com/youtube/registering_an_application.
20 |
21 | Make sure that you have enabled the YouTube Data API (v3) and the Freebase
22 | API for your project."""
23 |
24 | # Set API_KEY to the "API key" value from the Google Developers Console:
25 | # https://console.developers.google.com/project/_/apiui/credential
26 | # Please ensure that you have enabled the YouTube Data API and Freebase API
27 | # for your project.
28 | API_KEY = "REPLACE_ME"
29 | YOUTUBE_API_SERVICE_NAME = "youtube"
30 | YOUTUBE_API_VERSION = "v3"
31 | FREEBASE_SEARCH_URL = "https://www.googleapis.com/freebase/v1/search?%s"
32 | QUERY_TERM = "dog"
33 |
34 | class MainHandler(webapp2.RequestHandler):
35 |
36 | def get(self):
37 | if API_KEY == 'REPLACE_ME':
38 | self.response.write(REGISTRATION_INSTRUCTIONS)
39 | else:
40 | # Present a list of Freebase topic IDs for the query term
41 | self.request_channel()
42 |
43 | def request_channel(self):
44 | # Display a text box where the user can enter a channel name or
45 | # channel ID.
46 | select_channel_page = '''
47 |
48 |
49 |
Which channel's videos do you want to see?
50 |
60 |
61 |
62 | '''
63 |
64 | # Display the HTML page that shows the form.
65 | self.response.out.write(select_channel_page)
66 |
67 | def post(self):
68 | # Service for calling the YouTube API
69 | youtube = build(YOUTUBE_API_SERVICE_NAME,
70 | YOUTUBE_API_VERSION,
71 | developerKey=API_KEY)
72 |
73 | # Use form inputs to create request params for channel details
74 | channel_type = self.request.get('channel_type')
75 | channels_response = None
76 | if channel_type == 'id':
77 | channels_response = youtube.channels().list(
78 | id=self.request.get('channel'),
79 | part='snippet,contentDetails'
80 | ).execute()
81 | else:
82 | channels_response = youtube.channels().list(
83 | forUsername=self.request.get('channel'),
84 | part='snippet,contentDetails'
85 | ).execute()
86 |
87 | channel_name = ''
88 | videos = []
89 |
90 | for channel in channels_response['items']:
91 | uploads_list_id = channel['contentDetails']['relatedPlaylists']['uploads']
92 | channel_name = channel['snippet']['title']
93 |
94 | next_page_token = ''
95 | while next_page_token is not None:
96 | playlistitems_response = youtube.playlistItems().list(
97 | playlistId=uploads_list_id,
98 | part='snippet',
99 | maxResults=50,
100 | pageToken=next_page_token
101 | ).execute()
102 |
103 | for playlist_item in playlistitems_response['items']:
104 | videos.append(playlist_item)
105 |
106 | next_page_token = playlistitems_response.get('tokenPagination', {}).get(
107 | 'nextPageToken')
108 |
109 | if len(videos) > 100:
110 | break
111 |
112 | template_values = {
113 | 'channel_name': channel_name,
114 | 'videos': videos
115 | }
116 |
117 | self.response.headers['Content-type'] = 'text/html'
118 | template = JINJA_ENVIRONMENT.get_template('index.html')
119 | self.response.write(template.render(template_values))
120 |
121 | app = webapp2.WSGIApplication([
122 | ('/.*', MainHandler),
123 | ], debug=True)
124 |
--------------------------------------------------------------------------------
/ruby/README.md:
--------------------------------------------------------------------------------
1 | ## Samples in this directory:
2 |
3 | ### [Authorize a request](/ruby/oauth/oauth_util.rb)
4 |
5 | Description: The following code sample performs OAuth 2.0 authorization by checking for the presence of a local
6 | file that contains authorization credentials. If the file is not present, the script opens a browser and waits
7 | for a response, then saves the returned credentials locally.
8 |
9 | ### [Add a channel subscription](/ruby/add_subscription.rb)
10 |
11 | Method: youtube.subscriptions.insert
12 | Description: This sample calls the API's subscriptions.insert method to add a subscription
13 | to a specified channel.
14 |
15 | ### [Post a channel bulletin](/ruby/channel_bulletin.rb)
16 |
17 | Method: youtube.activities.insert
18 | Description: This sample calls the API's activities.insert method to post a bulletin to the channel
19 | associated with the request.
20 |
21 | ### [Retrieve my uploads](/ruby/my_uploads.rb)
22 |
23 | Method: youtube.playlistItems.list
24 | Description: This sample calls the API's playlistItems.list method to retrieve a list of videos uploaded
25 | to the channel associated with the request. The code also calls the channels.list method with the
26 | mine parameter set to true to retrieve the playlist ID that identifies the channel's
27 | uploaded videos.
28 |
29 | ### [Search by keyword](/ruby/search.rb)
30 |
31 | Method: youtube.search.list
32 | Description: This sample calls the API's search.list method to retrieve search results
33 | associated with a particular keyword.
34 |
35 | ### [Upload a video](/ruby/upload_video.rb)
36 |
37 | Method: youtube.videos.insert
38 | Description: This sample calls the API's videos.insert method to upload a video to the channel
39 | associated with the request.
40 |
41 | ### [Retrieve top 10 videos by viewcount](/ruby/yt_analytics_report.rb)
42 |
43 | Method: youtubeAnalytics.reports.query
44 | Description: This sample calls the API's reports.query method to retrieve YouTube Analytics data.
45 | By default, the report retrieves the top 10 videos based on viewcounts, and it returns several metrics for those
46 | videos, sorting the results in reverse order by viewcount. By setting command line parameters, you can use the same
47 | code to retrieve other reports as well.
48 |
--------------------------------------------------------------------------------
/ruby/add_subscription.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'rubygems'
4 | gem 'google-api-client', '>0.7'
5 | require 'google/api_client'
6 | require 'google/api_client/client_secrets'
7 | require 'google/api_client/auth/file_storage'
8 | require 'google/api_client/auth/installed_app'
9 | require 'trollop'
10 |
11 | # This OAuth 2.0 access scope allows for full read/write access to the
12 | # authenticated user's account.
13 | YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube'
14 | YOUTUBE_API_SERVICE_NAME = 'youtube'
15 | YOUTUBE_API_VERSION = 'v3'
16 |
17 | def get_authenticated_service
18 | client = Google::APIClient.new(
19 | :application_name => $PROGRAM_NAME,
20 | :application_version => '1.0.0'
21 | )
22 | youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
23 |
24 | file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
25 | if file_storage.authorization.nil?
26 | client_secrets = Google::APIClient::ClientSecrets.load
27 | flow = Google::APIClient::InstalledAppFlow.new(
28 | :client_id => client_secrets.client_id,
29 | :client_secret => client_secrets.client_secret,
30 | :scope => [YOUTUBE_SCOPE]
31 | )
32 | client.authorization = flow.authorize(file_storage)
33 | else
34 | client.authorization = file_storage.authorization
35 | end
36 |
37 | return client, youtube
38 | end
39 |
40 | def main
41 | opts = Trollop::options do
42 | opt :channel_id, 'ID of the channel to subscribe to.', :type => String,
43 | :default => 'UCtVd0c0tGXuTSbU5d8cSBUg'
44 | end
45 |
46 | client, youtube = get_authenticated_service
47 |
48 | begin
49 | body = {
50 | :snippet => {
51 | :resourceId => {
52 | :channelId => opts[:channel_id]
53 | }
54 | }
55 | }
56 |
57 | # Call the API's youtube.subscriptions.insert method to add the subscription
58 | # to the specified channel.
59 | subscriptions_response = client.execute!(
60 | :api_method => youtube.subscriptions.insert,
61 | :parameters => {
62 | :part => body.keys.join(',')
63 | },
64 | :body_object => body
65 | )
66 |
67 | puts "A subscription to '#{subscriptions_response.data.snippet.title}' was added."
68 | rescue Google::APIClient::TransmissionError => e
69 | puts e.result.body
70 | end
71 | end
72 |
73 | main
74 |
--------------------------------------------------------------------------------
/ruby/channel_bulletin.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'rubygems'
4 | gem 'google-api-client', '>0.7'
5 | require 'google/api_client'
6 | require 'google/api_client/client_secrets'
7 | require 'google/api_client/auth/file_storage'
8 | require 'google/api_client/auth/installed_app'
9 | require 'trollop'
10 |
11 | # This OAuth 2.0 access scope allows for full read/write access to the
12 | # authenticated user's account.
13 | YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube'
14 | YOUTUBE_API_SERVICE_NAME = 'youtube'
15 | YOUTUBE_API_VERSION = 'v3'
16 |
17 | def get_authenticated_service
18 | client = Google::APIClient.new(
19 | :application_name => $PROGRAM_NAME,
20 | :application_version => '1.0.0'
21 | )
22 | youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
23 |
24 | file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
25 | if file_storage.authorization.nil?
26 | client_secrets = Google::APIClient::ClientSecrets.load
27 | flow = Google::APIClient::InstalledAppFlow.new(
28 | :client_id => client_secrets.client_id,
29 | :client_secret => client_secrets.client_secret,
30 | :scope => [YOUTUBE_SCOPE]
31 | )
32 | client.authorization = flow.authorize(file_storage)
33 | else
34 | client.authorization = file_storage.authorization
35 | end
36 |
37 | return client, youtube
38 | end
39 |
40 | def main
41 | opts = Trollop::options do
42 | opt :message, 'Required text of message to post.', :type => String
43 | opt :video_id, 'Optional ID of video to post.', :type => String
44 | opt :playlist_id, 'Optional ID of playlist to post.', :type => String
45 | end
46 |
47 | # You can post a message with or without an accompanying video or playlist.
48 | # However, you can't post a video and a playlist at the same time.
49 | if opts[:video_id] and opts[:playlist_id]
50 | Trollop::die 'You cannot post a video and a playlist at the same time'
51 | end
52 | Trollop::die :message, 'is required' unless opts[:message]
53 |
54 | client, youtube = get_authenticated_service
55 |
56 | begin
57 | body = {
58 | :snippet => {
59 | :description => opts[:message]
60 | }
61 | }
62 |
63 | if opts[:video_id]
64 | body[:contentDetails] = {
65 | :bulletin => {
66 | :resourceId => {
67 | :kind => 'youtube#video',
68 | :videoId => opts[:video_id]
69 | }
70 | }
71 | }
72 | end
73 |
74 | if opts[:playlist_id]
75 | body[:contentDetails] = {
76 | :bulletin => {
77 | :resourceId => {
78 | :kind => 'youtube#playlist',
79 | :playlistId => opts[:playlist_id]
80 | }
81 | }
82 | }
83 | end
84 |
85 | # Call the youtube.activities.insert method to post the channel bulletin.
86 | client.execute!(
87 | :api_method => youtube.activities.insert,
88 | :parameters => {
89 | :part => body.keys.join(',')
90 | },
91 | :body_object => body
92 | )
93 |
94 | puts "The bulletin was posted to your channel."
95 | rescue Google::APIClient::TransmissionError => e
96 | puts e.result.body
97 | end
98 | end
99 |
100 | main
101 |
--------------------------------------------------------------------------------
/ruby/my_uploads.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'rubygems'
4 | gem 'google-api-client', '>0.7'
5 | require 'google/api_client'
6 | require 'google/api_client/client_secrets'
7 | require 'google/api_client/auth/file_storage'
8 | require 'google/api_client/auth/installed_app'
9 |
10 | # This OAuth 2.0 access scope allows for read-only access to the authenticated
11 | # user's account, but not other types of account access.
12 | YOUTUBE_READONLY_SCOPE = 'https://www.googleapis.com/auth/youtube.readonly'
13 | YOUTUBE_API_SERVICE_NAME = 'youtube'
14 | YOUTUBE_API_VERSION = 'v3'
15 |
16 | def get_authenticated_service
17 | client = Google::APIClient.new(
18 | :application_name => $PROGRAM_NAME,
19 | :application_version => '1.0.0'
20 | )
21 | youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
22 |
23 | file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
24 | if file_storage.authorization.nil?
25 | client_secrets = Google::APIClient::ClientSecrets.load
26 | flow = Google::APIClient::InstalledAppFlow.new(
27 | :client_id => client_secrets.client_id,
28 | :client_secret => client_secrets.client_secret,
29 | :scope => [YOUTUBE_READONLY_SCOPE]
30 | )
31 | client.authorization = flow.authorize(file_storage)
32 | else
33 | client.authorization = file_storage.authorization
34 | end
35 |
36 | return client, youtube
37 | end
38 |
39 | def main
40 | client, youtube = get_authenticated_service
41 |
42 | begin
43 | # Retrieve the "contentDetails" part of the channel resource for the
44 | # authenticated user's channel.
45 | channels_response = client.execute!(
46 | :api_method => youtube.channels.list,
47 | :parameters => {
48 | :mine => true,
49 | :part => 'contentDetails'
50 | }
51 | )
52 |
53 | channels_response.data.items.each do |channel|
54 | # From the API response, extract the playlist ID that identifies the list
55 | # of videos uploaded to the authenticated user's channel.
56 | uploads_list_id = channel['contentDetails']['relatedPlaylists']['uploads']
57 |
58 | # Retrieve the list of videos uploaded to the authenticated user's channel.
59 | next_page_token = ''
60 | until next_page_token.nil?
61 | playlistitems_response = client.execute!(
62 | :api_method => youtube.playlist_items.list,
63 | :parameters => {
64 | :playlistId => uploads_list_id,
65 | :part => 'snippet',
66 | :maxResults => 50,
67 | :pageToken => next_page_token
68 | }
69 | )
70 |
71 | puts "Videos in list #{uploads_list_id}"
72 |
73 | # Print information about each video.
74 | playlistitems_response.data.items.each do |playlist_item|
75 | title = playlist_item['snippet']['title']
76 | video_id = playlist_item['snippet']['resourceId']['videoId']
77 |
78 | puts "#{title} (#{video_id})"
79 | end
80 |
81 | next_page_token = playlistitems_response.next_page_token
82 | end
83 |
84 | puts
85 | end
86 | rescue Google::APIClient::TransmissionError => e
87 | puts e.result.body
88 | end
89 | end
90 |
91 | main
92 |
--------------------------------------------------------------------------------
/ruby/oauth/oauth_util.rb:
--------------------------------------------------------------------------------
1 | require 'google/api_client'
2 | require 'google/api_client/client_secrets'
3 | require 'json'
4 | require 'launchy'
5 | require 'thin'
6 |
7 | RESPONSE_HTML = <
9 |
10 | OAuth 2 Flow Complete
11 |
12 |
13 | You have successfully completed the OAuth 2 flow. Please close this browser window and return to your program.
14 |
15 |