-
אני מעוניין לפתח תוכנה שמעלה אוטומטית וידאו ליוטיוב, (כבר פיתחתי אחת דומה שמעלה לימות משיח), הקוד שלי כתוב כמו במדריך הזה: https://artisansweb.net/use-youtube-api-upload-video-youtube-channel/
של ההדרכה הנ"ל).
שבעצם יוצר טוקן שלא פג...
משום מה הקוד לא מעלה לי סרטונים ליוטיוב, פשוט לא קורה כלום בטופס של העלאה. (כמופיע
להלן הקובץ של הקוד שמעלה את הסרטון (הקריאה ל config.php זה בעצם לאחר שהקובץ config.php מקבל את הטוקן שמאוחסן במסד נתונים).<?php require_once 'config.php'; if (isset($_POST['submit'])) { $arr_data = array( 'title' => $_POST['title'], 'summary' => $_POST['summary'], 'video_path' => $_FILES['file']['tmp_name'], ); upload_video_on_youtube($arr_data); } function upload_video_on_youtube($arr_data) { $client = new Google_Client(); $db = new DB(); $arr_token = (array) $db->get_access_token(); $accessToken = array( 'access_token' => $arr_token['access_token'], 'expires_in' => $arr_token['expires_in'], ); $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('public'); $video->setStatus($videoStatus); try { $response = $service->videos->insert( 'snippet,status', $video, array( 'data' => file_get_contents($arr_data['video_path']), 'mimeType' => 'video/*', 'uploadType' => 'multipart' ) ); echo "Video uploaded successfully. Video ID is ". $response->id; } catch(Exception $e) { if( 401 == $e->getCode() ) { $refresh_token = $db->get_refersh_token(); $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" => GOOGLE_CLIENT_ID, "client_secret" => GOOGLE_CLIENT_SECRET, ], ]); $data = (array) json_decode($response->getBody()); $data['refresh_token'] = $refresh_token; $db->update_access_token(json_encode($data)); upload_video_on_youtube($arr_data); } else { //echo $e->getMessage(); //print the error just in case your video is not uploaded. } } } ?> <form method="post" enctype="multipart/form-data"> <p><input type="text" name="title" placeholder="Enter Video Title" /></p> <p><textarea name="summary" cols="30" rows="10" placeholder="Video description"></textarea></p> <p><input type="file" name="file" /></p> <input type="submit" name="submit" value="Submit" /> </form>
תודה רבה.
-
@ass הגעת לפורום של הזקנים העצבניים... לכן במקום התשובה שציפית לקבל תקבל שיחת מוסר ארוכה מטובלת בכמה שיעורי חיים...
(טוב, לא כולם זקנים, אני מציג רק את עצמי)
השאלה לא מספיק ממוקדת. אי אפשר לצפות שמישהו יעבור על כל המדריך שציינת ויבדוק למה לא עובד הקוד אצלך. (ובנוסף יש את האפשרות המאוד סבירה שהבעיה קשורה למשהו שבכלל לא כתבת בשאלה)
התהליך הנורמלי של מתכנתים הוא לנסות למקד את הבעיה.
כלומר לנסות למצוא איזה שורה של הקוד לא מתנהגת בצורה הצפוייה.
איך?
א) PHP פולטת שגיאות ואזהרות שונות, האם אתה מקבל אותם בפלט? (אם לא, תדאג שכן תקבל אותם). האם אתה רואה בפלט הזה שום שגיאות או אזהרות שיכולות להיות קשורות לנושא?
ב) אם לא קיבלת שום שגיאה, תעבור על הקוד שלב שלב ותוסיף פקודות print שידפיסו את המצב הנוכחי, כלומר, ערכים של משתנים קשורים, או סתם לוג שהגעת לשלב הזה בהצלחה. תנסה לזהות אם המצב הנוכחי לא מתאים למה שציפית. (זו דרך לא מקצועית של דיבוג אבל נהוג מאוד בקהילת מפתחי PHP... נקרא בעגה המקצועית - כלומר אצלי... - בנימה של זלזול: console log debugging)
ג) או תשתמש בדיבאגר אמיתי ותצעד צעד צעד דרך הקוד לבדוק איפה הוא נכשל. יש את xdebug עבור PHP.אני לא מומחה PHP. אולי יש למומחי ה-PHP פה טיפים יותר יעילים לדיבוג בעיות
-
@yossiz לגבי הזקנים - נו, אני לא יכול להכחיש את המציאות... אבל לגבי העצבניים - אני מוחה, יש פה בפורום סבלנות יוצאת דופן. מוכיחה על כך התשובה המפורטת שנתת (בשעה לא סטנדרטית זו), שמועילה פי כמה מפתרון פלא שעובד, כי עדיף ללמד מישהו ללכת לבד במקום לקנות לו כסא גלגלים.
-
@yossiz
קודם כל תודה על המוסר
אז אכן עשיתי כדבריך, לא כ"כ הצלחתי להבין בבירור מה הבעיה, אבל כנראה השיטה שבעל המדריך השתמש לא נתמכת או משהוא כזה...
בכל אופן ישבתי על זה 6 שעות, וזה בערך מה שהבנתי.אשמח אם מישהו מהזקנים החכמים יחכימו את העלם צעיר שכבר יושב על זה חודש...
איזה מדריך PHP נורמאלי יש בעניין. (חוץ מהמדריכים המעצבנים של יוטיוב).
עברתי על עשרות מדריכים כל אחד והבאג שלו..
ממש אודה מאוד למי שיוכל לעזור בעניין.תודה רבה..
-
@ass אמר בבעיה ב API של youtube:
לא כ"כ הצלחתי להבין בבירור מה הבעיה, אבל כנראה השיטה שבעל המדריך השתמש לא נתמכת או משהוא כזה...
איך הבנת את זה?
מהי הודעת השגיאה שקיבלת?
איזה שורת קוד בדיוק מייצרת אותה?איזה מדריך PHP נורמאלי יש בעניין. (חוץ מהמדריכים המעצבנים של יוטיוב).
עברתי על עשרות מדריכים כל אחד והבאג שלו..יתכן והבעיה לא ב-php בכלל, כך שמדריך לא יעזור כאן. אולי אתה מנסה לעשות משהו לא נכון.
דרך משל: אם אני מנסה לומר למחשב לחשב כמה זה 1 לחלק ל 0 והוא פולט שגיאה - זו לא בעייה בשפה. -
@ASS תודה על התודות. אבל לא הבנתי מה אתה רוצה עכשיו...
אתה מגלה לנו שידוע לך במעומעם מה הבעיה, אבל אתה לא מגלה לנו מה היא. אז כנראה לא נוכל לעזור בפתרונה.
ואם כן איך כן נוכל לעזור?איזה מדריך PHP נורמאלי יש בעניין
אתה רוצה לקרוא על השימוש ב-API של יוטיוב באמצעות שפת PHP? אז המקור הכי טוב זה התיעוד של יוטיוב עצמם: https://developers.google.com/youtube/v3/quickstart/php
-
@yossiz
@odeddvir
אוקי, קיבלתי!
אז התחלתי מחדש עם קוד יותר פשוט (בלי לאחסן את הטוקן במסד נתונים וכו)
כמופיע במדריך הזה.<?php // Include api config file require_once 'config.php'; // Include database class require_once 'DB.class.php'; // Create an object of database class $db = new DB; // If the form is submitted if(isset($_POST['videoSubmit'])){ // Video info $title = $_POST['title']; $desc = $_POST['description']; $tags = $_POST['tags']; $privacy = !empty($_POST['privacy'])?$_POST['privacy']:'public'; // Check whether file field is not empty if($_FILES["file"]["name"] != ''){ // File upload path $fileName = str_shuffle('codexworld').'-'.basename($_FILES["file"]["name"]); $filePath = "videos/".$fileName; // Check the file type $allowedTypeArr = array("video/mp4", "video/avi", "video/mpeg", "video/mpg", "video/mov", "video/wmv", "video/rm"); if(in_array($_FILES['file']['type'], $allowedTypeArr)){ // Upload file to local server if(move_uploaded_file($_FILES['file']['tmp_name'], $filePath)){ // Insert video data in the database $vdata = array( 'title' => $title, 'description' => $desc, 'tags' => $tags, 'privacy' => $privacy, 'file_name' => $fileName ); $insert = $db->insert($vdata); // Store db row id in the session $_SESSION['uploadedFileId'] = $insert; }else{ header("Location:".BASE_URL."index.php?err=ue"); exit; } }else{ header("Location:".BASE_URL."index.php?err=fe"); exit; } }else{ header('Location:'.BASE_URL.'index.php?err=bf'); exit; } } // Get uploaded video data from database $videoData = $db->getRow($_SESSION['uploadedFileId']); // Check if an auth token exists for the required scopes $tokenSessionKey = 'token-' . $client->prepareScopes(); if (isset($_GET['code'])) { if (strval($_SESSION['state']) !== strval($_GET['state'])) { die('The session state did not match.'); } $client->authenticate($_GET['code']); $_SESSION[$tokenSessionKey] = $client->getAccessToken(); header('Location: ' . REDIRECT_URL); } if (isset($_SESSION[$tokenSessionKey])) { $client->setAccessToken($_SESSION[$tokenSessionKey]); } // Check to ensure that the access token was successfully acquired. if ($client->getAccessToken()) { $htmlBody = ''; try{ // REPLACE this value with the path to the file you are uploading. $videoPath = 'videos/'.$videoData['file_name']; if(!empty($videoData['youtube_video_id'])){ // Uploaded video data $videoTitle = $videoData['title']; $videoDesc = $videoData['description']; $videoTags = $videoData['tags']; $videoId = $videoData['youtube_video_id']; }else{ // 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($videoData['title']); $snippet->setDescription($videoData['description']); $snippet->setTags(explode(",", $videoData['tags'])); // Numeric video category. See // https://developers.google.com/youtube/v3/docs/videoCategories/list $snippet->setCategoryId("22"); // Set the video's status to "public". Valid statuses are "public", // "private" and "unlisted". $status = new Google_Service_YouTube_VideoStatus(); $status->privacyStatus = $videoData['privacy']; // Associate the snippet and status objects with a new video resource. $video = new Google_Service_YouTube_Video(); $video->setSnippet($snippet); $video->setStatus($status); // Specify the size of each chunk of data, in bytes. Set a higher value for // reliable connection as fewer chunks lead to faster uploads. Set a lower // value for better recovery on less reliable connections. $chunkSizeBytes = 1 * 1024 * 1024; // 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); // Create a request for the API's videos.insert method to create and upload the video. $insertRequest = $youtube->videos->insert("status,snippet", $video); // Create a MediaFileUpload object for resumable uploads. $media = new Google_Http_MediaFileUpload( $client, $insertRequest, 'video/*', null, true, $chunkSizeBytes ); $media->setFileSize(filesize($videoPath)); // Read the media file and upload it chunk by chunk. $status = false; $handle = fopen($videoPath, "rb"); while (!$status && !feof($handle)) { $chunk = fread($handle, $chunkSizeBytes); $status = $media->nextChunk($chunk); } fclose($handle); // If you want to make other calls after the file upload, set setDefer back to false $client->setDefer(false); // Update youtube video id to database $db->update($videoData['id'], $status['id']); // Delete video file from local server @unlink("videos/".$videoData['file_name']); // uploaded video data $videoTitle = ""; } // uploaded video embed html $youtubeURL = 'https://youtu.be/'.$videoId .'</li>'; $htmlBody .= '<li><b>Description: </b>'.$videoDesc.'</li>'; $htmlBody .= '<li><b>Tags: </b>'.$videoTags.'</li></ul>'; $htmlBody .= '<a href="logout.php">Logout</a>'; } catch (Google_Service_Exception $e) { $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>', htmlspecialchars($e->getMessage())); } catch (Google_Exception $e) { $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>', htmlspecialchars($e->getMessage())); $htmlBody .= 'Please reset session <a href="logout.php">Logout</a>'; } $_SESSION[$tokenSessionKey] = $client->getAccessToken(); } elseif (OAUTH_CLIENT_ID == '') { $htmlBody = <<<END <h3>Client Credentials Required</h3> <p> You need to set <code>\$oauthClientID</code> and <code>\$oauthClientSecret</code> before proceeding. <p> END; } else { // If the user hasn't authorized the app, initiate the OAuth flow $state = mt_rand(); $client->setState($state); $_SESSION['state'] = $state; $authUrl = $client->createAuthUrl(); $htmlBody = <<<END <h3>Authorization Required</h3> <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p> END; } ?> <!DOCTYPE html> <html> <head> <title>Upload Video to YouTube using PHP by CodexWorld</title> </head> <body> <div class="uplink"><a href echo $htmlBody; ?> </div> </body> </html>
אני מקבל שגיאה : Notice: Undefined index: uploadedFileI
כלומר זה:// Get uploaded video data from database $videoData = $db->getRow($_SESSION['uploadedFileId']);
לא מבין מה עשיתי לא נכון...
-
@yossiz
@odeddvir
יתכן שזה בגלל שהוא לא מקבל נתונים מהטופס?<?php // Destroy previous session data if(session_id() != '') session_destroy(); // Get file upload status if(isset($_GET['err'])){ if($_GET['err'] == 'bf'){ $errorMsg = 'Please select a video file to upload.'; }elseif($_GET['err'] == 'ue'){ $errorMsg = 'Sorry, there was an error on uploading your file.'; }elseif($_GET['err'] == 'fe'){ $errorMsg = 'Sorry, only MP4, AVI, MPEG, MPG, MOV and WMV files are allowed.'; }else{ $errorMsg = 'Some problems occurred, please try again.'; } } ?> <form method="post" enctype="multipart/form-data" action="upload.php"> <?php echo (!empty($errorMsg))?'<p class="err-msg">'.$errorMsg.'</p>':''; ?> <label for="title">Title:</label> <input type="text" name="title" value="" /> <label for="description">Description:</label> <textarea name="description" cols="20" rows="2" ></textarea> <label for="tags">Tags:</label> <input type="text" name="tags" value="" /> <label for="tags">Privacy:</label> <select name="privacy"> <option value="public">Public</option> <option value="private">Private</option> </select> <label for="file">Choose Video File:</label> <input type="file" name="file" > <input name="videoSubmit" type="submit" value="Upload"> </form>
לא מצליח להבין מדוע?
-
@ass
ניסית להשתמש במדריך הרשמי של גוגל?
יש שם טופס יפה שבו אתה יכול ליצא את הקוד בשלל שפות
וגם בPHP, אם כי הייתי ממליץ קודם ליצא לCURL או משהו בסגנון כדי לראות מה קורה בפועל, ולא לעשות העתק הדבק לקטע קוד גדול בלי להבין מה
הוא עושה בכלל, והעיקר שיעבוד.
https://developers.google.com/youtube/v3/docs/videos/insert -
@ASS אני לא מבין כלום ב-php, אבל העקרונות ברוב שפות התכנות הם זהים.
השגיאה שקיבלת אומרת שהאינדקס 'uploadedFileId' לא מוגדר במערך. כלומר אתה מנסה לגשת למערך SESSION עם אינדקס\מפתח שלא קיים.
מכאן תבין שמשהו מונע השמת ערך ל-'uploadedFileId'.אז צריך לחשוב: למה הוא לא מוגדר?
מסתמא כי לא מתבצעת העלאה של קובץ.
למה?
לא יודע. זו עבודת נמלים לאתר את הבעיה.
אז מה עושים??
אני אפנה אותך שוב לעיין בדברי החכם לעיל:תעבור על הקוד שלב שלב ותוסיף פקודות print שידפיסו את המצב הנוכחי, כלומר, ערכים של משתנים קשורים, או סתם לוג שהגעת לשלב הזה בהצלחה. תנסה לזהות אם המצב הנוכחי לא מתאים למה שציפית. (זו דרך לא מקצועית של דיבוג אבל נהוג מאוד בקהילת מפתחי PHP... נקרא בעגה המקצועית - כלומר אצלי... - בנימה של זלזול: console log debugging)
או תשתמש בדיבאגר אמיתי ותצעד צעד צעד דרך הקוד לבדוק איפה הוא נכשל. יש את xdebug עבור PHP.בקיצור, תנסה לאתר בדיוק את הנקודה שבה הקוד לא עושה את מה שאתה מצפה.
ברוב השפות יש דיבאגר שמאפשר צפייה (watch) בערכי המשתנים בזמן אמת, עם אפשרות לקבוע נקודות שבירה (breakpoints) שבהן הקוד יעצור ויתן לך אפשרות להתבונן בכל מרכיבי המצב הנוכחי, בערכי המשתנים, בקונסול וכו'.
אם אתה עדיין לא יודע להשתמש בכזה, תחפש מדריך על זה, ובינתיים - פשוט תדפיס את המצב הנוכחי אחרי כל שורה, זה ממש לא אידיאלי אבל אם זה המנהג בקהילה - מי אני שאערער...
ברגע שגילית את הנקודה שבה הקוד מתנהג לא כמצופה - אתה יכול לשמוח כמוצא מטמון. -
@ass אתה בנטפרי?
אם כן צריך להתקין את תעודת נטפרי עבור PHP.נראה שהדף בויקי נטפרי חסר כרגע..... בהזדמנות צריך להוסיף את זה לויקי.
לכאורה הפתרון הוא להגדיר ב-PHP.ini את הערך:
curl.cainfo = "C:\ProgramData\NetFree\CA\netfree-ca-bundle-curl.crt"
עדכן בבקשה אם זה עזר או לא.
(עדכון: איזה צדיק אחד כבר הוסיף את הדף לויקי נטפרי)
-
@yossiz אמר בבעיה ב API של youtube:
@ass הגעת לפורום של הזקנים העצבניים... לכן במקום התשובה שציפית לקבל תקבל שיחת מוסר ארוכה מטובלת בכמה שיעורי חיים...
(טוב, לא כולם זקנים, אני מציג רק את עצמי)
השאלה לא מספיק ממוקדת. אי אפשר לצפות שמישהו יעבור על כל המדריך שציינת ויבדוק למה לא עובד הקוד אצלך. (ובנוסף יש את האפשרות המאוד סבירה שהבעיה קשורה למשהו שבכלל לא כתבת בשאלה)
התהליך הנורמלי של מתכנתים הוא לנסות למקד את הבעיה.
כלומר לנסות למצוא איזה שורה של הקוד לא מתנהגת בצורה הצפוייה.
איך?
א) PHP פולטת שגיאות ואזהרות שונות, האם אתה מקבל אותם בפלט? (אם לא, תדאג שכן תקבל אותם). האם אתה רואה בפלט הזה שום שגיאות או אזהרות שיכולות להיות קשורות לנושא?
ב) אם לא קיבלת שום שגיאה, תעבור על הקוד שלב שלב ותוסיף פקודות print שידפיסו את המצב הנוכחי, כלומר, ערכים של משתנים קשורים, או סתם לוג שהגעת לשלב הזה בהצלחה. תנסה לזהות אם המצב הנוכחי לא מתאים למה שציפית. (זו דרך לא מקצועית של דיבוג אבל נהוג מאוד בקהילת מפתחי PHP... נקרא בעגה המקצועית - כלומר אצלי... - בנימה של זלזול: console log debugging)
ג) או תשתמש בדיבאגר אמיתי ותצעד צעד צעד דרך הקוד לבדוק איפה הוא נכשל. יש את xdebug עבור PHP.אני לא מומחה PHP. אולי יש למומחי ה-PHP פה טיפים יותר יעילים לדיבוג בעיות
אתה פשוט אלוף
-