2015-11-23 14 views
28

Ich verwende die YouTube-API, um Videos Stück für Stück hochzuladen (siehe Code unten). Der Upload schlägt jedoch manchmal mit größeren Dateien (+ 1 GB) fehl, aber nicht immer. Der Upload wird als abgeschlossen angezeigt, aber nur ein paar Minuten können gespielt werden und der Rest wird abgeschnitten. Ich tat some research, aber ohne erkennbaren Erfolg. Meine Frage (n) jetzt:YouTube-API schneidet Videos ab [PHP]

  • Gibt es eine Möglichkeit, YouTube direkt zu kontaktieren (Protokolle zu sehen, was wirklich vor sich geht)?
  • Ist das ein Codierungsproblem?
  • Kann der Fehler über die API abgefangen/entdeckt werden (im Moment wird keine Ausnahme ausgelöst)
  • Kann dies passieren, wenn Sie verschiedene Videos auf einmal hochladen (parallel dazu)?
  • Hat jemand anderes dieses Problem festgestellt?

Jede Hilfe/Führung in die richtige Richtung wird sehr geschätzt. Ich würde sogar eine Prämie von 500 Punkten rufen, da dies mir wahnsinnig (genau das getan ...)

Anhang: Das Skript in einer Befehlszeile ausgeführt wird, durch einen Gearman Server, mit set_time_limit(0); Sets . Der Code/Funktion ist nur ein Auszug (und läuft super mit kleineren Dateien, manchmal sogar bis zu 10 GB).

EDIT: Nach aergistal der und GeorgeQ Kommentare von oben, ich habe die while-Schleife geändert Stücke direkt lesen (keine feof() mehr) und den Status in der Datenbank zu speichern.

