Reputation: 481
I would upload a video using the Youtube API v3 with curl in PHP, as described here: https://developers.google.com/youtube/v3/docs/videos/insert
I've this function
function uploadVideo($file, $title, $description, $tags, $categoryId, $privacy)
{
$token = getToken(); // Tested function to retrieve the correct AuthToken
$video->snippet['title'] = $title;
$video->snippet['description'] = $description;
$video->snippet['categoryId'] = $categoryId;
$video->snippet['tags'] = $tags; // array
$video->snippet['privacyStatus'] = $privacy;
$res = json_encode($video);
$parms = array(
'part' => 'snippet',
'file' => '@'.$_SERVER['DOCUMENT_ROOT'].'/complete/path/to/'.$file
'video' => $res
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.googleapis.com/upload/youtube/v3/videos');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parms);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$token['access_token']));
$return = json_decode(curl_exec($ch));
curl_close($ch);
return $return;
}
But it returns this
stdClass Object
(
[error] => stdClass Object
(
[errors] => Array
(
[0] => stdClass Object
(
[domain] => global
[reason] => badContent
[message] => Unsupported content with type: application/octet-stream
)
)
[code] => 400
[message] => Unsupported content with type: application/octet-stream
)
)
The file is an MP4.
Anyone can help?
Upvotes: 14
Views: 17301
Reputation: 77
I have been able to upload a video to my channel on YouTube using the following shell script.
#!/bin/sh
# Upload the given video file to your YouTube channel.
cid_base_url="apps.googleusercontent.com"
client_id="<YOUR_CLIENT_ID>.$cid_base_url"
client_secret="<YOUR_CLIENT_SECRET>"
refresh_token="<YOUR_REFRESH_TOKEN>"
token_url="https://accounts.google.com/o/oauth2/token"
api_base_url="https://www.googleapis.com/upload/youtube/v3"
api_url="$api_base_url/videos?uploadType=resumable&part=snippet"
access_token=$(curl -H "Content-Type: application/x-www-form-urlencoded" -d refresh_token="$refresh_token" -d client_id="$client_id" -d client_secret="$client_secret" -d grant_type="refresh_token" $token_url|awk -F '"' '/access/{print $4}')
auth_header="Authorization: Bearer $access_token"
upload_url=$(curl -I -X POST -H "$auth_header" "$api_url"|awk -F ' |\r' '/loc/{print $2}'); curl -v -X POST --data-binary "@$1" -H "$auth_header" "$upload_url"
Refer to the this similar question for how to get your custom variable values.
Upvotes: 0
Reputation: 10056
a python script:
# categoryId is '1' for Film & Animation
# to fetch all categories: https://www.googleapis.com/youtube/v3/videoCategories?part=snippet®ionCode={2 chars region code}&key={app key}
meta = {'snippet': {'categoryId': '1',
'description': description,
'tags': ['any tag'],
'title': your_title},
'status': {'privacyStatus': 'private' if private else 'public'}}
param = {'key': {GOOGLE_API_KEY},
'part': 'snippet,status',
'uploadType': 'resumable'}
headers = {'Authorization': 'Bearer {}'.format(token),
'Content-type': 'application/json'}
#get location url
retries = 0
retries_count = 1
while retries <= retries_count:
requset = requests.request('POST', 'https://www.googleapis.com/upload/youtube/v3/videos',headers=headers,params=param,data=json.dumps(meta))
if requset.status_code in [500,503]:
retries += 1
break
if requset.status_code != 200:
#do something
location = requset.headers['location']
file_data = open(file_name, 'rb').read()
headers = {'Authorization': 'Bearer {}'.format(token)}
#upload your video
retries = 0
retries_count = 1
while retries <= retries_count:
requset = requests.request('POST', location,headers=headers,data=file_data)
if requset.status_code in [500,503]:
retries += 1
break
if requset.status_code != 200:
#do something
# get youtube id
cont = json.loads(requset.content)
youtube_id = cont['id']
Upvotes: 1
Reputation: 1968
Updated version: Now with custom upload url and sending of metadata with the upload process. The entire process requires 2 requests:
Get a custom upload location
First, make a POST request for an upload url to:
"https://www.googleapis.com/upload/youtube/v3/videos"
You will need to send 2 headers:
"Authorization": "Bearer {YOUR_ACCESS_TOKEN}"
"Content-type": "application/json"
You need to send 3 parameters:
"uploadType": "resumable"
"part": "snippet, status"
"key": {YOUR_API_KEY}
And you will need to send the metadata for the video in the request body:
{
"snippet": {
"title": {VIDEO TITLE},
"description": {VIDEO DESCRIPTION},
"tags": [{TAGS LIST}],
"categoryId": {YOUTUBE CATEGORY ID}
},
"status": {
"privacyStatus": {"public", "unlisted" OR "private"}
}
}
From this request you should get a response with a "location" field in the headers.
POST to custom location to send file.
For the upload you need 1 header:
"Authorization": "Bearer {YOUR_ACCESS_TOKEN}"
And send the file as your data/body.
If you read through how their client works you will see they recommend retrying if you are returned errors of code 500, 502, 503, or 504. Clearly you will want to have a wait period between retries and a max number of retries. It works in my system every time, though I am using python & urllib2 instead of cURL.
Also, because of the custom upload location this version is upload resumable capable, though I have yet to need that.
Upvotes: 27
Reputation: 56044
Unfortunately, we don't have a specific example of YouTube API v3 uploads from PHP available yet, but my general advice is:
In general, there are a lot of things incorrect with your cURL code, and I can't walk through all the steps it would take to fix it, as I think using the PHP client library is a much better option. If you are convinced you want to use cURL then I'll defer to someone else to provide specific guidance.
Upvotes: 1