1

YouTube と Vimeo の両方に同時にアップロードできるフォームを設定しようとしています。私はこのような目的で Posterous.com を使用したいと思っていますが、Twitter に買収されて以来、彼らのヘルプ チームは地球上から姿を消してしまいました。 )...

とにかく、これがYouTubeプロセスがどのように機能するはずなのかです:

  1. ウェブフォームからアップロードする動画のタイトルとカテゴリを設定します
  2. フォームを送信し、YouTube からアクセス トークンを取得します
  3. 別のフォームが生成され、アップロードするファイルを選択できるようになります
  4. フォームを送信すると、アクセス トークンとファイルが送信され、YouTube が動画をアップロードします

私がやろうとしているのは、ドラッグ アンド ドロップ アップローダを使用して、これを 1 つのステップに変えることです。

  1. ファイルをページにドラッグ アンド ドロップ
  2. javascript はファイル情報を取得し、ファイル名をビデオ タイトルとして設定し、デフォルトのカテゴリを使用します。
  3. javascript は php を呼び出し、ファイル名とカテゴリを youtube に送信し、アクセス トークンを取得して、ファイル入力でフォームを作成します
  4. トークンを取得したら、セッション変数に保存されたファイルのアップロードを含む POST (PHP 経由) リクエストを送信します (今は、ファイルをもう一度選択して [送信] をクリックする必要があります)。

最初のステップのファイル情報を使用して、それをセッション変数に保存し、php 経由でトークンとファイル情報をプログラムで送信することはできませんか? フォーム送信として送信されたように、このデータを送信する方法がわかりません。コードを修正するために、YouTube から常に応答コードが返されるとは限りません。

これは私が必要とする答えかもしれません: curl経由でxmlとヘッダーを送信$xmlStringしますが、またはを設定する方法がわかりません$videoData

編集::

次のコードを変更しようとしているので、javascript ではなく PHP でこれを行う必要があると思います。

/**
 * Create upload form by sending the incoming video meta-data to youtube and
 * retrieving a new entry. Prints form HTML to page.
 *
 * @param string $VideoTitle The title for the video entry.
 * @param string $VideoDescription The description for the video entry.
 * @param string $VideoCategory The category for the video entry.
 * @param string $nextUrl (optional) The URL to redirect back to after form upload has completed.
 * @return void
 */

function createUploadForm($videoTitle, $videoCategory, $nextUrl = null) {
$httpClient = getAuthSubHttpClient();
$youTubeService = new Zend_Gdata_YouTube($httpClient);
$newVideoEntry = new Zend_Gdata_YouTube_VideoEntry();

$newVideoEntry->setVideoTitle($videoTitle);

//make sure first character in category is capitalized
$videoCategory = strtoupper(substr($videoCategory, 0, 1))
    . substr($videoCategory, 1);
$newVideoEntry->setVideoCategory($videoCategory);

// convert videoTags from whitespace separated into comma separated

$tokenHandlerUrl = 'https://gdata.youtube.com/action/GetUploadToken';
try {
    $tokenArray = $youTubeService->getFormUploadToken($newVideoEntry, $tokenHandlerUrl);
    if (loggingEnabled()) {
        logMessage($httpClient->getLastRequest(), 'request');
        logMessage($httpClient->getLastResponse()->getBody(), 'response');
    }
} catch (Zend_Gdata_App_HttpException $httpException) {
    print 'ERROR ' . $httpException->getMessage()
        . ' HTTP details<br /><textarea cols="100" rows="20">'
        . $httpException->getRawResponseBody()
        . '</textarea><br />'
        . '<a href="session_details.php">'
        . 'click here to view details of last request</a><br />';
    return;
} catch (Zend_Gdata_App_Exception $e) {
    print 'ERROR - Could not retrieve token for syndicated upload. '
        . $e->getMessage()
        . '<br /><a href="session_details.php">'
        . 'click here to view details of last request</a><br />';
    return;
}

$tokenValue = $tokenArray['token'];
$postUrl = $tokenArray['url'];

// place to redirect user after upload
if (!$nextUrl) {
    $nextUrl = $_SESSION['homeUrl'];
} 

//instead of echoing the form below, send $_FILES from previous form submit

print <<< END
    <br />      

    <form id="uploadToYouTubeForm" action="${postUrl}?nexturl=${nextUrl}" method="post" enctype="multipart/form-data">
    <input id="uploadToYouTube" name="file" type="file" />
    <input name="token" type="hidden" value="${tokenValue}"/>
    <input value="Upload Video File" type="submit" />
    </form>

END;
}
4