/* 
    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; 
} 
+1

, wie Sie den Lauf werden: es ein YT-Server Problem

  • gelingt anzeigen würde, Skript? Über einen Browser oder eine Befehlszeile? – DaImTo

  • +0

    @DaImTo Befehlszeile, Gearman-Server. Ich habe die Frage geändert, um die zusätzlichen Informationen widerzuspiegeln. – Jan

    +1

    Als eine Randnotiz [Warum es schlecht ist, feof() zu verwenden, um eine Schleife zu steuern] (http://stackoverflow.com/questions/5431941/why-is-which-feof-file-always-wrong). Sie können sogar eine Endlosschleife erstellen, wenn der Dateizeiger aus irgendeinem Grund ungültig ist. – aergistal

    Antwort

    8

    Gibt es eine Möglichkeit, direkt YouTube zu kontaktieren (zu sehen Protokolle was los ist wirklich)?

    Nun, das ist eine unmögliche Mission. Sie müssen ihnen zahlreiche E-Mails senden, um (vielleicht) eine Antwort zu erhalten. Ich habe ein paar Mal versucht, aber keine Antwort von ihnen.

    Ist dies ein Problem mit der Codierung?

    Ja, das ist Kodierungsproblem. Wenn Sie versuchen, ein HD-Video hochzuladen, und wenn es abgeschnitten oder gekürzt wird, ist dies ein Problem mit der Codierung. YouTube hat sie regelmäßig.

    Kann der Fehler über die API gefangen/ermittelt werden (im Moment keine Ausnahme ausgelöst wird)

    Nein, es kann nicht. Sie müssen das Video beim Hochladen sehen, um einen Fehler zu sehen. Es gibt keine Ausnahme in der Mitte des Prozesses oder in irgendeinem Teil des Uploads.

    Kann dies passieren, wenn Sie verschiedene Videos auf einmal hochladen (in parallel, das ist)?

    Es spielt keine Rolle. Wenn Sie ein Video oder zwei, drei, fünf Videos gleichzeitig hochladen, spielt dies keine Rolle. Es ist nur ein Upload. Nur eine schlechte Sache, die im Prozess passieren könnte, ist ein Verbindungsverlust. Jedes Video geht in seine Richtung. Es ist wie wenn Sie mehrere Dateien von einem Ordner in einen anderen kopieren.

    Hat jemand anderes dieses Problem festgestellt?

    Ja. Du, ich und der ganze Haufen anderer Uploader. Es ist ein YouTube-Problem. Es ist ihr Bug oder irgendeine Kodierung/Wiedergabe/Transcodierung, egal welches Problem sie haben. Das liegt an den YouTube-Verarbeitungsoptionen.

    Wenn das passiert ist, war meine Lösung HTTPS/SSL zu verwenden, als ich das Video hochgeladen habe. Und es hat funktioniert. Es gab kein Problem beim Schneiden, Trimmen, Transcodieren oder Codieren/Rendern.

    +2

    Das riecht wie das Kopfgeld zu gewinnen :-) Gute und detaillierte Antwort. Wie kann ich Videos programmatisch hochladen, um sicherzustellen, dass HTTPS dann über das SDK verwendet wird? – Jan

    +1

    Konfigurieren Sie einfach das Zertifikat und es wird funktionieren. Hier ist ein guter Start für den Einstieg in den gleichen Korb mit SSL. -> http://developer.android.com/training/articles/security-ssl.html –

    2

    sieht aus wie das Skript Timeout ist. versuchen, diesen Code auf der ersten Zeile: set_time_limit(0);

    +1

    Nein, das habe ich schon festgelegt. Der obige Code ist nur ein Auszug. – Jan

    +0

    @Jan Ich denke, er wollte nur das Kopfgeld "stehlen" ;-) –

    +1

    @MarkusSafar: Aber nicht auf meiner Uhr ;-) Ehrlich, wenn es funktionierte, würde ich das Kopfgeld gerne verschenken, aber bis jetzt ist es es nicht leider nicht. – Jan

    2

    Der Upload wird als abgeschlossen angezeigt, es können jedoch nur ein paar Minuten gespielt werden und der Rest wird abgeschnitten. Ich habe etwas recherchiert, aber ohne erkennbaren Erfolg.

    Ist dies ein Problem mit der Codierung?

    Ok..you verwenden "gestückelt" Upload. Mit anderen Worten: Es ist ein "wiederaufnehmbarer" Upload wie in der YT Upload API beschrieben.

    Meine erste Schätzung: Es ist ein content-range Header Problem (von einer der Anfragen). Alle Teile müssen auf der YT-Serverseite byteweise perfekt ausgerichtet sein, sonst haben Sie nur den ersten Teil der Binärdatei. Referenzieren: Upload Chunks und bitte beachten Sie die blaue Box auf Content Range Header.

    Die google-api-php-client sollte dies richtig behandeln. Fehlerbehaftet könnte es aber alles Mögliche sein: API nicht synchron mit dem Client, cURL-Konfigurationsproblem, Header nicht gesetzt, Bereich nicht korrekt berechnet.

    Kann der Fehler über die API gefangen/ermittelt werden (im Moment wird keine Ausnahme ausgelöst)

    die Client-Debugging ist nicht Ihre Aufgabe. Man müsste GuzzleHttp\RequestOptions::DEBUG aktivieren um zu sehen, ob alle Header korrekt sind. Dann könnten Sie versuchen, den Status des Uploads parallel zum Upload selbst zu ziehen (zweite Anfrage).

    Gibt es eine Möglichkeit, YouTube direkt zu kontaktieren (Protokolle zu sehen, was wirklich vor sich geht)?

    Ja, Sie verwenden Google_Http_MediaFileUpload und das ist Teil von Google-API-PHP-client.

    nur eine Frage offen über an ihren Github Repo: https://github.com/google/google-api-php-client/issues


    Mein Vorschlag ist:

    • die PHP-Zwiebel verlassen PHP(ext_curl(libcurl))) + yourscript(google-api-client(guzzle)))
      • PHP Zwiebel bedeutet: Ihr Skript verwendet google-api-client, der guzzle verwendet, das php_ext_curl verwendet, das libc verwendet url intern
      • Sie mehrere Schichten und Fehler auf allen von ihnen
      • bottom-line passieren kann: Ermöglicht umgehen einfach den PHP-Stack für den Test von der CLI
    • versuchen, die gestückelt Upload-Ausgabe auf das zu reproduzieren CLI unter Verwendung cURL
    • verwenden, um eine zweite Konsole, um den Status des aktiven hochladen zwischen hochgeladen chunks
    • dann, falls das hochladen von CLI zum Anfordern
      • fehlschlägt: vergleichen Sie die Header aus dem CLI gegen den PHP-Skript (verputzen im Debug-Modus), um das Problem näher zu kommen
    +0

    Vielen Dank für diesen Blick. Allerdings verstehe ich nicht ganz, was Sie mit Ihrer ersten Option meinen (lassen Sie die PHP-Zwiebel) - was soll dieser Teil sagen? – Jan

    +0

    Ok, ich habe meine Antwort aktualisiert, um es ein wenig zu erklären. (boxcon ... cooles Projekt!) –

    Verwandte Themen