使用PHP通过YouTube API上传时,视频文件停留在0%

时间:2015-10-12 16:20:49

标签: php api video google-api youtube-api

我尝试使用该实施工具将视频从here上传到我的频道:

但我陷入了一个非常具体的问题: 收到我的视频上传消息后,在我的YouTube帐户的视频管理器页面中,我看到了该视频,但下面的状态消息是" 0%已上传"它就像这样。

另外,我必须在第22行对代码进行更改:

$media = new Google_Http_MediaFileUpload(
$client,
$insertRequest,
'video/*',
file_get_contents($videoPath),
true,
$chunkSizeBytes
);

在此之前,使用原始代码,我收到了消息"准备上传。" (也是这样的)。

我知道存在类似的问题here。阅读之后我尝试将chunkSizeBytes设置得更低,甚至将其设置为null(在API中,在src / Google / Http / MediaFileUpload.php:88中,如果没有设置值,则分配一个)。

以下是我连接到API的代码:

<?php
header("Access-Control-Allow-Origin: *");
header( 'Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE' );
header( 'Access-Control-Allow-Headers: *' );
session_start();
// Call set_include_path() as needed to point to your client library.
require_once 'google_api_test/src/Google/Client.php';
require_once 'google_api_test/src/Google/Service/YouTube.php';

$OAUTH2_CLIENT_ID = 'my_client_id.apps.googleusercontent.com';
$OAUTH2_CLIENT_SECRET = 'my_client_secret';

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
//redirect to the same page
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST']."/youtube-sink",
    FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);

// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

if (isset($_GET['code'])) {

    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    //I commented this line because it kept posting the video twice
    //header('Location: ' . $redirect);

}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
    try{
        // REPLACE this value with the path to the file you are uploading.
        $videoPath = "videos" . DIRECTORY_SEPARATOR . $videoName;

        // 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("Test for Investing.com");
        $snippet->setDescription("This is our new video");
        $snippet->setTags(array("Investing.com", "PHP", "oauth"));

        // Numeric video category.    
        $snippet->setCategoryId("22"); //category - foreign

        $status = new Google_Service_YouTube_VideoStatus();
        $status->privacyStatus = "public"; //public,private or unlisted

        // 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 = 0.5 * 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/*',
            file_get_contents($videoPath),
            true,
            $chunkSizeBytes
        );    

        // 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);
        }

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

        $htmlBody = "<h1 class='alert alert-success text-center'>Video $videoName Uploaded</h3><ul>";
        //destroying the session to prevent users from reuploading the video if they refresh or go back
       session_destroy();
        fclose($handle);
    } catch (Google_ServiceException $e) {
        $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
            htmlspecialchars($e->getMessage()));
    } catch (Google_Exception $e) {
        $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
            htmlspecialchars($e->getMessage()));
    }

    $_SESSION['token'] = $client->getAccessToken();
} else {
    // If the user hasn't authorized the app, initiate the OAuth flow

    $authUrl = $client->createAuthUrl();
    $htmlBody = <<<END
    <div class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">Authorization Required</h4>
      </div>
      <div class="modal-body">
        <p>You need to login to Youtube in order to upload that video.</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <a href="$authUrl" class="btn btn-primary">Proceed</a>
      </div>
    </div>
  </div>
</div>

END;
}    
?>

<?=$htmlBody?>

1 个答案:

答案 0 :(得分:0)

我发现导致上传问题的问题是什么。错误原因是在服务器配置中。我需要更改以下内容:

应该设置.htaccess

<IfModule mod_php5.c>
php_value output_buffering Off
</IfModule>

Google YouTube API upload example所示,脚本以块的形式发送视频。这必须在脚本执行期间完成,而不是在脚本完成处理(output buffering = on)

之后完成

More info on output buffering