001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nelson Silva 018 */ 019 020package org.nuxeo.ecm.media.publishing.youtube; 021 022import com.google.api.client.auth.oauth2.Credential; 023import com.google.api.client.googleapis.media.MediaHttpUploader; 024import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener; 025import com.google.api.client.http.HttpStatusCodes; 026import com.google.api.client.http.HttpTransport; 027import com.google.api.client.http.InputStreamContent; 028import com.google.api.client.http.javanet.NetHttpTransport; 029import com.google.api.client.json.JsonFactory; 030import com.google.api.client.json.jackson2.JacksonFactory; 031import com.google.api.services.youtube.YouTube; 032import com.google.api.services.youtube.YouTube.Videos.Delete; 033import com.google.api.services.youtube.YouTube.Videos.Insert; 034import com.google.api.services.youtube.model.*; 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.nuxeo.ecm.platform.oauth2.providers.OAuth2ServiceProviderRegistry; 038import org.nuxeo.runtime.api.Framework; 039 040import java.io.IOException; 041import java.io.InputStream; 042import java.util.List; 043 044/** 045 * Client for the YouTube API 046 * 047 * @since 7.3 048 */ 049public class YouTubeClient { 050 private static final Log log = LogFactory.getLog(YouTubeClient.class); 051 052 /** Global instance of the HTTP transport. */ 053 private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); 054 055 /** Global instance of the JSON factory. */ 056 private static final JsonFactory JSON_FACTORY = new JacksonFactory(); 057 058 YouTube youtube; 059 060 Credential credential; 061 062 public YouTubeClient(Credential credential) { 063 this.credential = credential; 064 } 065 066 protected OAuth2ServiceProviderRegistry getOAuth2ServiceProviderRegistry() { 067 return Framework.getService(OAuth2ServiceProviderRegistry.class); 068 } 069 070 public boolean isAuthorized() { 071 return (credential != null && credential.getAccessToken() != null); 072 } 073 074 public YouTube getYouTube() throws IOException { 075 076 // if credential found with an access token, invoke the user code 077 if (youtube == null) { 078 youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, 079 credential).setApplicationName("nuxeo-media-publishing").build(); 080 } 081 return youtube; 082 } 083 084 public List<Video> getVideos() throws IOException { 085 return getYouTube().videos().list("snippet").execute().getItems(); 086 } 087 088 public List<Channel> getChannels() throws IOException { 089 return getYouTube().channels().list("snippet").setMine(true).execute().getItems(); 090 } 091 092 public List<PlaylistItem> getVideos(Channel channel) throws IOException { 093 String id = channel.getId(); 094 return getYouTube().playlistItems().list("snippet").setPlaylistId(id).execute().getItems(); 095 } 096 097 public Video upload(Video video, InputStream stream, String type, long length, 098 final MediaHttpUploaderProgressListener uploadListener) throws IOException { 099 100 InputStreamContent mediaContent = new InputStreamContent(type, stream); 101 mediaContent.setLength(length); 102 103 Insert insert = getYouTube().videos().insert("snippet,status", video, mediaContent); 104 105 // Set the upload type and add event listener. 106 MediaHttpUploader uploader = insert.getMediaHttpUploader(); 107 108 /* 109 * Sets whether direct media upload is enabled or disabled. True = whole 110 * media content is uploaded in a single request. False (default) = 111 * resumable media upload protocol to upload in data chunks. 112 */ 113 uploader.setDirectUploadEnabled(false); 114 115 uploader.setProgressListener(uploadListener); 116 117 // Execute upload. 118 Video returnedVideo = insert.execute(); 119 120 // Print out returned results. 121 if (returnedVideo != null) { 122 log.info("\n================== Returned Video ==================\n"); 123 log.info(" - Id: " + returnedVideo.getId()); 124 log.info(" - Title: " + returnedVideo.getSnippet().getTitle()); 125 log.info(" - Tags: " + returnedVideo.getSnippet().getTags()); 126 log.info(" - Privacy Status: " + returnedVideo.getStatus().getPrivacyStatus()); 127 } 128 129 return returnedVideo; 130 131 } 132 133 public void setPrivacyStatus(String videoId, String privacyStatus) throws IOException { 134 Video youtubeVideo = new Video(); 135 youtubeVideo.setId(videoId); 136 137 VideoStatus status = new VideoStatus(); 138 status.setPrivacyStatus(privacyStatus); 139 youtubeVideo.setStatus(status); 140 141 getYouTube().videos().update("status", youtubeVideo).execute(); 142 } 143 144 public boolean delete(String videoId) throws IOException { 145 Delete deleteRequest = getYouTube().videos().delete(videoId); 146 return deleteRequest.executeUnparsed().getStatusCode() == HttpStatusCodes.STATUS_CODE_NO_CONTENT; 147 } 148 149 public VideoStatistics getStatistics(String videoId) throws IOException { 150 VideoListResponse list = getYouTube().videos().list("statistics").setId(videoId).execute(); 151 152 if (list.isEmpty() || list.getItems().size() == 0) { 153 return null; 154 } 155 156 Video video = list.getItems().get(0); 157 return video.getStatistics(); 158 } 159}