1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.publication.youtube;
23
24 import org.opencastproject.publication.youtube.auth.ClientCredentials;
25 import org.opencastproject.publication.youtube.auth.OAuth2CredentialFactory;
26 import org.opencastproject.publication.youtube.auth.OAuth2CredentialFactoryImpl;
27 import org.opencastproject.util.data.Collections;
28
29 import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
30 import com.google.api.client.googleapis.media.MediaHttpUploader;
31 import com.google.api.client.http.InputStreamContent;
32 import com.google.api.client.http.javanet.NetHttpTransport;
33 import com.google.api.client.json.jackson2.JacksonFactory;
34 import com.google.api.services.youtube.YouTube;
35 import com.google.api.services.youtube.YouTubeRequest;
36 import com.google.api.services.youtube.model.Playlist;
37 import com.google.api.services.youtube.model.PlaylistItem;
38 import com.google.api.services.youtube.model.PlaylistItemListResponse;
39 import com.google.api.services.youtube.model.PlaylistItemSnippet;
40 import com.google.api.services.youtube.model.PlaylistListResponse;
41 import com.google.api.services.youtube.model.PlaylistSnippet;
42 import com.google.api.services.youtube.model.PlaylistStatus;
43 import com.google.api.services.youtube.model.ResourceId;
44 import com.google.api.services.youtube.model.SearchListResponse;
45 import com.google.api.services.youtube.model.Video;
46 import com.google.api.services.youtube.model.VideoListResponse;
47 import com.google.api.services.youtube.model.VideoSnippet;
48 import com.google.api.services.youtube.model.VideoStatus;
49
50 import org.apache.commons.lang3.ArrayUtils;
51
52 import java.io.BufferedInputStream;
53 import java.io.File;
54 import java.io.FileInputStream;
55 import java.io.IOException;
56 import java.util.LinkedList;
57 import java.util.List;
58
59 public class YouTubeAPIVersion3ServiceImpl implements YouTubeAPIVersion3Service {
60
61 private YouTube youTube;
62
63 @Override
64 public void initialize(final ClientCredentials credentials) throws IOException {
65 final OAuth2CredentialFactory factory = new OAuth2CredentialFactoryImpl();
66 final GoogleCredential credential = factory.getGoogleCredential(credentials);
67 youTube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), credential).build();
68 }
69
70 @Override
71 public Video addVideoToMyChannel(final VideoUpload videoUpload) throws IOException {
72 final Video videoObjectDefiningMetadata = new Video();
73 final VideoStatus status = new VideoStatus();
74 status.setPrivacyStatus(videoUpload.getPrivacyStatus());
75 videoObjectDefiningMetadata.setStatus(status);
76
77 final VideoSnippet snippet = new VideoSnippet();
78 snippet.setTitle(videoUpload.getTitle());
79 snippet.setDescription(videoUpload.getDescription());
80 final String[] tags = videoUpload.getTags();
81 if (ArrayUtils.isNotEmpty(tags)) {
82 snippet.setTags(Collections.list(tags));
83 }
84
85 videoObjectDefiningMetadata.setSnippet(snippet);
86
87 final File videoFile = videoUpload.getVideoFile();
88 final BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(videoFile));
89 final InputStreamContent mediaContent = new InputStreamContent("video/*", inputStream);
90 mediaContent.setLength(videoFile.length());
91
92 final YouTube.Videos.Insert videoInsert = youTube.videos()
93 .insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
94 final MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
95
96 uploader.setDirectUploadEnabled(false);
97 uploader.setProgressListener(videoUpload.getProgressListener());
98 return execute(videoInsert);
99 }
100
101 @Override
102 public Playlist createPlaylist(final String title, final String description, final String... tags)
103 throws IOException {
104 final PlaylistSnippet playlistSnippet = new PlaylistSnippet();
105 playlistSnippet.setTitle(title);
106 playlistSnippet.setDescription(description);
107 if (tags.length > 0) {
108 playlistSnippet.setTags(Collections.list(tags));
109 }
110
111 final PlaylistStatus playlistStatus = new PlaylistStatus();
112 playlistStatus.setPrivacyStatus("public");
113
114
115 final Playlist youTubePlaylist = new Playlist();
116 youTubePlaylist.setSnippet(playlistSnippet);
117 youTubePlaylist.setStatus(playlistStatus);
118
119
120 final YouTube.Playlists.Insert command = youTube.playlists().insert("snippet,status", youTubePlaylist);
121 return execute(command);
122 }
123
124 @Override
125 public PlaylistItem addPlaylistItem(final String playlistId, final String videoId) throws IOException {
126
127 final ResourceId resourceId = new ResourceId();
128 resourceId.setKind("youtube#video");
129 resourceId.setVideoId(videoId);
130
131
132 final PlaylistItemSnippet playlistItemSnippet = new PlaylistItemSnippet();
133 playlistItemSnippet.setTitle("First video in the test playlist");
134 playlistItemSnippet.setPlaylistId(playlistId);
135 playlistItemSnippet.setResourceId(resourceId);
136
137
138 final PlaylistItem playlistItem = new PlaylistItem();
139 playlistItem.setSnippet(playlistItemSnippet);
140
141
142 final YouTube.PlaylistItems.Insert playlistItemsInsertCommand
143 = youTube.playlistItems().insert("snippet,contentDetails", playlistItem);
144 return execute(playlistItemsInsertCommand);
145 }
146
147 @Override
148 public void removeVideoFromPlaylist(final String playlistId, final String videoId) throws IOException {
149 final PlaylistItem playlistItem = findPlaylistItem(playlistId, videoId);
150 final YouTube.PlaylistItems.Delete deleteRequest = youTube.playlistItems().delete(playlistItem.getId());
151 execute(deleteRequest);
152 }
153
154 @Override
155 public void removeMyVideo(final String videoId) throws Exception {
156 final YouTube.Videos.Delete deleteRequest = youTube.videos().delete(videoId);
157 execute(deleteRequest);
158 }
159
160 @Override
161 public void removeMyPlaylist(final String playlistId) throws IOException {
162 final YouTube.Playlists.Delete deleteRequest = youTube.playlists().delete(playlistId);
163 execute(deleteRequest);
164 }
165
166 @Override
167 public SearchListResponse searchMyVideos(final String queryTerm, final String pageToken, final long maxResults)
168 throws IOException {
169 final YouTube.Search.List search = youTube.search().list("id,snippet");
170 if (pageToken != null) {
171 search.set("pageToken", pageToken);
172 }
173 search.setQ(queryTerm);
174 search.setType("video");
175 search.setForMine(true);
176 search.setMaxResults(maxResults);
177 search.setFields("items(id,kind,snippet),nextPageToken,pageInfo,prevPageToken,tokenPagination");
178 return execute(search);
179 }
180
181 @Override
182 public Video getVideoById(final String videoId) throws IOException {
183 final YouTube.Videos.List search = youTube.videos().list("id,snippet");
184 search.setId(videoId);
185 search.setFields("items(id,kind,snippet),nextPageToken,pageInfo,prevPageToken,tokenPagination");
186 final VideoListResponse response = execute(search);
187 return response.getItems().isEmpty() ? null : response.getItems().get(0);
188 }
189
190 @Override
191 public Playlist getMyPlaylistByTitle(final String title) throws IOException {
192 final String trimmedTitle = title.trim();
193 boolean searchedAllPlaylist = false;
194 Playlist playlist = null;
195 String nextPageToken = null;
196 while (!searchedAllPlaylist) {
197 final PlaylistListResponse searchResult = getMyPlaylists(nextPageToken, 50);
198 for (final Playlist p : searchResult.getItems()) {
199 if (p.getSnippet().getTitle().trim().equals(trimmedTitle)) {
200 playlist = p;
201 break;
202 }
203 }
204 nextPageToken = searchResult.getNextPageToken();
205 searchedAllPlaylist = nextPageToken == null;
206 }
207 return playlist;
208 }
209
210 @Override
211 public PlaylistListResponse getMyPlaylists(final String pageToken, final long maxResults) throws IOException {
212 final YouTube.Playlists.List search = youTube.playlists().list("id,snippet");
213 if (pageToken != null) {
214 search.set("pageToken", pageToken);
215 }
216 search.setMaxResults(maxResults);
217 search.setMine(true);
218 search.setFields("items(id,snippet),kind,nextPageToken,pageInfo,prevPageToken,tokenPagination");
219 return execute(search);
220 }
221
222 @Override
223 public PlaylistItemListResponse getPlaylistItems(
224 final String playlistId,
225 final String pageToken,
226 final long maxResults
227 ) throws IOException {
228 final YouTube.PlaylistItems.List search = youTube.playlistItems().list("id,snippet");
229 search.setPlaylistId(playlistId);
230 search.setPageToken(pageToken);
231 search.setMaxResults(maxResults);
232 search.setFields("items(id,kind,snippet),nextPageToken,pageInfo,prevPageToken,tokenPagination");
233 return execute(search);
234 }
235
236
237
238
239
240
241
242 private PlaylistItem findPlaylistItem(final String playlistId, final String videoId) throws IOException {
243 final List<PlaylistItem> playlistItems = getAllPlaylistItems(playlistId);
244 PlaylistItem playlistItem = null;
245 for (final PlaylistItem next : playlistItems) {
246 final String id = next.getSnippet().getResourceId().getVideoId();
247 if (videoId.equals(id)) {
248 playlistItem = next;
249 break;
250 }
251 }
252 return playlistItem;
253 }
254
255
256
257
258
259
260
261 private List<PlaylistItem> getAllPlaylistItems(final String playlistId) throws IOException {
262 final List<PlaylistItem> playlistItems = new LinkedList<PlaylistItem>();
263 boolean done = false;
264 String nextPageToken = null;
265 while (!done) {
266 final PlaylistItemListResponse searchResult = getPlaylistItems(playlistId, nextPageToken, 50);
267 playlistItems.addAll(searchResult.getItems());
268 nextPageToken = searchResult.getNextPageToken();
269 done = nextPageToken == null;
270 }
271 return playlistItems;
272 }
273
274
275
276
277
278
279
280
281 private <T> T execute(final YouTubeRequest<T> command) throws IOException {
282 return command.execute();
283 }
284 }