2012-04-10 14 views
5

में यूट्यूब के लिए S3 से एक वीडियो अपलोड किया जा रहा है और हो रही है मैं कुछ काम कर रहा है कि यूट्यूब पर एक वीडियो फ़ाइल ऊपर अपलोड करता है कोड है। हमारे एस 3 खाते में वीडियो सार्वजनिक है, इसलिए मैं wget जैसे कमांड का उपयोग कर सकता हूं। क्या मुझे एक ऐसा आदेश चलाया जाए जो वीडियो फ़ाइल को wgets और इस स्क्रिप्ट को चलाने से पहले इसे स्थानीय रूप से डाउनलोड करता है (shell_exec("wget ".$s3videoURL))?पीएचपी

या क्या मुझे MediaFileSource को S3 फ़ाइल के URL के रूप में दर्ज करने का प्रयास करना चाहिए?

मुख्य रूप से, मुझे केवल स्थिरता की आवश्यकता है (अक्सर समाधान समय-समय पर समाधान नहीं); गति और स्थानीय भंडारण वास्तव में महत्वपूर्ण नहीं है (अपलोड होने के बाद मैं स्थानीय रूप से वीडियो फ़ाइल को हटा सकता हूं)।

इस बारे में जाने का सबसे अच्छा तरीका क्या होगा?

धन्यवाद!

अद्यतन: मुझे शायद यह उल्लेख करना चाहिए कि यह स्क्रिप्ट YouTube पर निष्पादन के लिए लगभग 5 वीडियो अपलोड करने जा रही है।

उत्तर

7

यह एक पुराना सवाल है लेकिन मेरा मानना ​​है कि मेरे पास एक बेहतर जवाब है।

आपको एचडीडी में वीडियो लिखना नहीं है और आप पूरी चीज़ को रैम में नहीं रख सकते हैं (मुझे लगता है कि यह एक बड़ी फाइल है)।

आप एस 3 से फ़ाइल बफर करने के लिए PHP एडब्ल्यूएस एसडीके और Google क्लाइंट लाइब्रेरी का उपयोग कर सकते हैं और इसे फ्लाई पर YouTube पर भेज सकते हैं। S3 को फ़ाइल सिस्टम के रूप में पंजीकृत करने के लिए registerStreamWrapper विधि का उपयोग करें और YouTube API से पुन: प्रारंभ करने योग्य अपलोड का उपयोग करें। तो आपको बस इतना करना है कि एस 3 से भाग फेंकने और उन्हें यूट्यूब पर भेजना है। इस तरह आप राम उपयोग को सीमित भी कर सकते हैं।

मुझे लगता है कि आपने Google_Video क्लास से वीडियो ऑब्जेक्ट (कोड में $ वीडियो) बनाया है। यह एक पूरा कोड है।

<?php 
require_once 'path/to/libraries/aws/vendor/autoload.php'; 
require_once 'path/to/libraries/google-client-lib/autoload.php'; 

use Aws\S3\S3Client; 

$chunkSizeBytes = 2 * 1024 * 1024; // 2 mb 
$streamName = 's3://bucketname/video.mp4'; 

$s3client = S3Client::factory(array(
        'key' => S3_ACCESS_KEY, 
        'secret' => S3_SECRET_KEY, 
        'region' => 'eu-west-1' // if you need to set. 
       )); 
$s3client->registerStreamWrapper(); 

$client = new Google_Client(); 
$client->setClientId(YOUTUBE_CLIENT_ID); 
$client->setClientSecret(YOUTUBE_CLIENT_SECRET); 
$client->setAccessToken(YOUTUBE_TOKEN); 

$youtube = new Google_YoutubeService($client); 
$media = new Google_MediaFileUpload('video/*', null, true, $chunkSizeBytes); 

$filesize = filesize($streamName); // use it as a reguler file. 
$media->setFileSize($filesize); 

$insertResponse = $youtube->videos->insert("status,snippet", $video, array('mediaUpload' => $media)); 
$uploadStatus = false; 

