How to correctly use oembed to pull thumbs from youtube - youtube-api

I show a lot of thumbs on my homepage from youtube videos. I was using this function below to grab the thumb from a youtube url which works fast but it doesn't work for url's in the shortned form like youtu.be/JSHDLSKL.
function get_youtube_screen_link( $url = '', $type = 'default', $echo = true ) {
if( empty( $url ) )
return false;
if( !isset( $type ) )
$type = '';
$url = esc_url( $url );
preg_match("|[\\?&]v=([^&#]*)|",$url,$vid_id);
if( !isset( $vid_id[1] ) )
return false;
$img_server_num = 'i'. rand(1,4);
switch( $type ) {
case 'large':
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/0.jpg";
break;
case 'first':
// Thumbnail of the first frame
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/1.jpg";
break;
case 'small':
// Thumbnail of a later frame(i'm not sure how they determine this)
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/2.jpg";
break;
case 'default':
case '':
default:
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/default.jpg";
break;
}
if( $echo )
echo $img_link;
else
return $img_link;
}
So I tried to use Oembed to get the thumbs instead which works for all variations of the youtube url but it retrieves the 480px/360px thumb which causes a lot of cropping to get it down to the 120px/90px size I use to display them. The other issue was it caused my page speed to increase by 4 seconds which Im guessing is a problem with the way I'm implementing it. Here's how I call the thumb inside a loop.
<?php
require_once(ABSPATH.'wp-includes/class-oembed.php');
$oembed= new WP_oEmbed;
$name = get_post_meta($post->ID,'video_code',true);
$url = $name;
//As noted in the comments below, you can auto-detect the video provider with the following
$provider = $oembed->discover($name);
//$provider = 'http://www.youtube.com/oembed';
$video = $oembed->fetch($provider, $url, array('width' => 300, 'height' => 175));
$thumb = $video->thumbnail_url; if ($thumb) { ?>
<img src="<?php echo $thumb; ?>" width="120px" height="90px" />
<?php } ?>
So how should I be doing this to maximize efficiency?

I came across this page from youtube explaining their oembed support, They mentioned that they output to json format so I made a function that gets the json data and then enables you to use it.
Feel free to ask if you need more help.
<?php
$youtube_url = 'http://youtu.be/oHg5SJYRHA0'; // url to youtube video
function getJson($youtube_url){
$baseurl = 'http://www.youtube.com/oembed?url='; // youtube oembed base url
$url = $baseurl . $youtube_url . '&format=json'; // combines the url with format json
$json = json_decode(file_get_contents($url)); // gets url and decodes the json
return $json;
}
$json = getJson($youtube_url);
// from this point on you have all your data placed in variables.
$provider_url = $json->{'provider_url'};
$thumbnail_url = $json->{'thumbnail_url'};
$title = $json->{'title'};
$html = $json->{'html'};
$author_name = $json->{'author_name'};
$height = $json->{'height'};
$thumbnail_width = $json->{'thumbnail_width'};
$thumbnail_height = $json->{'thumbnail_height'};
$width = $json->{'width'};
$version = $json->{'version'};
$author_url = $json->{'author_url'};
$provider_name = $json->{'provider_name'};
$type = $json->{'type'};
echo '<img src="'.$thumbnail_url.'" />'; // echo'ing out the thumbnail image

Ok I came up with a solution from pieces of other questions. First we need to get the id from any type of url youtube has using this function.
function getVideoId($url)
{
$parsedUrl = parse_url($url);
if ($parsedUrl === false)
return false;
if (!empty($parsedUrl['query']))
{
$query = array();
parse_str($parsedUrl['query'], $query);
if (!empty($query['v']))
return $query['v'];
}
if (strtolower($parsedUrl['host']) == 'youtu.be')
return trim($parsedUrl['path'], '/');
return false;
}
Now we can get use YouTube Data API to get the thumbnail from the video id. Looks like this.
<?php
$vid_id = getVideoId($video_code);
$json = json_decode(file_get_contents("http://gdata.youtube.com/feeds/api/videos/$vid_id?v=2&alt=jsonc"));
echo '<img src="' . $json->data->thumbnail->sqDefault . '" width="176" height="126">';
?>
The problem is that is causing an extra 2 seconds load time so I simply use the $vid_id and place it inside http://i3.ytimg.com/vi/<?php echo $vid_id; ?>/default.jpg which gets rid of the 2 seconds added by accessing the youtube api.

