유튜브 Service Account 인증방식으로 업로드 API 사용 질문

302 views
Skip to first unread message

편현장

unread,
Aug 26, 2013, 2:29:23 AM8/26/13
to ks...@googlegroups.com
스프링 질문은 아니지만, 강력한 자바 유저들이 모여있는 관계로 여기에 올려봅니다.

Google Data API 3.0 을 이용해서 유튜브에 동영상을 올리려고 합니다.
인증방식은 Service Account 방식으로 하려고 하는데 인증이 필요한 API 를 콜하면 401 Unauthorized 오류가 나더란 말입니다.

{
  "code" : 401,
  "errors" : [ {
    "domain" : "youtube.header",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Unauthorized",
    "reason" : "youtubeSignupRequired"
  } ],
  "message" : "Unauthorized"
}

그런데 https://developers.google.com/youtube/v3/docs/errors?hl=ko 에 에러 코드 정의된 페이지를 보니깐

This error is commonly seen if you try to use the OAuth 2.0 Service Account flow. YouTube does not support Service Accounts, and if you attempt to authenticate using a Service Account, you will get this error.

라고 "지원안합니다." 라고 명백히 되어있더군요. 그러면 도대체 API 는 왜 있는걸까? 의구심이 들어서 자애스런 자바님들께 다음과 같은 케이스로 사용 경험이 있는지, 아니면 어떻게 해결하셨는지 여쭤봅니다.
  • Google Data API 3.0
  • Service Account 인증
  • 인증이 필요한 API 호출 (playlist, insert, ... )

다음은 작성해놓은 소스입니다.

+===================================================================================+

public class YoutubeService {

    /** Email of the Service Account */
    private static final String SERVICE_ACCOUNT_EMAIL = "443008...@developer.gserviceaccount.com";

   
    /* Global instance of the format used for the video being uploaded (MIME type). */
    private static String VIDEO_FILE_FORMAT = "video/*";

    /**
     * Build and returns a Drive service object authorized with the service accounts.
     *
     * @return Drive service object that is ready to make requests.
     */
    public static YouTube getYoutubeService(File privateKeyFile) throws GeneralSecurityException,
            IOException, URISyntaxException {
        HttpTransport httpTransport = new NetHttpTransport();
        JacksonFactory jsonFactory = new JacksonFactory();

        List<String> scopes = new ArrayList<String>();
        scopes.add("https://www.googleapis.com/auth/youtube");
        scopes.add("https://www.googleapis.com/auth/youtube.upload");

        GoogleCredential.Builder builder = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                // .setServiceAccountScopes(YouTubeScopes.all())
                // .setServiceAccountScopes(Collections.singleton(YouTubeScopes.YOUTUBE))
                .setServiceAccountScopes(scopes)
                .setServiceAccountPrivateKeyFromP12File(privateKeyFile);
        GoogleCredential credential = builder.build();

        YouTube service = new YouTube.Builder(httpTransport, jsonFactory, null)
                .setHttpRequestInitializer(credential).build();
        return service;
    }

 
    public static void getPlayList(YouTube youtube) {
        try {
        /*
       * Now that the user is authenticated, the app makes a channel list request to get the
       * authenticated user's channel. Returned with that data is the playlist id for the uploaded
       * videos. https://developers.google.com/youtube/v3/docs/channels/list
       */
            YouTube.Channels.List channelRequest = youtube.channels().list("contentDetails");
            channelRequest.setMine(true);
      /*
       * Limits the results to only the data we needo which makes things more efficient.
       */
            channelRequest.setFields("items/contentDetails,nextPageToken,pageInfo");
            ChannelListResponse channelResult = channelRequest.execute();

      /*
       * Gets the list of channels associated with the user. This sample only pulls the uploaded
       * videos for the first channel (default channel for user).
       */
            List<Channel> channelsList = channelResult.getItems();

            if (channelsList != null) {
                // Gets user's default channel id (first channel in list).
                String uploadPlaylistId =
                        channelsList.get(0).getContentDetails().getRelatedPlaylists().getUploads();

                // List to store all PlaylistItem items associated with the uploadPlaylistId.
                List<PlaylistItem> playlistItemList = new ArrayList<PlaylistItem>();

        /*
         * Now that we have the playlist id for your uploads, we will request the playlistItems
         * associated with that playlist id, so we can get information on each video uploaded. This
         * is the template for the list call. We call it multiple times in the do while loop below
         * (only changing the nextToken to get all the videos).
         * https://developers.google.com/youtube/v3/docs/playlistitems/list
         */
                YouTube.PlaylistItems.List playlistItemRequest =
                        youtube.playlistItems().list("id,contentDetails,snippet");
                playlistItemRequest.setPlaylistId(uploadPlaylistId);

                // This limits the results to only the data we need and makes things more efficient.
                playlistItemRequest.setFields(
                        "items(contentDetails/videoId,snippet/title,snippet/publishedAt),nextPageToken,pageInfo");

                String nextToken = "";

                // Loops over all search page results returned for the uploadPlaylistId.
                do {
                    playlistItemRequest.setPageToken(nextToken);
                    PlaylistItemListResponse playlistItemResult = playlistItemRequest.execute();

                    playlistItemList.addAll(playlistItemResult.getItems());

                    nextToken = playlistItemResult.getNextPageToken();
                } while (nextToken != null);

                // Prints results.
                prettyPrint(playlistItemList.size(), playlistItemList.iterator());
            }

        } catch (GoogleJsonResponseException e) {
            e.printStackTrace();
            System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
                    + e.getDetails().getMessage());

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /*
   * Method that prints all the PlaylistItems in an Iterator.
   *
   * @param size size of list
   *
   * @param iterator of Playlist Items from uploaded Playlist
   */
    private static void prettyPrint(int size, Iterator<PlaylistItem> playlistEntries) {
        System.out.println("=============================================================");
        System.out.println("\t\tTotal Videos Uploaded: " + size);
        System.out.println("=============================================================\n");

        while (playlistEntries.hasNext()) {
            PlaylistItem playlistItem = playlistEntries.next();
            System.out.println(" video name  = " + playlistItem.getSnippet().getTitle());
            System.out.println(" video id    = " + playlistItem.getContentDetails().getVideoId());
            System.out.println(" upload date = " + playlistItem.getSnippet().getPublishedAt());
            System.out.println("\n-------------------------------------------------------------\n");
        }
    }
}

+===================================================================================+
Reply all
Reply to author
Forward
0 new messages