1 に答える 1

0

私は解決策があるかもしれないと思います。以下は私が使用したいフォームです:

<!--removing the action ensures form will be sent via javascript, then when that request comes back, I can add in the authenticated youtube URL needed-->
<form id="upload" action="" method="POST" enctype="multipart/form-data" class="form-horizontal"><!--upload.php-->
  <fieldset>
    <legend><h1>Video File Upload</h1></legend>
    <input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="1000000000" /> <!--1GB-->
    <p id="filedrag">Drag and drop a video file from your computer here. Or use the 'File upload' button below.</p><!--dragFileHere-->
    <label class="control-label" for="fileselect">Files to upload:</label>
    <input type="file" id="fileselect" name="fileselect[]" /> <!--multiple="multiple"-->
    <button class="btn" id="submitbutton" type="submit">Upload Files</button> <!--hidden via js/css-->
    <div class="progress progress-striped active">
      <div class="bar" style="width: 0%;"></div>
    </div>
    <label class="hide" for="video-title">Title</label>
    <input type="text" id="video-title" class="span4" placeholder="Video Title"/>
    <label class="control-label" for="video-category">Category</label>
    <select id="video-category" name="videoCategory" class="span4">
      <option value="Autos">Autos &amp; Vehicles</option>
      <option value="Music">Music</option>
      .......
      <option value="Entertainment" selected>Entertainment</option>
    </select>
    <input id="token" type="text" placeholder="token"/> <!--will be hidden-->
</div>
</fieldset>
</form>

action属性を空白のままにすることで(そして、ユーザーの操作に応答するためにすでに配置されているスクリプトを使用して)、フォームがjavascriptを介してプログラムで送信されるようにすることができます。

<script src=http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js></script>
<script src=_js/video_app.js" type="text/javascript></script>
<script>
  /*
  filedrag.js - HTML5 File Drag & Drop demonstration
  Featured on SitePoint.com
  Developed by Craig Buckler (@craigbuckler) of OptimalWorks.net (without jQuery)
  */

  // output information
  function Output(msg) {
    $('#messages').html(msg + $('#messages').html());
  }

  // file drag hover
  function FileDragHover(e) {
    e.stopPropagation();
    e.preventDefault();
    $(this).addClass("hover");
  } 

  function FileDragOut(e) {
    $(this).removeClass("hover");
  }

  // file selection
  function FileSelectHandler(e) {
    // cancel event and hover styling
    FileDragHover(e);

    // fetch FileList object
    var files = e.target.files || e.dataTransfer.files;
    // process all File objects
    for (var i = 0, f; f = files[i]; i++) {
      ParseFile(f); //prints file data to div and optionally displays content of selected file
      UploadFile(f); //uploads file to server
    }
  }

  // output file information
  function ParseFile(file) {
    videoName = file.name;
    videoType = file.type;
    videoURL = "http://localhost/"+videoName;
    videoCategory = $('#video-category').val();

    Output(
      "</strong> type: <strong>" + file.type +
      "</strong> size: <strong>" + file.size +
      "</strong> bytes</p>"
    );

    // sets a default value because a title is needed for youtube to send response  
    if( $('#video-title').val() == $('#video-title').attr('placeholder') ) {
      $('#video-title').val(videoName);
    }

    var reader = new FileReader();
    reader.onload = function(e) {

      var fileContents = e.target.result;

      Output(
        '<img src="'+e.target.result+'"/>'
      );
    }
    reader.readAsDataURL(file);

    //get upload token
    ytVideoApp.prepareSyndicatedUpload(videoName, videoCategory);
  }

  // upload video files
  function UploadFile(file) {       
    var xhr = new XMLHttpRequest();
    if (xhr.upload && file.size <= $('#MAX_FILE_SIZE').val()) { //&& file.type == "video/mp4" or video/*
      xhr.upload.addEventListener("progress", function(e) {
        var pc = Math.ceil(e.loaded / e.total * 100);
      }, false);
      // file received/failed
      xhr.onreadystatechange = function(e) {
        if (xhr.readyState == 4) {
          if(xhr.status == 200) { //success

          } else { //fail  

          }
        }
      };
      // start upload
      xhr.open("POST", 'upload.php', true); //$("#upload").attr('action')
      xhr.setRequestHeader("X_FILENAME", file.name);
      xhr.send(file);
    }
  }

  // initialize
  function Init() {
    // file select
    $('#fileselect').change(FileSelectHandler);
    // is XHR2 available?
    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
      // file drop
      $('#filedrag').bind('dragover', FileDragHover);
      $('#filedrag').bind('dragleave', FileDragOut);

      //I can't get the below line to work, so I've used the ugly fallback
      //$('#filedrag').bind('drop', FileSelectHandler);
      document.getElementById('filedrag').addEventListener("drop", FileSelectHandler, false);           

      filedrag.style.display = "block";
      // remove submit button
      submitbutton.style.display = "none";
    }
  }
  // call initialization file
  if (window.File && window.FileList && window.FileReader) {
    Init();
  }