Related

Pagination is not working in twilio call logs laravel

<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ApiController;
use App\Model\User;
use Illuminate\Support\Facades\Validator;
use Auth;
use Twilio\Rest\Client;
use Twilio\TwiML\VoiceResponse;
class TwilioController extends ApiController
{
public function __construct(){
$sid = env('TWILIO_SID');
$token = env('TWILIO_TOKEN');
$this->twilio = new Client($sid, $token);
if (request('lang'))
\App::setLocale(request('lang'));
}
public function callLogs(Request $request){
try{
$twilioNumber = Auth::user()->twilio_number;
$calls = $this->twilio->calls
->read([], 20);
$data = [];
$i = 0;
foreach($calls as $call){
$data[$i]['from'] = $call->from;
$i++;
}
$responseData = array('status'=>true, 'message'=>'Data has been returned successfully!', 'data'=>$data);
} catch (\Exception $e) {
$responseData = array('status'=>false, 'message'=>$e->getMessage(), 'data'=>[]);
}
$res = json_encode($responseData);
print $res;
}
Pagination is not working when i get call history in twilio using laravel rest api. when i use page parameter with this then pagination is not working it give me save output as given me 1st page.
Postman parameters - Page:2
Thanks
I think Twilio's page() function will help you. Like read(), it accepts an array of options to narrow your search along with a pageSize parameter defaulting to 50 calls per page. (I believe the maximum value is 1000.)
Here is an example.
//Get all call logs. 20 per page
$calls = $twilio->calls->page( [], 20 );
$data = [];
foreach($calls as $call){
$data[] = $call->sid;
}
//You can access the previous and next page urls using the resource functions in the calls object return from twilio.
return response()->json(["prev" => $calls->getPreviousPageUrl(), "next" => $calls->getNextPageUrl(), "calls" => $data]);

Youtube Data API is returning invalid data

I'm not really sure how to ask this, but I have a php script that pulls data from the youtube-v3-api for my youtube channel, mainly a list of videos that I have published. It's been working great up until earlier today when I went to run it again because I added a new video. Here's the output for the first object in the items array
items:[
{
kind:"youtube#searchResult",
etag:"" XpPGQXPnxQJhLgs6enD_n8JR4Qk/tluoWYe5GE9lVFAkcMtcec2Ycug"",
id:{
kind:"youtube#channel",
channelId:"UCD8d3FGC907iS1qiMF0ccxA"
},
snippet:{
publishedAt:"2006-04-30T19:39:08.000Z",
channelId:"UCD8d3FGC907iS1qiMF0ccxA",
title:"Travis Ballard",
description:"",
thumbnails:{
default:{
url:"https://yt3.ggpht.com/-L5MV7tUNjlk/AAAAAAAAAAI/AAAAAAAAAAA/dXNuqxAYprw/s88-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
medium:{
url:"https://yt3.ggpht.com/-L5MV7tUNjlk/AAAAAAAAAAI/AAAAAAAAAAA/dXNuqxAYprw/s240-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
high:{
url:"https://yt3.ggpht.com/-L5MV7tUNjlk/AAAAAAAAAAI/AAAAAAAAAAA/dXNuqxAYprw/s800-c-k-no-mo-rj-c0xffffff/photo.jpg"
}
},
channelTitle:"Travis Ballard",
liveBroadcastContent:"none"
}
}
]
This does not represent a video on my channel? also, it's not in order at all. It should be ordered by date as i'm asking it to in my php script:
<?php
const APIKEY = 'MyAPIKeyHere';
const CHANNELID = 'UCD8d3FGC907iS1qiMF0ccxA';
const VIDEO_COUNT = 50;
class FetchYoutubeVideos {
private $api_key = null;
private $channel_id = null;
private $count = null;
public function __construct($api_key, $channel_id, $count = 10) {
$this->api_key = $api_key;
$this->channel_id = $channel_id;
$this->count = $count;
$this->writeToFile(
'videos.json',
$this->fetch($this->getApiUrl())
);
printf( 'fetched videos from: %s', $this->getApiUrl());
}
public function getApiUrl($options = array()) {
$endpoint = 'https://www.googleapis.com/youtube/v3/search';
$default_options = array(
'key' => $this->api_key,
'channelId' => $this->channel_id,
'part' => 'snippet,id',
'order' => 'date',
'maxResults' => $this->count
);
$options = array_merge($options, $default_options);
return sprintf('%s/?%s', $endpoint, http_build_query($options));
}
public function fetch($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
return $result;
}
public function writeToFile($filename, $data) {;
$fh = fopen($filename, 'w+');
fwrite($fh, $data, strlen($data));
fclose($fh);
}
}
$fetchVideos = new FetchYoutubeVideos(APIKEY, CHANNELID, VIDEO_COUNT);
The newest video should be 'Tragic - Rock-a-Hoola Revisited' and then 'Rocket Timelapse - Anycubic i3 Mega'. You can reference my yt channel to see what it should be returning: https://www.youtube.com/channel/UCD8d3FGC907iS1qiMF0ccxA?view_as=subscriber
Any insights into why it changed? Or why it's not returning the data that it should be?
You experienced an API issue which is known for a few days now. Follow-up https://issuetracker.google.com/issues/128673552, or the answers already given on this site (e.g. https://stackoverflow.com/a/55246970/8327971).
Either of the two links we'll lead you to find a workaround for the issue at hand.
Note that, until now, Google has refrained itself from providing an ETA for when it'll enable back the API's features it disabled. I suppose that it may well take a few more days (perhaps weeks?) until we'll see those disabled features working again.

Access specific node (custom_field) simplexml

This XML file, which can be accessed here # http://afdclinics.com/persistentpresence/category/brentwood/lobby-1/feed/ - has a custom_fields node with 2 fields called custom-bgcolor, and custom-fontcolor. I have tried numerous ways to try, and access the data inside them with no luck.
I have been accessing other nodes with simplexml, but haven't been able to get the custom_fields working. Here is what I have so far.
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL,'http://afdclinics.com/persistentpresence/category/brentwood/lobby-1/feed/');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($curl);
if ($result === false) {
die('Error fetching data: ' . curl_error($curl));
}
curl_close ($curl);
//we can at this point echo the XML if you want
//echo $result;
//parse xml string into SimpleXML objects
$xml = simplexml_load_string($result);
if ($xml === false) {
die('Error parsing XML');
}
//now we can loop through the xml structure
foreach ($xml->channel->item as $item) {
//print $item->title; rss feed article title
//print $item->description; rss feed article description
//print $item->link; rss feed article link
//print $item->pubDate; rss feed article publish date
print $item->children('content', true); //rss feed article content
// here is where is would like to print the custom values
print $item->custom_fields->custom-bgcolor; // this line doesn't seem to work
//gets img url's and appends them to offline manifest file
$imgUrl = array();
$doc2 = new DOMDocument();
$doc2->loadHTML($item->children('content', true));
$imgUrl = simplexml_import_dom($doc2);
$images = $imgUrl->xpath('//img');
foreach ($images as $img) {
$imgUrl = $img['src'] . "\r\n";
print $imgUrl; //rss feed image url's
$i++;
}

Get duration from a youtube url

Im looking for a function that will pull the youtube duration of a video from the url. I read some tutorials but don't get it. I embed videos on my site using a url and I have a function that pulls the thumbnail and I just want something similar that gets the duration. Here's how I get the thumb...
function get_youtube_screen_link( $url = '', $type = 'default', $echo = true ) {
if( empty( $url ) )
return false;
if( !isset( $type ) )
$type = '';
$url = esc_url( $url );
preg_match("|[\\?&]v=([^&#]*)|",$url,$vid_id);
if( !isset( $vid_id[1] ) )
return false;
$img_server_num = 'i'. rand(1,4);
switch( $type ) {
case 'large':
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/0.jpg";
break;
case 'first':
// Thumbnail of the first frame
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/1.jpg";
break;
case 'small':
// Thumbnail of a later frame(i'm not sure how they determine this)
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/2.jpg";
break;
case 'default':
case '':
default:
$img_link = "http://{$img_server_num}.ytimg.com/vi/{$vid_id[1]}/default.jpg";
break;
}
if( $echo )
echo $img_link;
else
return $img_link;
}
You could use something like this:
<?php
function getDuration($url){
parse_str(parse_url($url,PHP_URL_QUERY),$arr);
$video_id=$arr['v'];
$data=#file_get_contents('http://gdata.youtube.com/feeds/api/videos/'.$video_id.'?v=2&alt=jsonc');
if (false===$data) return false;
$obj=json_decode($data);
return $obj->data->duration;
}
echo getDuration('http://www.youtube.com/watch?v=rFQc7VRJowk');
?>
that returns the duration in seconds of the video.
Reference: http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html
You can use a function like this one to change the seconds to hours, minutes, and seconds.
youtube api v3
usage
echo youtubeVideoDuration('video_url', 'your_api_key');
// output: 63 (seconds)
function
/**
* Return video duration in seconds.
*
* #param $video_url
* #param $api_key
* #return integer|null
*/
function youtubeVideoDuration($video_url, $api_key) {
// video id from url
parse_str(parse_url($video_url, PHP_URL_QUERY), $get_parameters);
$video_id = $get_parameters['v'];
// video json data
$json_result = file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=$video_id&key=$api_key");
$result = json_decode($json_result, true);
// video duration data
if (!count($result['items'])) {
return null;
}
$duration_encoded = $result['items'][0]['contentDetails']['duration'];
// duration
$interval = new DateInterval($duration_encoded);
$seconds = $interval->days * 86400 + $interval->h * 3600 + $interval->i * 60 + $interval->s;
return $seconds;
}
This is my function to get youtube duration in second.
he is fully 100% work.
you need just youtube id video and youtube api key.
how to add youtube api key show
this video https://www.youtube.com/watch?v=4AQ9UamPN6E
public static function getYoutubeDuration($id)
{
$Youtube_KEY='';
$dur = file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id={$id}&key={$Youtube_KEY}");
$vTime='';
$H=0;
$M=0;
$S=0;
$duration = json_decode($dur, true);
foreach ($duration['items'] as $vidTime) {
$vTime = $vidTime['contentDetails']['duration'];
}
$vTime = substr($vTime, 2);
$exp = explode("H",$vTime);
//if explode executed
if( $exp[0] != $vTime )
{
$H = $exp[0];
$vTime = $exp[1];
}
$exp = explode("M",$vTime);
if( $exp[0] != $vTime )
{
$M = $exp[0];
$vTime = $exp[1];
}
$exp = explode("S",$vTime);
$S = $exp[0];
$H = ($H*3600);
$M = ($M*60);
$S = ($H+$M+$S);
return $S;
}
This is my function to get youtube duration in second.
he is fully 100% work.
you need just youtube id video and youtube api key.
how to add youtube api key show
this video https://www.youtube.com/watch?v=4AQ9UamPN6E
You can simply use a time formater to change the seconds into whatever format you like.
i.e. return gmdate("H:i:s", $obj->data->duration);
function getYoutubeDuration($videoid) {
$xml = simplexml_load_file('https://gdata.youtube.com/feeds/api/videos/' . $videoid . '?v=2');
$result = $xml->xpath('//yt:duration[#seconds]');
$total_seconds = (int) $result[0]->attributes()->seconds;
return $total_seconds;
}
//now call this pretty function.
//As parameter I gave a video id to my function and bam!
echo getYoutubeDuration("y5nKxHn4yVA");
1) You will need an API key. Go to https://developers.google.com/ and log in or create an account, if necessary. After logging in go to this link https://console.developers.google.com/project and click on the blue CREATE PROJECT button. Wait a moment as Google prepares your project.
2) You will need a web host that is running PHP with file_get_content supported. You can check by creating a new script with just "echo php_info();" and verifying that allow_url_fopen is set to On. If it is not, then change the configuration or talk to your web host.
<?php
$sYouTubeApiKey = "<enter the key you get>";
//Replace This With The Video ID. You can get it from the URL.
//ie https://www.youtube.com/XWuUdJo9ubM would be
$sVideoId = "XWuUdJo9ubM";
//Get The Video Details From The API.
function getVideoDetails ($sVideoId) {
global $sYouTubeApiKey;
//Generate The API URL
$sUrl = "https://www.googleapis.com/youtube/v3/videos?id=".$sVideoId."&key=".$sYouTubeApiKey."&part=contentDetails";
//Perform The Request
$sData = file_get_contents($sUrl);
//Decode The JSON Response
return json_decode($sData);
}
//Get The Video Duration In Seconds.
function getVideoDuration ($sVideoId) {
$oData = getVideoDetails($sVideoId);
//Deal With No Videos In List
if (count($oData->items) < 1) return false;
//Get The First Video
$oVideo = array_shift($oData->items);
//Extract The Duration
$sDuration = $oVideo->contentDetails->duration;
//Use Regular Expression To Parse The Length
$pFields = "'PT(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)S)?'si";
if (preg_match($pFields, $sDuration, $aMatch)) {
//Add Up Hours, Minutes, and Seconds
return $aMatch[1]*3600 + $aMatch[2]*60 + $aMatch[3];
}
}
header("Content-Type: text/plain");
$oData = getVideoDetails($sVideoId);
print_r($oData);
echo "Length: ".getVideoDuration($sVideoId);
?>
Hope this helps!

Problems decoding JSON data from Twitter API (THM oauth)

I am using tmhOAuth.php / class to login into twitter. I have been successful in logging in and sending a tweet.
When I go to use the friends.php script, I am having some problems inserting into my database. I do believe that my problem lies some where with the $paging variable in the code. Because it is looping only seven times. I am following 626 people so my $ids is 626 and then $paging is 7.
When I run the php in a web browser, I am only able to extract 7 of the followers (ie following user #626,following user 526,following user 426...) It seem to be echoing the last user on each page request. This due in part to requesting 100 user ids at a time, via the PAGESIZE constant. When I adjust the $paging with different number such as the number 626 I get {"errors":[{"code":17,"message":"No user matches for specified terms"}]}
Unfortunately, I suspect this is fairly simple php looping problem, but after the amount of time I have spent trying to crack this I can no longer think straight.
Thanks in advance.
define('PAGESIZE', 100);
require 'tmhOAuth.php';
require 'tmhUtilities.php';
if ($tmhOAuth->response['code'] == 200) {
$data = json_decode($tmhOAuth->response['response'], true);
$ids += $data['ids'];
$cursor = $data['next_cursor_str'];
} else {
echo $tmhOAuth->response['response'];
break;
}
endwhile;
// lookup users
$paging = ceil(count($ids) / PAGESIZE);
$users = array();
for ($i=0; $i < $paging ; $i++) {
$set = array_slice($ids, $i*PAGESIZE, PAGESIZE);
$tmhOAuth->request('GET', $tmhOAuth->url('1/users/lookup'), array(
'user_id' => implode(',', $set)
));
// check the rate limit
check_rate_limit($tmhOAuth->response);
if ($tmhOAuth->response['code'] == 200) {
$data = json_decode($tmhOAuth->response['response'], true);
if ($tmhOAuth->response['code'] == 200) {
$data = json_decode($tmhOAuth->response['response'], true);
$name = array();
foreach ($data as $val)
{
$name = $data[0]['screen_name'];
}
echo "this is the screen name " .$name. "\n";
$users += $data;
} else {
echo $tmhOAuth->response['response'];
break;
}
}
var_dump($users);
?>
The data I am trying to echo, then parse and insert into database is the standard twitter JSON data, so I won't include this in the message. Any help would be
Problem solved:
foreach ($data as $val)
{
$name = $val['screen_name'];
echo "this is the screen name " .$name. "\n";
$users[] = $name;
}

Resources