$handle = fopen($streamName, "r"); 
$totalReceived = 0; 
$chunkBuffer = ''; 
while (!$uploadStatus && !feof($handle)) { 
    $chunk = fread($handle, $chunkSizeBytes); 
    $chunkBuffer .= $chunk; 
    $chunkBufferSize = strlen($chunkBuffer); 
    if($chunkBufferSize > $chunkSizeBytes) { 
     $fullChunk = substr($chunkBuffer, 0, $chunkSizeBytes); 
     $leapChunk = substr($chunkBuffer, $chunkSizeBytes); 
     $uploadStatus = $media->nextChunk($insertResponse, $fullChunk); 
     $totalSend += strlen($fullChunk); 

     $chunkBuffer = $leapChunk; 
     echo PHP_EOL.'Status: '.($totalReceived).'/'.$filesize.' (%'.(($totalReceived/$filesize) * 100).')'.PHP_EOL; 
    } 

    $totalReceived += strlen($chunk); 
} 

$extraChunkLen = strlen($chunkBuffer); 
$uploadStatus = $media->nextChunk($insertResponse, $chunkBuffer); 
$totalSend += strlen($chunkBuffer); 
fclose($handle); 
+0

धन्यवाद। आपने मेरा समय बचाया :)। – BCoder

+0

बस अगर किसी को इसे सरल बनाने की कोशिश करने वाले मुद्दों में भाग लिया गया है, तो आपको दूरदराज के स्थानों से PHP में फ़्रेड की सीमा के कारण खंड को बंक में जोड़ने की आवश्यकता है। php.net से: " चेतावनी नियमित रूप से स्थानीय फ़ाइल नहीं होने पर, जो दूरस्थ फ़ाइलों को पढ़ने या पॉपन() और fsockopen() से पढ़ने पर लौटाई गई धाराओं को पढ़ते समय, एक पैकेट उपलब्ध होने के बाद पढ़ना बंद हो जाएगा। इसका मतलब यह है कि आपको नीचे दिए गए उदाहरणों में दिखाए गए हिस्सों में डेटा एकत्र करना चाहिए। " – bertmaclin

2

"मीडियाफाइल स्रोत" एक वास्तविक फ़ाइल होना चाहिए। यह एक यूआरएल नहीं लेगा, इसलिए आपको यूट्यूब पर भेजने से पहले, एस 3 से वीडियो को अपने सर्वर पर कॉपी करने की आवश्यकता होगी।

यदि आपका उपयोग हल्का है, तो शायद आप "shell_exec" से दूर हो सकते हैं, लेकिन कई कारणों से एस 0 से फ़ाइलों को खींचने के लिए Zend S3 Service, या cURL का उपयोग करना संभवतः बेहतर है।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद, मैं इन विकल्पों का पता लगाने जा रहा हूं –

-1

$ chunkSizeBytes = 2 * 1024 * 1024; // 2 एमबी

$s3client = $this->c_aws->getS3Client(); 
    $s3client->registerStreamWrapper(); 

    try { 

     $client = new \Google_Client(); 

     $client->setAccessType("offline"); 
     $client->setApprovalPrompt('force'); 

     $client->setClientId(GOOGLE_CLIENT_ID); 
     $client->setClientSecret(GOOGLE_CLIENT_SECRET); 
     $token = $client->fetchAccessTokenWithRefreshToken(GOOGLE_REFRESH_TOKEN); 


     $client->setAccessToken($token); 

     $youtube = new \Google_Service_YouTube($client); 

     // 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($title); 
     $snippet->setDescription($summary); 
     $snippet->setTags(explode(',', $keywords)); 

     // Numeric video category. See 
     // https://developers.google.com/youtube/v3/docs/videoCategories/list 

// $ स्निपेट-> 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); 

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

     $insertRequest = $youtube->videos->insert("status,snippet", $video); 

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

     $result = $this->c_aws->getAwsFile($aws_file_path); 

     $media->setFileSize($result['ContentLength']); 

     $uploadStatus = false; 

     // Seek to the beginning of the stream 
     $result['Body']->rewind(); 

     // Read the body off of the underlying stream in chunks 
     while (!$uploadStatus && $data = $result['Body']->read($chunkSizeBytes)) { 

      $uploadStatus = $media->nextChunk($data); 

     } 
     $client->setDefer(false); 
     if ($uploadStatus->status['uploadStatus'] == 'uploaded') { 
      // Actions to perform for a successful upload 
      $uploaded_video_id = $uploadStatus['id']; 
      return ($uploadStatus['id']); 
     } 
    }catch (\Google_Service_Exception $exception){ 
     return ''; 
     print_r($exception); 
    }