</script>

_js / video_app.js:

/**
* Zend Framework
* @package    Zend_Gdata
....
/**
* provides namespacing for the YouTube Video Application PHP version (ytVideoApp)
**/
var ytVideoApp = {};
/**
* Sends an AJAX request to the server to retrieve a list of videos or
* the video player/metadata.  Sends the request to the specified filePath
* on the same host, passing the specified params, and filling the specified
* resultDivName with the resutls upon success.
* @param {String} filePath The path to which the request should be sent
* @param {String} params The URL encoded POST params
* @param {String} resultDivName The name of the DIV used to hold the results
*/
ytVideoApp.sendRequest = function(filePath, params, resultDivName) {
  if (window.XMLHttpRequest) {
    var xmlhr = new XMLHttpRequest();
  } else {
    var xmlhr = new ActiveXObject('MSXML2.XMLHTTP.3.0');
  }

  xmlhr.open('POST', filePath);
  xmlhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 

  xmlhr.onreadystatechange = function() {
    var resultDiv = document.getElementById(resultDivName);
    if (xmlhr.readyState == 1) {
      resultDiv.innerHTML = '<b>Loading...</b>'; 
    } else if (xmlhr.readyState == 4 && xmlhr.status == 200) {
      if (xmlhr.responseText) {
        resultDiv.innerHTML = xmlhr.responseText;
      }
    } else if (xmlhr.readyState == 4) {
      alert('Invalid response received - Status: ' + xmlhr.status);
    }
  }
  xmlhr.send(params);
}


ytVideoApp.prepareSyndicatedUpload = function(videoTitle, videoCategory, fileContents) {    
  var filePath = '_scripts/operations.php';
  var params = 'operation=create_upload_form' +
    '&videoTitle=' + videoTitle +
    '&videoCategory=' + videoCategory;
  ytVideoApp.sendRequest(filePath, params, ytVideoApp.SYNDICATED_UPLOAD_DIV);
}

_scripts / operations.php:

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_App_Exception');
/*
 * The main controller logic.
 *
 * POST used for all authenticated requests
 * otherwise use GET for retrieve and supplementary values
 */
session_start();
setLogging('on');
generateUrlInformation();

if (!isset($_POST['operation'])) {
  // if a GET variable is set then process the token upgrade
  if (isset($_GET['token'])) {
    updateAuthSubToken($_GET['token']);
  } else {
    if (loggingEnabled()) {
      logMessage('reached operations.php without $_POST or $_GET variables set', 'error');
      header('Location: add-content.php');
    }
  }
}

