Java 使用服务帐户时,如何在youtube/google帐户下上传视频文件

Java 使用服务帐户时,如何在youtube/google帐户下上传视频文件,java,youtube-api,google-oauth,Java,Youtube Api,Google Oauth,我希望创建一个服务器应用程序,检查所述服务器上的文件夹,并自动上传已放入所述文件夹的任何视频文件。服务器是远程的,不会发生人工交互 在阅读了Youtube的API v3指南后,我得出结论,我需要一个服务帐户来上传这些视频,因为应用程序会不断监视这个文件夹。我的问题是:是否有可能使用服务帐户上传视频,然后将视频放在我的个人youtube帐户下 如果事实上可能的话;我已经创建了以下代码,但是遇到了401未经授权的无效令牌错误 我有以下可编译的源代码;我已尝试使其尽可能小: package PACKA

我希望创建一个服务器应用程序,检查所述服务器上的文件夹,并自动上传已放入所述文件夹的任何视频文件。服务器是远程的,不会发生人工交互

在阅读了Youtube的API v3指南后,我得出结论,我需要一个服务帐户来上传这些视频,因为应用程序会不断监视这个文件夹。我的问题是:是否有可能使用服务帐户上传视频,然后将视频放在我的个人youtube帐户下

如果事实上可能的话;我已经创建了以下代码,但是遇到了401未经授权的无效令牌错误

我有以下可编译的源代码;我已尝试使其尽可能小:

package PACKAGE;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
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.youtube.YouTube;
import com.google.api.services.youtube.YouTubeScopes;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoSnippet;
import com.google.api.services.youtube.model.VideoStatus;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

public class BigQueryTestApp {

  private static final String VIDEO_FILE_FORMAT = "video/*";
  private static final String SAMPLE_VIDEO_FILENAME = "sample_video.mp4";
  public static void main(String[] args) throws IOException, InterruptedException, GeneralSecurityException {

    final HttpTransport TRANSPORT = new NetHttpTransport();
    final JsonFactory JSON_FACTORY = new JacksonFactory();
    File privateKeyFile = new File("privatekey.p12");

    GoogleCredential credential = new  GoogleCredential.Builder()
      .setTransport(TRANSPORT)
      .setJsonFactory(JSON_FACTORY)
      .setServiceAccountId("XXXX@developer.gserviceaccount.com")
      .setServiceAccountScopes(YouTubeScopes.all())
      .setServiceAccountPrivateKeyFromP12File(privateKeyFile)
      .build();


    try
    {

      YouTube youtube = new YouTube.Builder(TRANSPORT, JSON_FACTORY, credential).setApplicationName("CHANGE_IT").build();
      Video videoObjectDefiningMetadata = new Video();

      VideoStatus status = new VideoStatus();
      status.setPrivacyStatus("unlisted");
      videoObjectDefiningMetadata.setStatus(status);

      VideoSnippet snippet = new VideoSnippet();

      Calendar cal = Calendar.getInstance();
      snippet.setTitle("Test Upload via Java on " + cal.getTime());
      snippet.setDescription(
              "Video uploaded via YouTube Data API V3 using the Java library " + "on " + cal.getTime());

      List<String> tags = new ArrayList<String>();
      tags.add("test");
      tags.add("example");
      tags.add("java");
      tags.add("YouTube Data API V3");
      tags.add("erase me");
      snippet.setTags(tags);

      videoObjectDefiningMetadata.setSnippet(snippet);

      InputStreamContent mediaContent = new InputStreamContent(VIDEO_FILE_FORMAT,
              BigQueryTestApp.class.getResourceAsStream(SAMPLE_VIDEO_FILENAME));
      YouTube.Videos.Insert videoInsert = youtube.videos().insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
      MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();//thumbnailSet.getMediaHttpUploader();
      uploader.setDirectUploadEnabled(false);

      MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {

          public void progressChanged(MediaHttpUploader uploader) throws IOException
          {
              switch (uploader.getUploadState())
              {
                  case INITIATION_STARTED:
                      System.out.println("Initiation Started");
                      break;
                  case INITIATION_COMPLETE:
                      System.out.println("Initiation Completed");
                      break;
                  case MEDIA_IN_PROGRESS:
                      System.out.println("Upload in progress");
                      System.out.println("Upload percentage: " + uploader.getProgress());
                      break;
                  case MEDIA_COMPLETE:
                      System.out.println("Upload Completed!");
                      break;
                  case NOT_STARTED:
                      System.out.println("Upload Not Started!");
                      break;
              }
          }
      };
      uploader.setProgressListener(progressListener);

      // Call the API and upload the video.
      Video returnedVideo = videoInsert.execute();

            // Print data about the newly inserted video from the API response.
            System.out.println("\n================== Returned Video ==================\n");
            System.out.println("  - Id: " + returnedVideo.getId());
            System.out.println("  - Title: " + returnedVideo.getSnippet().getTitle());
            System.out.println("  - Tags: " + returnedVideo.getSnippet().getTags());
            System.out.println("  - Privacy Status: " + returnedVideo.getStatus().getPrivacyStatus());
            System.out.println("  - Video Count: " + returnedVideo.getStatistics().getViewCount());       
    }
    catch (GoogleJsonResponseException e) {

            System.out.println(e.getMessage());
            System.out.println("Headers: "+e.getHeaders().toString());
    }

最后,我读了关于服务账户的各种故事。一些人说它们与Youtube兼容,另一些人说它们与Youtube不兼容。这让我感到困惑,我发现了更多关于stackoverflow的问题,这些问题并没有明确说明这是否可能

YouTube不支持服务帐户,他们也没有计划:

那么,您可以选择将应用程序设置为执行初始oAuth流,您可以通过用户交互一次性启动该流,然后作为该流的一部分,您将获得一个临时访问令牌和一个刷新令牌。刷新令牌可用于获取更多访问令牌,而无需再次运行oAuth流,而且刷新令牌本身不会过期,但可以手动撤销。因此,你的应用程序可以存储你的刷新令牌,监视你的文件夹,然后在需要上传新视频时自行获取访问令牌。请参阅此链接:

注意,它特别提到了一个守护进程的概念,该守护进程监视一个目录,以便上传新的视频