问题
I am trying to setup youtube live streaming APIs using service account delegation. I have done all the necessary steps for service account delegation on my domain. I have a youtube channel owned by a user with email id of this domain name. Channel has more than 10k subscribers and has all the necessary permissions to live stream (I can live stream via youtube studio). While using youtube java APIs, i am getting this error :
{
"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."
}
I am attaching my code for reference
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, JSON_FACTORY, 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);
}
EDIT : I have identified the root cause. I was passing the channel Id which belonged to a brand account which is further owned by this user. A user can have multiple brand accounts on youtube. Now my new issue is how to impersonate brand account using service-account. Some useful threads I found :
YouTube API and brand account
Using Youtube Data API to Edit with Brand Account Playlist
回答1:
The YouTube APIs does not support service accounts (as other Google APIs do).
Here is quote from the official API doc Move from ClientLogin to OAuth 2.0, the section Service Accounts do not work with the YouTube API (the emphasis below is mine):
Service accounts do not work for YouTube Data API calls because service accounts require an associated YouTube channel, and you cannot associate new or existing channels with service accounts. If you use a service account to call the YouTube Data API, the API server returns an error with the error type set to
unauthorized
and the reason set toyoutubeSignupRequired
.
Moreover, here is a text extracted from another place of the official docs that states that fact once more (the emphasis below is also mine):
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.
The context from which I extracted the above official statement is not subsumed to that you've shown above. Nonetheless, the fact remains.
Yet another quote asserting the above mentioned fact, this time from the Live Streaming API docs themselves (the emphasis below is mine too):
The service account flow supports server-to-server interactions that do not access user information. However, the YouTube Live Streaming API does not support this flow. Since there is no way to link a Service Account to a YouTube account, attempts to authorize requests with this flow will generate a
NoLinkedYouTubeAccount
error.
Consequently, you have to acknowledge that you cannot initiate a live broadcast using YouTube's corresponding APIs by means of a service account.
来源:https://stackoverflow.com/questions/64387915/youtube-live-streaming-api-giving-livepermissionblocked-error