$operation = $_POST['operation'];

switch ($operation) {
  ....
  case 'create_upload_form':
    createUploadForm($_POST['videoTitle'],
                     $_POST['videoCategory'],
                     $_POST['videoContents']);
  break;
  ....
  default:
    unsupportedOperation($_POST);
  break;
}

function createUploadForm($videoTitle, $videoCategory, $nextUrl = null) {
  $httpClient = getAuthSubHttpClient();
  $youTubeService = new Zend_Gdata_YouTube($httpClient);
  $newVideoEntry = new Zend_Gdata_YouTube_VideoEntry();

  $newVideoEntry->setVideoTitle($videoTitle);

  //make sure first character in category is capitalized
  $videoCategory = strtoupper(substr($videoCategory, 0, 1))
                              . substr($videoCategory, 1);
  $newVideoEntry->setVideoCategory($videoCategory);

  // convert videoTags from whitespace separated into comma separated
  $tokenHandlerUrl = 'https://gdata.youtube.com/action/GetUploadToken';
  try {
    $tokenArray = $youTubeService->getFormUploadToken($newVideoEntry, $tokenHandlerUrl);
    if (loggingEnabled()) {
      logMessage($httpClient->getLastRequest(), 'request');
      logMessage($httpClient->getLastResponse()->getBody(), 'response');
    }
  } catch (Zend_Gdata_App_HttpException $httpException) {
    print 'ERROR ' . $httpException->getMessage()
                   . ' HTTP details<br /><textarea cols="100" rows="20">'
                   . $httpException->getRawResponseBody()
                   . '</textarea><br />'
                   . '<a href="session_details.php">'
                   . 'click here to view details of last request</a><br />';
    return;
  } catch (Zend_Gdata_App_Exception $e) {
    print 'ERROR - Could not retrieve token for syndicated upload. '
                 . $e->getMessage()
                 . '<br /><a href="session_details.php">'
                 . 'click here to view details of last request</a><br />';
    return;
  }
  $tokenValue = $tokenArray['token'];
  $postUrl = $tokenArray['url'];
  // place to redirect user after upload
  if (!$nextUrl) {
    $nextUrl = $_SESSION['homeUrl'];
  }

  //instead of outputting the form below, send variables (json???) to be interpreted by xmlhr in _js/video_app.js
  //print <<< END
  //<br />      
  //<p>url: ${postUrl}?nexturl=${nextUrl}</p>
  //<form id="uploadToYouTubeForm" action="temp.php" method="post" enctype="multipart/form-data">
  //<input id="uploadToYouTube" name="file" type="file" onchange="autoUploadToYouTube();" /><br/>
  //token: <input id="token" name="token" type="text" value="${tokenValue}"/><br/>
  //<input value="Manual upload" type="submit" />
  //</form>     
  //END;
  //}

したがって、最初のjavascriptは、入力type = "file"のドラッグアンドドロップ(div上)またはchange()イベントをリッスンします。フォームは実際には送信されませんが、データが収集され、ajaxを介してphpスクリプトに送信されます。このスクリプトは、アップロードに必要なトークンとURLを返します。次に、元のPHPスクリプトは、ファイル(およびトークンを含む非表示フィールド)を選択するためのフォームを出力します。その代わりに、URLとトークンを変数として渡し、XMLHttpRequestを使用して、これらの変数をフォームのaction属性に配置し、キーを非表示の入力フィールドの値に設定します。次に、フィールドを介して送信できます$('#uploadToYouTubeForm').submit();

発生する可能性のある唯一の問題は、YouTubeアプリに追加情報を送信することです。それが単に無視されるか、YouTubeが受け入れないフィールド(タイトル、カテゴリ、最大ファイルサイズ)をプログラムで削除する必要があるかもしれません。 ..

于 2012-08-28T21:58:47.060 に答える