Ich arbeite an einer Android-App, die Videos aufzeichnet und es dem Nutzer ermöglicht, sie mithilfe des YouTube Data API v3 direkt auf YouTube hochzuladen.YouTube API 3 Video hochladen - Zugriff nicht konfiguriert - Android
Ich habe meine App in Google API-Konsole eingerichtet. Unter Dienste habe ich YouTube Data API v3 aktiviert. Unter API-Zugang habe ich sowohl einen Abschnitt "Client ID für installierte Anwendungen" (einschließlich einer Client ID und Client Secret) und einen Abschnitt "Simple API Access" -> "Schlüssel für Android Apps (mit Zertifikaten)" (welcher einen API Schlüssel enthält) und einen "Android Apps" Abschnitt, der vorerst leer bleibt, dh alle Android Apps zulassen, aber ich habe es mit der Einstellung meines Android-Schlüssels versucht).
Ich habe meinen Code aus einer Reihe von Orten basiert in erster Linie:
https://developers.google.com/youtube/v3/code_samples/java#upload_a_video
und
Der Upload OK initialisiert, beginnt die AsyncTask, aber dann bekomme ich eine IOException geworfen sagen:
{
"code": 403,
"errors": [
{
"domain": "usageLimits",
"message": "Access Not Configured",
"reason": "accessNotConfigured"
}
],
"message": "Access Not Configured"
}
Ähnliche SO-Beiträge deuten darauf hin, dass es mit meinen Google-API-Konsoleneinstellungen zu tun hat, aber ich kann nichts falsch finden. Irgendwelche Vorschläge? Ich frage mich, ob es daran liegt, dass ich meine Kundennummer oder mein Geheimnis nirgendwo hingebe ...
Danke.
Mein Code läuft von einem Fragment mit einer Liste von Videos. Die entsprechenden Abschnitte sind:
- Init
public class UploadFragment extends Fragment {
private static GoogleAccountCredential credential;
private static final HttpTransport transport = AndroidHttp.newCompatibleTransport();
private static final JsonFactory jsonFactory = new GsonFactory();
public YouTube youtube;
List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
private static String VIDEO_FILE_FORMAT = "video/*";
static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
static final int REQUEST_AUTHORIZATION = 1;
static final int REQUEST_ACCOUNT_PICKER = 2;
- Setup-Anmeldeinformationen und youtube
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
credential = googleAccountCredential(scopes);
youtube = new YouTube.Builder(transport, jsonFactory, credential)
.setApplicationName("MyAppName")
.build();
...
}
- Auf Schaltfläche klicken, starten Sie laden
@Override void onClick(View v) {
...
if (hasGooglePlayServices()) {
uploadYouTubeVideos();
...
}
- Bauen Berechtigungsnachweis
/**
* Get the credential to authorize the installed application to access user's protected data.
*
* @param scopes list of scopes needed to run YouTube upload.
*/
private static GoogleAccountCredential googleAccountCredential(List<String> scopes) throws Exception {
credential = GoogleAccountCredential.usingOAuth2(context, scopes)
.setSelectedAccountName(PreferenceManager.getAccountName());
return credential;
}
- ein Konto aus den
Benutzern anfordern/**
* Fire intent to get user to choose account
* Return to onActivityResult
*/
private void chooseAccount() {
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
- Bei der Rückkehr von dem Benutzer der Wahl und Konto -/anfordernden Genehmigung
/**
* Returns from chooseAccount and from request authorization
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
uploadYouTubeVideos();
} else {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
PreferenceManager.setAccountName(accountName);
uploadYouTubeVideos();
}
}
break;
}
}
- Called mehrmals je nachdem, was Informationen, die wir haben - Konto, Autorisierung usw.
/**
* Uploads user selected video to the user's YouTube account using OAuth2
* for authentication.
*
* @param videoFile file to be uploaded
*/
public void uploadYouTubeVideos() {
if (credential.getSelectedAccountName() == null) {
chooseAccount();
} else {
File videoFile = getVideoFile();
Insert videoInsert = prepareUpload(videoFile);
new VideoUploadAsyncTask().execute(videoInsert);
}
}
- Bereiten Sie den Upload - bringt alles zusammen
/**
* Prepare upload. Just leaves execute to be run in AsyncTask.
*
* @param videoFile file to be uploaded
* @return
*/
public Insert prepareUpload(File videoFile) {
try {
// Add extra information to the video before uploading.
Video videoObjectDefiningMetadata = new Video();
// Set the video to public (default).
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
// We set a majority of the metadata with the VideoSnippet object.
VideoSnippet snippet = new VideoSnippet();
// Video file name.
snippet.setTitle(videoFile.getName());
snippet.setDescription("Test description");
// Set keywords.
List<String> tags = new ArrayList<String>();
tags.add("test");
snippet.setTags(tags);
// Set completed snippet to the video object.
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent = new InputStreamContent(
VIDEO_FILE_FORMAT, new BufferedInputStream(new FileInputStream(videoFile)));
mediaContent.setLength(videoFile.length());
/*
* The upload command includes: 1. Information we want returned after file is successfully
* uploaded. 2. Metadata we want associated with the uploaded video. 3. Video file itself.
*/
YouTube.Videos.Insert videoInsert = youtube.videos()
.insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
// Set the upload type and add event listener.
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
/*
* Sets whether direct media upload is enabled or disabled. True = whole media content is
* uploaded in a single request. False (default) = resumable media upload protocol to upload
* in data chunks.
*/
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
Log.d(TAG, "Upload file: Initiation Started");
break;
case INITIATION_COMPLETE:
Log.d(TAG, "Upload file: Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
Log.d(TAG, "Upload file: Upload in progress");
Log.d(TAG, "Upload file: Upload percentage: " + uploader.getProgress());
break;
case MEDIA_COMPLETE:
Log.d(TAG, "Upload file: Upload Completed!");
break;
case NOT_STARTED:
Log.d(TAG, "Upload file: Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
return videoInsert;
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
return null;
}
}
- Erfordern Google-Dienste spielen
/**
* Pop up dialog requesting user to download Google Play Services.
* Returns to onActivityResult
*/
void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, getActivity(),
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
- AsyncTask die
auf dem Upload läuft ausführenpublic class VideoUploadAsyncTask extends AsyncTask<Insert, Void, Void> {
@Override
protected Void doInBackground(Insert... inserts) {
Insert videoInsert = inserts[0];
try {
Video returnVideo = videoInsert.execute();
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
showGooglePlayServicesAvailabilityErrorDialog(
availabilityException.getConnectionStatusCode());
} catch (UserRecoverableAuthIOException userRecoverableException) {
startActivityForResult(
userRecoverableException.getIntent(), UploadFragment.REQUEST_AUTHORIZATION);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
return null;
}
}
}
Die verwandten Fragen von SO wies mich auf https://github.com/youtube/ytd-android, ich werde einen genaueren Blick darauf haben, aber auf den ersten Blick scheint es, dass wir eine sehr ähnliche Methode verwenden . –
Hallo, können Sie den ganzen Code als Referenz posten? –
Ich bin verwirrt mit dem "Android API Key" auf der Projekthomepage geschrieben. Heißt das "Client ID für Android-Anwendung"? –