问题描述
我正在尝试使用服务帐户委派设置youtube实时流API。我已经完成了在域上委派服务帐户的所有必要步骤。 我有一个用户拥有的YouTube频道,其电子邮件ID为该域名。频道拥有超过1万名订阅者,并且拥有直播视频的所有必要权限(我可以通过youtube studio直播)。 使用youtube Java API时,出现此错误:
{
"code" : 403,"errors" : [ {
"domain" : "youtube.livebroadcast","message" : "The user is blocked from live streaming.","reason" : "livePermissionBlocked","extendedHelp" : "https://support.google.com/youtube/answer/2853834"
} ],"message" : "The user is blocked from live streaming."
}
我附上我的代码以供参考
private static final Collection<String> ScopES =
Arrays.asList("https://www.googleapis.com/auth/youtube.force-ssl");
private static final String APPLICATION_NAME = "youtubeLive";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create an authorized Credential object.
*
* @return an authorized Credential object.
* @throws IOException
*/
public static Credential authorize(final NetHttpTransport httpTransport) throws IOException,GeneralSecurityException {
// Load client secrets.
InputStream in = new FileInputStream(CLIENT_SECRETS);
// GoogleClientSecrets clientSecrets =
// GoogleClientSecrets.load(JSON_FACTORY,new InputStreamReader(in));
// // Build flow and trigger user authorization request.
// GoogleAuthorizationCodeFlow flow =
// new GoogleAuthorizationCodeFlow.Builder(httpTransport,JSON_FACTORY,clientSecrets,ScopES)
// .build();
// Credential credential = new AuthorizationCodeInstalledApp(flow,null).authorize("user");
// GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(CLIENT_SECRETS))
// .createScoped(ScopES);
GoogleCredential credential = new GoogleCredential.Builder()
.setServiceAccountScopes(ScopES)
.setServiceAccountPrivateKeyFromP12File(new File("/Users/ashishjindal/Downloads/youtubelive-291213-be89f6b31144.p12"))
.setServiceAccountId("a******@youtubelive****.iam.gserviceaccount.com")
.setServiceAccountUser("USER@MY_DOMAIN.COM")
.setJsonFactory(JSON_FACTORY)
.setTransport(httpTransport)
.build();
return credential;
}
/**
* Build and return an authorized API client service.
*
* @return an authorized API client service
* @throws GeneralSecurityException,IOException
*/
public static YouTube getService() throws GeneralSecurityException,IOException {
final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
Credential credential = authorize(httpTransport);
return new YouTube.Builder(httpTransport,credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
@Scheduled(fixedDelay = 1000l)
public void test() throws IOException,GeneralSecurityException {
YouTube youtubeService = getService();
Livebroadcast livebroadcast = new Livebroadcast();
// Add the contentDetails object property to the Livebroadcast object.
LivebroadcastContentDetails contentDetails = new LivebroadcastContentDetails();
contentDetails.setEnableClosedCaptions(true);
contentDetails.setEnableContentEncryption(true);
contentDetails.setEnableDvr(true);
contentDetails.setEnableEmbed(true);
contentDetails.setEnableAutoStart(true);
contentDetails.setRecordFromStart(true);
contentDetails.setStartWithSlate(true);
livebroadcast.setContentDetails(contentDetails);
LivebroadcastSnippet snippet = new LivebroadcastSnippet();
snippet.setScheduledEndTime(new DateTime("2030-10-10T00:00:00"));
snippet.setScheduledStartTime(new DateTime("2029-10-10T00:00:00"));
snippet.setTitle("Test broadcast");
snippet.setChannelId("CHANNEL ID OWNED BY MY USER");
livebroadcast.setSnippet(snippet);
LivebroadcastStatus status = new LivebroadcastStatus();
status.setPrivacyStatus("unlisted");
livebroadcast.setStatus(status);
YouTube.Livebroadcasts.Insert request = youtubeService.livebroadcasts()
.insert("snippet,contentDetails,status",livebroadcast);
livebroadcast = request.execute();
System.out.println(response);
}
编辑:我已经确定了根本原因。我正在传递属于该用户进一步拥有的品牌帐户的频道ID。一个用户可以在youtube上拥有多个品牌帐户。现在,我的新问题是如何使用服务帐户模拟品牌帐户。 我发现了一些有用的线程:
Using Youtube Data API to Edit with Brand Account Playlist
解决方法
YouTube API不支持服务帐户(就像其他Google API一样)。
这里引用了官方API文档Move from ClientLogin to OAuth 2.0的Service Accounts do not work with the YouTube API部分(以下为我的重点):
服务帐户不适用于YouTube数据API调用,因为服务帐户需要关联的YouTube频道,并且您无法将新频道或现有频道与服务帐户相关联。如果您使用服务帐户调用YouTube数据API,则API服务器returns an error的错误类型设置为
unauthorized
,原因设置为youtubeSignupRequired
。
此外,这是从official docs的另一个地方提取的文本,再次说明了这一事实(以下重点也是我的意思):
如果您尝试使用OAuth 2.0服务帐户流,通常会看到此错误。 YouTube不支持服务帐户,如果您尝试使用服务帐户进行身份验证,则会收到此错误。
我从上面提取官方声明的上下文不包含在您上面的显示中。尽管如此,事实仍然存在。
这一次来自Live Streaming API docs本身的另一句话断言了上述事实(下面的重点也是我的):
服务帐户流支持不访问用户信息的服务器到服务器的交互。但是, YouTube Live Streaming API不支持此流程。由于无法将服务帐户链接到YouTube帐户,因此尝试使用此流程授权请求将产生
NoLinkedYouTubeAccount
错误。
因此,您必须确认您无法通过服务帐户使用YouTube的相应API发起直播。