I have tried uploading a video to YouTube channels using by the YouTube Data API, by composer:
"require": {
"google/apiclient": "^2.7",
"hybridauth/hybridauth": "~3.4.0",
"guzzlehttp/guzzle": "^7.0"
}
The video is uploaded successfully, but YouTube marks every video uploaded into it as private. Does anybody know how to fix this scenario?
public function upload_video_on_youtube($id, $arr_data)
{
$result_data = array();
$channel_id = $id;
$uploaded = false;
$stopper = 0;
while ($uploaded == false && $stopper == 0) {
$arr_data['summary'] = $this->getrandomstring(10);
$arr_data['title'] = $this->getrandomstring(10);
$client = new Google_Client();
$arr_token = $this->getAccessToken($channel_id);
if ($arr_token['error'] == false) {
$res = array();
$accessToken = array(
'access_token' => $arr_token['access_token']
);
$client->setAccessToken($accessToken);
$service = new Google_Service_YouTube($client);
$video = new Google_Service_YouTube_Video();
$videoSnippet = new Google_Service_YouTube_VideoSnippet();
$videoSnippet->setDescription($arr_data['summary']);
$videoSnippet->setTitle($arr_data['title']);
$video->setSnippet($videoSnippet);
$videoStatus = new Google_Service_YouTube_VideoStatus();
$videoStatus->setPrivacyStatus('unlisted');
$video->setStatus($videoStatus);
try {
$response = $service->videos->insert(
'snippet,status',
$video,
array(
'data' => file_get_contents($arr_data['video_path']),
'mimeType' => 'video/*',
'uploadType' => 'multipart'
)
);
if (isset($response->id)) {
$video_id = $response->id;
$res['error'] = false;
$res['response'] = $video_id;
array_push($result_data, $res);
$uploaded = true;
return $result_data;
}
} catch (Exception $e) {
if (401 == $e->getCode()) {
// echo ($arr_token['email'] . " Youtube Access token expired");
$refresh_token = $this->get_refersh_token($channel_id);
$client = new GuzzleHttp\Client(['base_uri' => 'https://accounts.google.com']);
$response = $client->request('POST', '/o/oauth2/token', [
'form_params' => [
"grant_type" => "refresh_token",
"refresh_token" => $refresh_token,
"client_id" => $arr_token['client_id'],
"client_secret" => $arr_token['client_secret'],
],
]);
$data = json_decode($response->getBody());
$data->refresh_token = $refresh_token;
$this->update_access_token($channel_id, json_encode($data));
$uploaded = false;
} elseif (403 == $e->getCode()) {
// echo ($arr_token['email'] . ' Youtube channel quota exceeded');
$channel_id = $channel_id + 1;
$uploaded = false;
}
}
} else if ($arr_token['error'] == true) {
$res['error'] = true;
$res['response'] = "Your Daily Upload Quota is Exceeded";
array_push($result_data, $res);
$stopper = 1;
return $result_data;
}
}
}
If you check the documentation for videos.insert you will see that all videos that are uploaded by apps that have not gone through the verification process will be set to private.
Once you go through the verification process you will be able to set your videos to public
This is an update after some clarity from Google.
At the top of the Video.insert page you will see it states.
Apps that dont need to be verified can just go though an audit is not verification, these are two different things. You need to apply for an audit. YouTube API Services - Audit and Quota Extension Form
Related
On my site I use google api to upload images in folder. Actually, there is no official documentation from google how to use api using php, only python, js and etc. Current problem is that I get no errors, but file isn't uploading. I'm 100% sure that my service workers work (sorry for such bad english) properly. Below I put my php code for uploading images:
<?php
include '../vendor/autoload.php';
function handleGoogleDrive($file)
{
//connecting to google drive
$client = new \Google_Client();
$client->setApplicationName('Somesite');
$client->setScopes([\Google_Service_Drive::DRIVE]);
$client->setAccessType('offline');
$client->setAuthConfig('./credentials.json');
$client->setClientId('2445617429-6k99ikago0s0jdh5q5k3o37de6lqtsd3.apps.googleusercontent.com');
$client->setClientSecret('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');
$service = new Google_Service_Drive($client);
//counting amount of files in folder, there is no real reason in doing that
//it is just a test of connecting
$folder_id = '1eQtNOJjlA2CalZYb90bEs34IaP6v9ZHM';
$options = [
'q' => "'" . $folder_id . "' in parents",
'fields' => 'files(id, name)'
];
//printing result
$results = $service->files->listFiles($options);
echo count($results->getFiles());
//trying to add file
$data = file_get_contents("../test.jpg");
$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid(). '.jpg');
$file->setDescription('A test document');
$file->setMimeType('image/jpeg');
$new_file = $service->files->create($file, [
'data' => $data,
'mimeType' => 'image/jpeg',
'uploadType' => 'multipart',
]);
print_r($new_file);
}
This is my standard upload code for uploading.
Try removing 'uploadType' => 'multipart', in your code.
I also cant see you setting the folder id when you upload your file which means its going to root directory.
// Upload a file to the users Google Drive account
try{
$filePath = "image.png";
$folder_id = '1eQtNOJjlA2CalZYb90bEs34IaP6v9ZHM';
$fileMetadata = new Drive\DriveFile();
$fileMetadata->setName("image.png");
$fileMetadata->setMimeType('image/png');
$fileMetadata->setParents(array($folder_id));
$content = file_get_contents($filePath);
$mimeType=mime_content_type($filePath);
$request = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'fields' => 'id'));
printf("File ID: %s\n", $request->id);
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
Remember if you are using a service account, files are uploaded to the service accounts drive account unless you add the folder you want to upload the file to.
files list
// Print the next 10 events on the user's drive account.
try{
$optParams = array(
'pageSize' => 10,
'fields' => 'files(id,name,mimeType)'
);
$results = $service->files->listFiles($optParams);
$files = $results->getFiles();
if (empty($files)) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($files as $file) {
$id = $file->id;
printf("%s - (%s) - (%s)\n", $file->getId(), $file->getName(), $file->getMimeType());
}
}
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
Using the code which was suggested to me, this is full solution.
(Thanks everybody who helped me)
<?php
include '../vendor/autoload.php';
function handleGoogleDrive($file)
{
//connecting to google drive
$client = new \Google_Client();
$client->setClientId('YOUR ID IN SECRET FILE');
$client->setClientSecret(YOUR SECRET IN JSON FILE);
$client->setRedirectUri(YOUR REDIRECT URI);
//you should register redirect uri
$client->setApplicationName('Somesite');
$client->setScopes([\Google_Service_Drive::DRIVE]);
$client->setAuthConfig('./credentials.json');
$service = new Google_Service_Drive($client);
try{
$filePath = "../test.jpg";
$folder_id = 'YOUR FOLDER ID';
$fileMetadata = new Google_Service_Drive_DriveFile();
$fileMetadata->setName("image.png");
$fileMetadata->setMimeType('image/png');
$fileMetadata->setParents(array($folder_id));
$content = file_get_contents($filePath);
$mimeType=mime_content_type($filePath);
$request = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'fields' => 'id'));
printf("File ID: %s\n", $request->id);
}
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
try{
$optParams = array(
'pageSize' => 10,
'fields' => 'files(id,name,mimeType)'
);
$results = $service->files->listFiles($optParams);
$files = $results->getFiles();
if (empty($files)) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($files as $file) {
$id = $file->id;
printf("%s - (%s) - (%s)\n", $file->getId(), $file->getName(), $file->getMimeType());
}
}
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
}
I am trying to upload files to google drive using PHP code. I can't get API response whatever it is. Incase of successful upload response should be 200 and different error codes. I just want to get receive error codes. Can anyone help me with it. Bellow I have pasted my complete code. I am using function like check if folder already exists and if it does place file in it otherwise just create new folder and place file in it. I am trying to make my code fail safe, if an error is encountered it saves the particular file and error code. right now it is just returning critical error and breaks AJAX.
function getClient(){
$authdata = array (
'web' =>
array (
'client_id' => get_option("csc_gdrive_clientid"),
'project_id' => get_option("csc_gdrive_projectid"),
'auth_uri' => "https://accounts.google.com/o/oauth2/auth",
'token_uri' => "https://oauth2.googleapis.com/token",
'auth_provider_x509_cert_url' => "https://www.googleapis.com/oauth2/v1/certs",
'client_secret' => get_option("csc_gdrive_clientsecret"),
),
);
include( plugin_dir_path( __FILE__ ) . '../vendor/autoload.php');
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setScopes(Google_Service_Drive::DRIVE);
$client->setAuthConfig($authdata);
$client->setAccessType('offline');
// $client->setPrompt('select_account consent');
$client->setRedirectUri(get_option("csc_gdrive_redirecturi"));
// Load previously authorized token from a file, if it exists.
// The file key_config.txt stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = plugin_dir_path( __FILE__ ) .'111key_config.txt';
if (!file_exists($tokenPath)) {
return;
} else{
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
if (file_exists($tokenPath)){
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
$authCode = get_option('csc_gdrive_token');
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
}
}
return $client;
}enter code here
function create_folder( $folder_name, $parent_folder_id=null ){
//$folder_list = $this->check_folder_exists( $folder_name );
// if folder does not exists
//if( count( $folder_list ) == 0 ){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
$folder = new Google_Service_Drive_DriveFile();
$folder->setName( $folder_name );
$folder->setMimeType('application/vnd.google-apps.folder');
if( !empty( $parent_folder_id ) ){
$folder->setParents( [ $parent_folder_id ] );
}
$result = $service->files->create( $folder );
$folder_id = null;
if( isset( $result['id'] ) && !empty( $result['id'] ) ){
$folder_id = $result['id'];
}
return $folder_id;
}
//}
//return $folder_list[0]['id'];
}
// This will check folders and sub folders by name
function check_folder_exists( $folder_name, $parent_folder_id=null){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
if ($parent_folder_id){
$parameters['q'] = "mimeType='application/vnd.google-apps.folder' and name='$folder_name' and trashed=false and '$parent_folder_id' in parents";
} else {
$parameters['q'] = "mimeType='application/vnd.google-apps.folder' and name='$folder_name' and trashed=false";
}
$files = $service->files->listFiles($parameters);
$op = [];
foreach( $files as $k => $file ){
$op[] = $file;
}
return $op;
}
}
// This will insert file into drive and returns boolean values.
function insert_file_to_drive( $file_path, $file_name, $parent_file_id = null ){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
$file = new Google_Service_Drive_DriveFile();
$file->setName( $file_name );
if( !empty( $parent_file_id ) ){
$file->setParents( [ $parent_file_id ] );
}
$result = $service->files->create(
$file,
array(
'data' => file_get_contents($file_path.'/'.$file_name),
'mimeType' => 'application/octet-stream',
)
);
$is_success = false;
if( isset( $result['name'] ) && !empty( $result['name'] ) ){
$is_success = true;
}
return $is_success;
}
}
I'm a PHP developer, I would like to use transcribe real time transcriptions, but I haven't found documentation for PHP about this tool, do you have a strength?
For audio translation, I found it, but I didn't find real time.
Below audio conversion example:
//Storage::disk('temp')->get('1.mp3');
// // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-transcribe-2017-10-26.html
// https://docs.aws.amazon.com/transcribe/latest/dg/streaming.html
public function transcribeVoice(Request $request)
{
$client = AWS::createClient('transcribeService');
$path = 'https://audio-job.s3.us-east-2.amazonaws.com/audio.mp3';
try {
$result = $client->getTranscriptionJob([
'TranscriptionJobName' => 'audio-job'
]);
if ($result['TranscriptionJob']['TranscriptionJobStatus'] == 'IN_PROGRESS') {
return redirect('/')->with('status', 'Progressing now');
} else if ($result['TranscriptionJob']['TranscriptionJobStatus'] == 'COMPLETED') {
$file = file_get_contents($result['TranscriptionJob']['Transcript']['TranscriptFileUri']);
$json = json_decode($file);
$transcript = $json->results->transcripts[0]->transcript;
$client->deleteTranscriptionJob([
'TranscriptionJobName' => 'audio-job', // REQUIRED
]);
return redirect('/transcribeVoice')->with('result', $transcript);
}
} catch (Aws\TranscribeService\Exception\TranscribeServiceException $e) {
$result = $client->startTranscriptionJob([
'LanguageCode' => 'pt-BR', // REQUIRED
'Media' => [ // REQUIRED
'MediaFileUri' => $path,
],
'MediaFormat' => 'mp3', // REQUIRED
'TranscriptionJobName' => 'audio-job', // REQUIRED
]);
return redirect('/transcribeVoice')->with('status', 'Progressing now');
}
}
}
// StartStreamTranscription – Starts a bi-directional HTTP/2 stream where audio is streamed to Amazon Transcribe and the transcription results are streamed to your application.
// https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.TranscribeService.TranscribeServiceClient.html
I'm trying to create a copy of a document using the Google Docs Api, and then edit it that copy by inserting text into it. So, I've looked at the documentation and seemingly implemented it exactly the way it says.
<?php
//That is, if this is just a regular login
//Personal Files
require("loginManager.php");
require("globals.php");
require("googleDrive.php");
//Moodle files
require("../config.php");
require("../my/lib.php");
require("../files/renderer.php");
require("../course/lib.php");
//Google Docs
$CREDENTIALS_PATH = "../../" . "vendor/autoload.php";
require ($CREDENTIALS_PATH);
//Example code
$copyTitle = 'Copy Title';
$documentId = "1vYyeGLbadFi0sl9g2LEJSZCB4YiGOpCb";
$copy = new Google_Service_Drive_DriveFile(array(
'name' => $copyTitle
));
//Initialize necessary client variables
$desiredPath = "../../credentials.json";
$authCode = (isset($_GET["code"]) ? $_GET["code"]:"");
GoogleDrive::setAuthCode($authCode);
$client = GoogleDrive::getClient($desiredPath, $FULLSCRIPT);
$docServices = new Google_Service_Docs($client);
$driveServices = new Google_Service_Drive($client);
$files = $driveServices->files;
$documents = $docServices->documents;
$driveResponse = $files->copy($documentId, $copy);
$documentCopyId = $driveResponse->id;
//Create desiredRequests
$desiredRequests = array(new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25)))));
$batchUpdateRequests = new Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => $desiredRequests));
$docChangeResponse = $documents->batchUpdate($documentCopyId, $batchUpdateRequests);
echo $OUTPUT->header();
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();
//Check if there's any get actions that need to be serviced
$getVariable = filter_input(INPUT_GET, "action");
if($getVariable == "openFileManager") {core_files_renderer::render_form_filemanager();}
else if($getVariable == "createCourse")
{
/*Important note: there are two types of ids when it comes to courses
*
* Programmer's Notes:
*
* -$instance is the instance of a record of from the enrol table
* -the enrol table stores instances of courses...so does mdl_course
* -idnumber and id, the latter is the actual primary key, the other is
* I guess is for school admins or course creators to be able to number
* the courses according to their own system. idnumber can be null.
*
*/
$enrollmentPlugin = enrol_get_plugin("manual");
if($enrollmentPlugin)
{
//Create data for course_request
$data = new stdClass();
$data->requester = $USER->id;
$data->id = 1;
$course_request_object = new course_request($data);
unset($data);
//create data for new course
$data = new stdClass();
$data->fullname = 'Math';
$data->shortname = 'Math 7';
$data->summary = 'Awesome!';
$data->summaryformat = FORMAT_PLAIN;
$data->format = 'topics';
$data->newsitems = 0;
$data->numsections = 5;
//$data->category = $course_request_object->get_category();
$data->category = 1;
$course = create_course($data);
//Instance is the record from the enrol table
$instanceid = $enrollmentPlugin->add_instance($course);
$instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$enrollmentPlugin->enrol_user($instance, $USER->id);
}
}
else if($getVariable == "appendDocument")
{
$courseID = filter_input(INPUT_GET, "courseID");
$fs = get_file_storage();
$data = array(
'contextid' => $courseID, // ID of context
'component' => 'course_myarea', // usually = table name
'filearea' => 'myarea', // usually = table name
'itemid' => 0, // usually = ID of row in table
'filepath' => '/', // any path beginning and ending in /
'filename' => 'myfile.txt'
);
$content = "hellp worldl";
$fs->create_file_from_string($data, $content);
}
else if($getvariable == null)
{
//if there are no get paramaters then it's a first time entry
//get all of user's courses, files, etc
$courses = enrol_get_all_users_courses($USER->id);
global $DB;
foreach($courses as $currentCourse)
{
$desiredID = $currentCourse->id;
$desiredFiles = $DB->get_record('files', array('contextid'=> $desiredID));
$contentHash = $desiredFiles->contenthash;
$dir1 = substr($contentHash, 0, 2); $dir2 = substr($contentHash, 2, 2);
$desiredPath = $CFG->dirrot."../../../../moodledata/filedir/"
.$dir1."/".$dir2."/".$contentHash;
$myFile = file_get_contents($desiredPath);
$type = mime_content_type($desiredPath);
$contentTypes = array("pdf" => "application/pdf",
"txt" => "text/plain");
//header("Content-Type: application/pdf");
//readfile($desiredPath, false, $foo);
$myFile = file_get_contents("goedel.pdf");
$foo = 3;
}
}
?>
Here's where GoogleDrive::getClient is defined in case it helps
class GoogleDrive
{
private static $AUTH_CODE;
public static function setAuthCode($desiredCode)
{
self::$AUTH_CODE = $desiredCode;
}
public static function getClient($credentialsPath, $callbackScript)
{
$client = new Google_Client();
$client->setApplicationName('MyApp');
$client->setScopes(Google_Service_Drive::DRIVE);
$client->setAuthConfig($credentialsPath);
$client->setAccessType('online');
$client->setPrompt('select_account consent');
$desiredVariable = self::$AUTH_CODE;
if($desiredVariable != null)
{
$accessToken = $client->fetchAccessTokenWithAuthCode($desiredVariable);
$client->setAccessToken($accessToken);
return $client;
}
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
$client->setRedirectUri($callbackScript);
redirect($authUrl);
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
}
However, when I run the previous code I get this error.
"{
"error": {
"code": 400,
"message": "This operation is not supported for this document",
"errors": [
{
"message": "This operation is not supported for this document",
"domain": "global",
"reason": "failedPrecondition"
}
],
"status": "FAILED_PRECONDITION"
}
}
"
Any help or direction will be greatly appreciated.
Edit 1: I've changed the script to reflect Tanaike's solution
I believe your situation and goal as follows.
You have already been able to use Google Docs API.
The script of a copy of a document worked.
You want to remove the error in your question.
For this, how about this modification?
From:
$desiredRequests = new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25))));
In your script, when $batchUpdateRequests is retrieved, it becomes as follows.
{"requests":{"createNamedRangeType":{},"createNamedRangeDataType":{},"createParagraphBulletsType":{},"createParagraphBulletsDataType":{},"deleteContentRangeType":{},"deleteContentRangeDataType":{},"deleteNamedRangeType":{},"deleteNamedRangeDataType":{},"deleteParagraphBulletsType":{},"deleteParagraphBulletsDataType":{},"deletePositionedObjectType":{},"deletePositionedObjectDataType":{},"deleteTableColumnType":{},"deleteTableColumnDataType":{},"deleteTableRowType":{},"deleteTableRowDataType":{},"insertInlineImageType":{},"insertInlineImageDataType":{},"insertTableRowType":{},"insertTableRowDataType":{},"insertTextType":{},"insertTextDataType":{},"replaceAllTextType":{},"replaceAllTextDataType":{},"updateParagraphStyleType":{},"updateParagraphStyleDataType":{},"updateTextStyleType":{},"updateTextStyleDataType":{},"internal_gapi_mappings":{},"modelData":{},"processed":{},"insertText":{}}}
I think that this is the reason of your issue.
To:
$desiredRequests = array(new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25)))));
In this modified script, when $batchUpdateRequests is retrieved, it becomes as follows.
{"requests":[{"insertText":{"text":"Hello world!","location":{"index":25,"segmentId":null}}}]}
In this request body, I could confirm that it worked.
Note:
If an error like Invalid requests[0].insertText: Index 25 must be less than the end index of the referenced segment occurs, please modify 'index' => 25 to 'index' => 1.
Reference:
Method: documents.batchUpdate
I have a video exist on my server,
I need to post that video on Facebook using Graph API.
Here is the code suggested by Team Facebook.
What I am doing is as below.
1) From an Android device I am getting an access token
2) Recognizing user by passing that access token to Facebook and get email id and through email id recognize user
3) Posting user's video from my server to Facebook through Graph API.
4) Returning a video id to android device as an API response.
I am approaching this route because in Android device it is 2 step process to post video on Facebook.
1) Download the video first
2) Post to Facebook
This is time consuming.
Here is the code that I am trying
define("FB_WEB_APP_ID","********");
define("FB_WEB_SECRET","********");
define("FB_WEB_REDIRECT_URI","<< redirect url >>");
$GLOBALS["all_user_dir_path"]="/var/www/proj/web/video/user_videos/";
define("FB_WEB_SCOPE","user_friends,email,public_profile,user_hometown,user_location,user_photos,user_videos,publish_actions,read_friendlists,publish_stream,offline_access");
define("FB_WEB_RESPONSE_TYPE","code%20token");
$GLOBALS["fb_app_creds"]=array();
$GLOBALS["fb_app_creds"]['appId']= FB_WEB_APP_ID;
$GLOBALS["fb_app_creds"]['secret']=FB_WEB_SECRET;
$GLOBALS["fb_app_creds"]['response_type']=FB_WEB_RESPONSE_TYPE;
$GLOBALS["fb_app_creds"]['redirect_uri']=FB_WEB_REDIRECT_URI;
$GLOBALS["fb_app_creds"]['scope']=FB_WEB_SCOPE;
$GLOBALS["facebook"] = new Facebook($GLOBALS["fb_app_creds"]);
class DefaultController extends Controller
{
// some code....
/**
* #Route("/gk",name="_fb")
* #Template()
*/
public function gkAction(Request $request){
$facebook = $GLOBALS["facebook"];
$access_token=$request->query->get("access_token");
if(!$access_token){
die("give access token in url.......");
}
echo "<pre>";
$facebook->setAccessToken($access_token);
$user = $facebook->getUser();
$me=$facebook->api("/me");
$email=$me['email'];
$all_user_dir_path=$GLOBALS["all_user_dir_path"];
$user_directory = str_replace(array(".","#"), "_",$email);
$user_dir_abs_path=$all_user_dir_path.$user_directory;
print_r($me);
$video_file_path=$user_dir_abs_path."/video.mp4";
if(file_exists($video_file_path))
{
echo "file exists...";
}else{
die("not exist");
}
$video_title="Test";
$video_desc="Test";
$access_token=$request->query->get("access_token");
$file = "#".$video_file_path;
$data = array('name' => 'file', 'file' => $file);
$post_url = "https://graph-video.facebook.com/me/videos?"
. "title=" . $video_title. "&description=" . $video_desc
. "&". $access_token
;
echo "<hr>TRY 1<hr>";
try{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$res = curl_exec($ch);
$video_id=0;
if( $res === false ) {
}else{
$res=json_decode($res,true);
/* $video_id = $res['id'];*/
echo ":::: ";print_r($res);
}
curl_close($ch);
}catch(\Exception $e){
echo " Exception generated in Try 1 : ".$e->getMessage();
}
echo "<hr>TRY 2<hr>";
$params = array(
"access_token" => $access_token,
"name"=>"file",
"file" => "#".$video_file_path,
"title" => $video_title,
"description" => $video_desc
);
try {
$ret = $facebook->api('/me/videos', 'POST', $params);
print_r($ret);
} catch(\Exception $e) {
echo " Exception generated in Try 2 : ".$e->getMessage();
}
die("</pre>");
}
}
Output I am getting is An active access token must be used to query information about the current user. error and (#353) You must select a video file to upload.
Look at this image
Please tell me how to solve this problem ??
New code tried...................................................
/* code with sdk - object oriented way */
$file=$GLOBALS["all_user_dir_path"].$user_directory."/video.mp4";
$source = array();
$source['name']="video.mp4";
$source['type'] = "video/mp4";
$source['tmp_name'] = $file;
$source['error'] = 0;
$source['size'] = filesize($file);
echo "<br><br>$file<br><br>";
$params = array(
"access_token" => $access_token,
"source" => $source,
"title" => "testvideo",
"description" => "testvideo"
);
try {
$ret = $facebook->api('/me/videos', 'POST', $params);
echo 'Successfully posted to Facebook';
echo "<pre>";print_r($ret);echo "</pre>";
} catch(Exception $e) {
echo $e->getMessage();
}
but this gives (#353) You must select a video file to upload error
Here is the answer
public function shareSocialgrationFB($access_token,& $exception){
$video_id=0;
try{
$config = array();
$config['appId'] = FB_WEB_APP_ID;
$config['secret'] = FB_WEB_SECRET;
$config['fileUpload'] = true;
$config['cookie'] = true;
$facebook = new Facebook($config);
$facebook->setFileUploadSupport(true);
$facebook->setAccessToken($access_token);
$me=$facebook->api("/me");
$email=$me['email'];
$user_directory = str_replace(array(".","#"), "_",$email);
$file = $GLOBALS["all_user_dir_path"].$user_directory."/video.mp4";
$usersFacebookID=$facebook->getUser();
$video_details = array(
'access_token'=> $access_token,
'message'=> 'Testvideo!',
'source'=> '#' .realpath($file),
'title'=>'Test'
);
$post_video = $facebook->api('/'.$usersFacebookID.'/videos', 'post', $video_details);
$video_id=$post_video['id'];
}catch(\Exception $e){
//echo "Exception generated :: ".$e->getMessage();
$exception=$e->getMessage();
// extra code to handle exception
}
return $video_id;
}
Reference : How to POST video to Facebook through Graph API using PHP
I don't know why the info about configurations
$config['fileUpload'] = true;
$config['cookie'] = true;
is not mentioned at below official docs of APIs
https://developers.facebook.com/blog/post/493/
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/videos#publish
However solution given above, worked fine for me.
file is not a valid parameter. Instead of parameter file, use source.
Reference
For FB SDK4+Composer: (see the hardcoded video path, and the encoding).
Doc: https://developers.facebook.com/docs/php/gettingstarted/4.0.0
FB requests the video file to be passed encoded as form-data:
https://developers.facebook.com/docs/graph-api/reference/user/videos/
use Facebook\FacebookSession;
use Facebook\GraphSessionInfo;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;
private function postFBVideo($authResponse, $filePath, $formDataMessage)
{
FacebookSession::setDefaultApplication('yourAppkey', 'yourAppSecret');
$ajaxResponse = '';
try {
$session = new FacebookSession($authResponse->accessToken);
} catch (FacebookRequestException $ex) {
// When Facebook returns an error
$ajaxResponse = 'FB Error ->' . json_encode($ex) ;
} catch (\Exception $ex) {
// When validation fails or other local issues
$ajaxResponse = 'FB Validation Error - ' . json_encode($ex) ;
}
if ($session) {
$response = (new FacebookRequest(
$session, 'POST', '/me/videos', array(
'source' => new CURLFile('videos/81JZrD_IMG_4349.MOV', 'video/MOV'),
'message' => $formDataMessage,
)
))->execute();
$ajaxResponse = $response->getGraphObject();
}
return json_encode($ajaxResponse);
}