web-dev-qa-db-fra.com

Transférer une vidéo sur Youtube à l'aide de Youtube API V3 et PHP

J'essaie de télécharger une vidéo sur Youtube en utilisant PHP. J'utilise Youtube API v3 et le dernier code source extrait de la bibliothèque client Google API PHP.
J'utilise l'exemple de code donné sur
https://code.google.com/p/google-api-php-client/ pour effectuer l'authentification. L'authentification se passe bien, mais lorsque j'essaie de télécharger une vidéo, je reçois Google_ServiceException avec le code d'erreur 500 et le message avec la valeur null. 

J'ai jeté un coup d'œil à la question suivante posée précédemment: Transférer une vidéo sur youtube à l'aide de la librairie client php v3 Mais la réponse acceptée ne décrit pas comment spécifier les données d'un fichier à téléverser.
J'ai trouvé une autre question similaire Envoi d'un fichier avec Youtube API v3 et PHP , où, dans le commentaire, il est mentionné que categoryId est obligatoire, c'est pourquoi j'ai essayé de définir le categoryId dans l'extrait, mais cela donne quand même la même exception.

J'ai également fait référence au code Python sur le site de documentation ( https://developers.google.com/youtube/v3/docs/videos/insert ), mais je n'ai pas trouvé la fonction next_chunk dans le client. bibliothèque. Mais j'ai essayé de mettre une boucle (mentionnée dans l'extrait de code) pour réessayer d'obtenir le code d'erreur 500, mais toutes les 10 itérations, je reçois la même erreur.

Voici l'extrait de code que j'essaie:

$youTubeService = new Google_YoutubeService($client);
if ($client->getAccessToken()) {
    print "Successfully authenticated";
    $snippet = new Google_VideoSnippet();
    $snippet->setTitle = "My Demo title";
    $snippet->setDescription = "My Demo descrition";
    $snippet->setTags = array("tag1","tag2");
    $snippet->setCategoryId(23); // this was added later after refering to another question on stackoverflow

    $status = new Google_VideoStatus();
    $status->privacyStatus = "private";

    $video = new Google_Video();
    $video->setSnippet($snippet);
    $video->setStatus($status);

    $data = file_get_contents("video.mp4"); // This file is present in the same directory as the code
    $mediaUpload = new Google_MediaFileUpload("video/mp4",$data);
    $error = true;
    $i = 0;

    // I added this loop because on the sample python code on the documentation page
    // mentions we should retry if we get error codes 500,502,503,504
    $retryErrorCodes = array(500, 502, 503, 504);
    while($i < 10 && $error) {
        try{
            $ret = $youTubeService->videos->insert("status,snippet", 
                                                   $video, 
                                                   array("data" => $data));

            // tried the following as well, but even this returns error code 500,
            // $ret = $youTubeService->videos->insert("status,snippet", 
            //                                        $video, 
            //                                        array("mediaUpload" => $mediaUpload); 
            $error = false;
        } catch(Google_ServiceException $e) {
            print "Caught Google service Exception ".$e->getCode()
                  . " message is ".$e->getMessage();
            if(!in_array($e->getCode(), $retryErrorCodes)){
                break;
            }
            $i++;
        }
    }
    print "Return value is ".print_r($ret,true);

    // We're not done yet. Remember to update the cached access token.
    // Remember to replace $_SESSION with a real database or memcached.
    $_SESSION['token'] = $client->getAccessToken();
} else {
    $authUrl = $client->createAuthUrl();
    print "<a href='$authUrl'>Connect Me!</a>";
}

Est-ce quelque chose que je fais mal? 

20
jayendrap

J'ai pu obtenir le téléchargement en utilisant le code suivant:

if($client->getAccessToken()) {
    $snippet = new Google_VideoSnippet();
    $snippet->setTitle("Test title");
    $snippet->setDescription("Test descrition");
    $snippet->setTags(array("tag1","tag2"));
    $snippet->setCategoryId("22");

    $status = new Google_VideoStatus();
    $status->privacyStatus = "private";

    $video = new Google_Video();
    $video->setSnippet($snippet);
    $video->setStatus($status);

    $error = true;
    $i = 0;

    try {
        $obj = $youTubeService->videos->insert("status,snippet", $video,
                                         array("data"=>file_get_contents("video.mp4"), 
                                        "mimeType" => "video/mp4"));
    } catch(Google_ServiceException $e) {
        print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage(). " <br>";
        print "Stack trace is ".$e->getTraceAsString();
    }
}
8
jayendrap

Je me rends compte que c'est vieux, mais voici la réponse de la documentation:

    // REPLACE this value with the path to the file you are uploading.
    $videoPath = "/path/to/file.mp4";

    $snippet = new Google_Service_YouTube_VideoSnippet();
    $snippet->setTitle("Test title");
    $snippet->setDescription("Test description");
    $snippet->setTags(array("tag1", "tag2"));

    // Numeric video category. See
    // https://developers.google.com/youtube/v3/docs/videoCategories/list 
    $snippet->setCategoryId("22");

    // Set the video's status to "public". Valid statuses are "public",
    // "private" and "unlisted".
    $status = new Google_Service_YouTube_VideoStatus();
    $status->privacyStatus = "public";

    // Associate the snippet and status objects with a new video resource.
    $video = new Google_Service_YouTube_Video();
    $video->setSnippet($snippet);
    $video->setStatus($status);

    // Specify the size of each chunk of data, in bytes. Set a higher value for
    // reliable connection as fewer chunks lead to faster uploads. Set a lower
    // value for better recovery on less reliable connections.
    $chunkSizeBytes = 1 * 1024 * 1024;

    // Setting the defer flag to true tells the client to return a request which can be called
    // with ->execute(); instead of making the API call immediately.
    $client->setDefer(true);

    // Create a request for the API's videos.insert method to create and upload the video.
    $insertRequest = $youtube->videos->insert("status,snippet", $video);

    // Create a MediaFileUpload object for resumable uploads.
    $media = new Google_Http_MediaFileUpload(
        $client,
        $insertRequest,
        'video/*',
        null,
        true,
        $chunkSizeBytes
    );
    $media->setFileSize(filesize($videoPath));


    // Read the media file and upload it chunk by chunk.
    $status = false;
    $handle = fopen($videoPath, "rb");
    while (!$status && !feof($handle)) {
      $chunk = fread($handle, $chunkSizeBytes);
      $status = $media->nextChunk($chunk);
    }

    fclose($handle);

    // If you want to make other calls after the file upload, set setDefer back to false
    $client->setDefer(false);
3
Any Day

Je réalise aussi que c'est vieux, mais comme j'ai cloné la dernière version de php-client de GitHub, je me suis heurté à un problème avec la méthode Google_Service_YouTube_Videos_Resource::insert()-. 

Je voudrais passer un tableau avec "data" => file_get_contents($pathToVideo) et "mimeType" => "video/mp4" défini comme argument pour la méthode insert()-, mais je continuais toujours à obtenir (400) BadRequest en retour.

Lors du débogage et de la lecture du code de Google trouvé dans \Google\Service\Resource.php, il y avait un contrôle (lignes 179-180) par rapport à une clé de tableau "uploadType" qui initierait l'objet Google_Http_MediaFielUpload.

$part = 'status,snippet';
$optParams = array(
    "data" => file_get_contents($filename),
    "uploadType" => "media",  // This was needed in my case
    "mimeType" => "video/mp4",
);
$response = $youtube->videos->insert($part, $video, $optParams);

Si je me souviens bien, avec la version 0.6 de PHP-api, l'argument uploadType n'était pas nécessaire. Cela pourrait ne s'appliquer que pour le style de téléchargement direct et non pour le téléchargement de pouvant être repris indiqué dans la réponse de Any Day.

2
Gemmu

La réponse serait d'utiliser Google_Http_MediaFileUpload via le Google PHP bibliothèques clientes .

Voici l'exemple de code: https://github.com/youtube/api-samples/blob/master/php/resumable_upload.php

0
Ibrahim Ulukaya