YouTube Data API - Resumable Uploads - Start a resumable session - Errors

982 views Asked by At

Running into parseError attempting to follow the "start a resumable session" YouTube Data API - Resumable Uploads documentation.

complete list of efforts ,response and code

  1. I read on the Google APIs - "Global domain errors" page "parseError The API server cannot parse the request body."
  2. I have watched "YouTube Developers Live: Debugging & Dealing with Errors" still know clue there
  3. I have read "stack over flow" for similar questions, but never get answered,or answers are still un clear
  4. the test youtube account i want to upload to has a youtube channel with videos
  5. I tried the client PHP upload API, but found out later its not a resumable upload.
  6. I thought resumable upoad would be a better option, so i dont frustrate users, by wasting there time,if there connection drops out....
  7. I am runing PHP from hostgator account
  8. I noticed how when i did not get an error, it would return the regular snippet and status data and not the "Step 2 - Save the resumable session URI" data
  9. I am using long lived access tokens pulled from my database...in the requests, the youtube user has a channel with videos before i stored the access tokens
  10. I do check the access tokens with tokeninfo?
  11. I noticed changing "uploadType" to "uploadtype" would produce "message": "Media type 'application/json; charset=utf-8'

is not supported. Valid media types: [video/*, application/octet-stream]",following this error by changing content type to "application/octet-stream" would return "kind = youtube#video
object with json snippet,status" not the Step 2 - Save the resumable session URI, so i changed things back to "uploadType" and "application/json; charset=utf-8" now facing same parse error

  1. I notice in the docs "Parameter values in the request URL must be URL-encoded." when i would urlencode() "Parameter values" it would return errors or parseError when i removed the urlencode function
  2. Even changing "Host: www.googleapis.com" to "Host: https://www.googleapis.com" would produce "The requested URL /upload/youtube/v3/videos was not found on this server. That’s all we know."
  3. parse error appears to be most persistent so far
  4. I have changed urlencode() to rawurlencode() still parse error
  5. i would add charset=utf-8;multipart/form-data;application/octet-stream to content type header, still parse error
  6. I notice content type on string is text/plain; charset=us-ascii not sure if google server expects pure application/json

any help would be great…

  Array
  (
      [response] => Array
          (
              [0] => {
   "error": {
    "errors": [
     {
      "domain": "global",
      "reason": "parseError",
      "message": "Parse Error"
     }
    ],
    "code": 400,
    "message": "Parse Error"
   }
  }

          )

      [headers] => [
      "POST \/upload\/youtube\/v3\/videos?uploadType=resumable&part=snippet,status HTTP\/1.1",
      "Host: www.googleapis.com",
      "Authorization: Bearer ya29.vAAY5n3SJq3uCG7z4tOhehDxYj9Z7mxFENtD5PKF_dJqFlLqwCktRHTrEJkUgY_NrJD3KMetKeBA_w",
      "Content-Length: 303",
      "Content-Type: application\/json; charset=utf-8",
      "X-Upload-Content-Length: 20121",
      "X-Upload-Content-Type: video\/*"
  ]
      [curl_resource] => Resource id #18
      [video_aray] => {
      "snippet": {
          "title": "test video",
          "description": "testing api",
          "tags": [
              "any",
              "thing"
          ],
          "categoryId": 25
      },
      "status": {
          "privacyStatus": "public",
          "embeddable": true,
          "license": "youtube"
      }
  }
      [json_requestbody] => {
      "snippet": {
          "title": "test video",
          "description": "testing api",
          "tags": [
              "any",
              "thing"
          ],
          "categoryId": 25
      },
      "status": {
          "privacyStatus": "public",
          "embeddable": true,
          "license": "youtube"
      }
  }
      [request_url] => https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status
      [content_type_of_request] => text/plain; charset=us-ascii
      [0] => text/plain; charset=us-ascii
      [1] => text/plain; charset=us-ascii
  )

Source

 public function startResumableSession()
    {
            $videoResource = array( 'snippet'=>array('title'=>"test video",'description'=>"testing api",
                                    'tags'=>array("any","thing"),'categoryId'=>25),
                                    'status'=>array('privacyStatus'=>"public",'embeddable'=>True,'license'=>"youtube"));
            $requestBody = json_encode($videoResource,JSON_PRETTY_PRINT);
            $headers = array
              (

                "POST /upload/youtube/v3/videos?uploadType=resumable&part=snippet,status HTTP/1.1",
                "Host: www.googleapis.com",
                "Authorization: Bearer ya29.vAAY5n3SJq3uCG7z4tOhehDxYj9Z7mxFENtD5PKF_dJqFlLqwCktRHTrEJkUgY_NrJD3KMetKeBA_w",
                "Content-Length: ".strlen($requestBody),
                "Content-Type: application/json; charset=utf-8",
                "X-Upload-Content-Length: 20121",
                "X-Upload-Content-Type: video/*"
            );
            /* Parameter values in the request URL must be URL-encoded. */
            $url = "https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status"; 
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL,$url);
            curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
            curl_setopt($ch, CURLOPT_POSTFIELDS,urlencode($requestBody));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE);
            $result = curl_exec($ch);
            $json = json_decode($result);
            /* Check request body contenttype */
            $finfo = new finfo(FILEINFO_MIME);
            $t1=  $finfo->buffer($requestBody);
            $t2 = $finfo->buffer("test");
            $t3 = $finfo->buffer(utf8_encode("test"));
            /* debug info */
            return array(   'response'=>(array)$result,
                            'headers'=>json_encode($headers,JSON_PRETTY_PRINT),
                            'curl_resource'=>$ch,
                            'video_aray'=>json_encode($videoResource,JSON_PRETTY_PRINT),
                            'json_requestbody'=>$requestBody,
                            'request_url'=>$url,
                            'content_type_of_request'=>$t1,$t2,$t3
                        );
    }    
1

There are 1 answers

1
smooty86 On

Easy answer is - you do it wrong.

You are NOT supposed to add "POST", "Host:" and "Content-Length:" into $headers because that is generated by curl (CURLOPT_URL and CURLOPT_POSTFIELDS).

YouTube API works correctly. It is not their fault.