27 votes

API YouTube tronque les vidéos [PHP]

Je suis à l'aide de l'API YouTube pour télécharger des vidéos morceau par morceau (voir le code ci-dessous). Cependant, le téléchargement échoue parfois avec de gros fichiers (+1 GO), mais pas toujours. Le téléchargement est montré pour être complète, mais seulement un couple de minutes peut être joué et le reste est tronqué. J'ai fait quelques recherches mais sans succès apparent. Ma question(s) aujourd'hui:

  • Est-il possible de contacter directement dans YouTube (voir les journaux de ce qui se passe réellement)?
  • Est-ce une problème de codage?
  • Peut l'erreur d'être pris ou détectés via l'API (à l'heure actuelle, aucune exception n'est levée)
  • Cela peut-il se passer si vous êtes le téléchargement de vidéos différentes à la fois (en parallèle, qui est) ?
  • Quelqu'un d'autre a rencontré ce problème?

Toute aide/conduire dans la bonne direction est beaucoup apprécié. J'irais même jusqu'à appeler un bounty de 500 points c'est me rend fou (fait juste que...)

Annexe: Le script est exécuté en ligne de commande, par le biais d'un Gearman Serveur, avec set_time_limit(0); ensemble. Le code de la fonction/est juste un extrait (et fonctionne très bien avec des fichiers plus petits, parfois même jusqu'à 10 GO).

EDIT: Selon aergistal et GeorgeQ les commentaires ci-dessus, j'ai changé la boucle while pour lire des morceaux directement (pas de feof() plus) et enregistrer l'état de la base de données.

/*
    Uploads one file to youtube chunk by chunk
*/
function uploadFile($dbfile) {
    $client = $this->client;
    $youtube = new Google_Service_YouTube($client);
    $htmlBody = "";

    try {
        // Create a snippet with title, description, tags and category ID
        // Create an asset resource and set its snippet metadata and type.
        // This example sets the video's title, description, keyword tags, and
        // video category.
        $snippet = new Google_Service_YouTube_VideoSnippet();
        $snippet->setTitle("SO Example");

        // 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 = "private";

        // 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($dbfile->localfile));

        // Read the media file and upload it chunk by chunk.
        $status = false;
        $handle = fopen($dbfile->localfile, "rb");

        while (!$status && ($chunk = (fread($handle, $chunkSizeBytes))) !== FALSE) { 
            $status = $media->nextChunk($chunk);
            $data = array("filename" => $dbfile->localfile, "status" => print_r($status, true));
            $db->saveLog($data);
        }

        /* the old code
        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);

        $log = array("success" => true, "snippet_id" => $status["id"]);
    } catch (Google_ServiceException $e) {
        $log = array("success" => false, "errormsg" => $e->getMessage());
    } catch (Google_Exception $e) {
        $log = array("success" => false, "errormsg" => $e->getMessage());
    }

    return $log;
}

8voto

Josip Ivic Points 1785

Est-il possible de contacter directement dans YouTube (voir les journaux de l' ce qui se passe réellement)?

Eh bien, c'est une mission impossible. Vous avez besoin d'envoyer de nombreux mails de (peut-être) obtenir une réponse. J'ai essayé quelques fois, mais aucune réponse de leur part.

Est-ce une problème de codage?

Oui, c'est le problème de codage. Si vous essayez de charger une vidéo HD, et si il se tronquée ou raccourcie ou que ce soit, c'est un problème de codage. YouTube a périodiquement.

Peut l'erreur d'être pris ou détectés via l'API (à l'heure actuelle, aucune exception est levée)

Non, il ne le peut pas. Vous avez besoin de voir la vidéo quand il est transféré à voir une erreur. Il n'y a aucune exception dans le milieu du processus, ou dans toute partie du chargement.

Cela peut-il se passer si vous êtes le téléchargement de vidéos différentes à la fois (dans en parallèle, qui est)?

Il n'a pas d'importance. Si vous téléchargez une vidéo ou deux, trois, cinq vidéos en même temps, il ne sera pas question. C'est juste un téléchargement. Que de mauvaise chose qui pourrait se produire dans des processus est une perte de connexion. Chaque vidéo va à sa propre direction. C'est comme lors de la copie de plusieurs fichiers d'un dossier à un autre.

Quelqu'un d'autre a rencontré ce problème?

Oui. Vous, moi, et des tas d'autres uploaders. C'est un YouTube problème. C'est leur bug ou d'encodage / rendu / transcodage, quel que soit le problème qu'ils ont. C'est à cause de YouTube, les options de traitement.

Quand ça m'est arrivé, ma solution a été d'utiliser le protocole HTTPS/SSL lorsque j'ai téléchargé la vidéo. Et cela a fonctionné. Il n'y a pas de coupe, le parage, le transcodage ni de l'encodage / problème de rendu.

2voto

rain Points 235

ressemble le script est en timeout. essayez ce code sur la première ligne: set_time_limit(0);

2voto

Jens-André Koch Points 3506

Le téléchargement est montré pour être complète, mais seulement un couple de minutes peut être joué et le reste est tronqué. J'ai fait quelques recherches mais sans succès apparent.

Est-ce une problème de codage?

Ok..vous êtes à l'aide de "chunked" le téléchargement. En d'autres mots: c'est une "reprise" télécharger comme décrit dans le YT Téléchargement de l'API.

Ma première hypothèse: c'est un content-range - tête question (d'une demande). Toutes les pièces ont pour aligner parfaitement octet-sage sur le YT côté serveur, sinon vous allez vous retrouver avec seulement la première partie de la binaire. Référencement: Télécharger des Morceaux et s'il vous plaît noter la zone bleue sur la Plage d'en-Tête.

L' google-api-php-client doit gérer cela correctement. Mais bug-sage, il pourrait être n'importe quoi: API de synchronisation avec le client, cURL problème de configuration de l'en-tête n'est pas défini, la gamme n'est pas correctement calculé.

Peut l'erreur d'être pris ou détectés via l'API (à l'heure actuelle, aucune exception n'est levée)

De débogage, le client n'est pas votre travail. On aurait pour activer GuzzleHttp\RequestOptions::DEBUG pour voir, si tous les en-têtes sont corrects. Ensuite, vous pouvez essayer de tirer le statut de l'upload en parallèle pour le téléchargement lui-même (deuxième bouffer demande).

Est-il possible de contacter directement dans YouTube (voir les journaux de ce qui se passe réellement)?

Oui, vous êtes à l'aide de Google_Http_MediaFileUpload et c'est en partie Google-API-PHP-client.

Il suffit d'ouvrir une question de plus à leur dépôt Github: https://github.com/google/google-api-php-client/issues


Ma suggestion est:

  • laissez le PHP oignon PHP(ext_curl(libcurl))) + yourscript(google-api-client(guzzle)))
    • PHP oignon signifie: votre script utilise google-api-client, qui utilise bouffer, qui utilise php_ext_curl, qui utilise libcurl en interne
    • vous avez plusieurs couches et des erreurs peuvent se produire à tous
    • bas de ligne: permet de simplement ignorer la pile PHP pour le test de la CLI
  • essayez de reproduire le bloc de téléchargement question sur la CLI à l'aide de cURL
  • l'utilisation d'une deuxième console pour demander l'état de l'actif télécharger entre les morceaux téléchargés
  • ensuite, dans le cas où le télécharger à partir de la CLI
    • échoue: il indique un YT problème de serveur
    • réussit: comparer les en-têtes de la CLI contre le script PHP (bouffer en mode debug) pour se rapprocher du problème

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X