I'm working on an iOS/MacOS issue.
I'm trying to play a simple audio file through a HTML5 audio element, and everything is working as expected except on iOS/MacOS.
My app is built on Symfony, using Nginx and custom PHP controllers to serve the audio resource. The audio element's given source is a link to a route that handles the streaming.
My logical is the following :
Get the file from url ID
Read request headers to find expected range and length
Setting up the good headers to force 206 Partial Content behaviour
Writing expected file chunks and returning a 206 response.
Here is the code for this:
public function getAudio(Request $request, $audioId)
{
/*
* Getting the file
*/
$em = $this->getDoctrine()->getManager();
$voice = $em->getRepository("CoreBundle:Audio")->findOneById($audioId);
$media = $audio->getFile();
$path = $this->container->get('sonata.media.twig.extension')->path($media, 'reference');
$file = $this->get('kernel')->getRootDir() . "/../web$path";
/*
* Setting length and offset for serving the right chunk
*/
$offset = 0;
$requestedRange = $request->headers->get("Range");
$size = $media->getSize();
$length = $size;
if($requestedRange){
preg_match('/bytes=(\d+)-(\d+)?/', $requestedRange, $matches);
$offset = intval($matches[1]);
if(count($matches) > 2){
$length = intval($matches[2]) - $offset + 1;
}
else{
$length = ($size) - $offset;
}
}
if(file_exists($file) && $length) {
$file = fopen($file, 'r');
fseek($file, $offset);
$data = fread($file, $length);
fclose($file);
if($requestedRange){
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $size);
}
else{
header('Content-Range: bytes 0-'.($size-1).'/'.$size);
}
/*
* Forcing some headers in the response to fit request attempts
*/
header("Pragma: public");
header("Expires: 0");
header('Content-type: audio/mpeg');
header('Content-Disposition: inline');
header('Accept-Ranges: bytes');
header('Content-Length: '.$length);
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
print($data);
return new Response("",206);
}
else{
return new Response("",200);
}
}
Again, everything is working fine on Firefox and Chrome, file is streamed and played perfectly.
But when it comes to IOS and MacOS, the file just doesn't play. A peek at network console shows two subsequent requests, with the last one in error (see next links).
However, no error is logged in PHP and I'm now completely stuck.
first-request
second-request
The logical was fine but the management of the response wasn't.
After reading the Symfony documentation about Response, I just changed every header() function to:
$response->setHeaders()
And every print($data) to:
$response = new Response($data);
Returning the complete Response object did the job.
Related
I'm trying to use an ESP8266 NodeMCU to retrieve data from a database on my web page to control a LED. I'm struggling with the code on both sides for the ESP8266 to ask for the data and the web page to return it. I have the web page and database built. Here is the relevant bit of the server side PHP file, which isn't working....
if(!empty($_GET['mode']) && !empty($_GET['brightness']))
{
$mode = $_GET['mode'];
$brightness = $_GET['brightness'];
$sql = "SELECT * FROM config ORDER BY id DESC LIMIT 1 (mode, brightness)
$result = $conn->query($sql);
SELECT fields FROM table ORDER BY id DESC LIMIT 1;
VALUES ('".$mode."', '".$brightness."')";
if ($conn->query($sql) === TRUE) {
echo "1" . $row["id"]."<br>";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
$conn->close();
<code>
and on the ESP8266 side....
getData = "?mode=" "&brightness=";
Link = "http://***.com/Feed.php" + getData;
http.begin(Link); //Specify request destination
int httpCode = http.GET();
String payload = http.getString();
Mode = payload.substring(0,3);
String Brightness = payload.substring (4,6);
Thanks in advance!
I changed my approach and got it working. Instead of trying to return data from the web page to the ESP8266 I displayed the data on a very simple page....
<?php
$con=mysqli_connect("localhost","*****","*****","*****");
if (mysqli_connect_errno()) { echo "Failed to connect to config: " . mysqli_connect_error(); }
$result = mysqli_query($con,"SELECT * FROM config ORDER BY id DESC LIMIT 1");
while ($row = $result->fetch_assoc()) {
$mode = $row[mode]; $brightness = $row[brightness]; $speed = $row[speed];
print $mode;
print $brightness;
print $speed;
}
?>
and then had the ESP download the entire page and parsed out the data using substring like so...
HTTPClient http; //Declare object of class HTTPClient
Link = "http://*****.com/*****.php";
http.begin(Link); //Specify request destination
int httpCode = http.GET(); //Send the request
String payload = http.getString(); //Get the response payload
Mode = payload.substring(156,158).toInt();
Speed = payload.substring(158,160).toInt();
Brightness = payload.substring(160,162).toInt();
I am trying to load a very short .mp3 file in my preload() function like this:
game.load.audio('sword', '$assetPath/swordraw.mp3', true);
As soon as this code gets executed, it crashes with the error
Breaking on exception: Invalid arguments(s)
pointing to a console.warn in Phaser's Loader's fileError function which is as below:
fileError(int index) {
this._fileList[index]['loaded'] = true;
this._fileList[index]['error'] = true;
this.onFileError.dispatch([this._fileList[index]['key'], this._fileList[index]]);
window.console.warn("Phaser.Loader error loading file: "
+ this._fileList[index]['key'] + ' from URL ' + this._fileList[index]['url']);
this.nextFile(index, false);
}
Through the debugger of DartEditor I have seen that for some reason _fileList[10]['url'] (URL for audio file) is picked up as being null here, and that is the cause of the exception (can't concat. null to a string) but why is url null?
I've checked the obvious: the file name is correct and assetPath is certainly initialised correctly since all the other files (which are images) before this load fine. So this seems like an audio file issue of some kind but I can't see what the problem is.
Oh, seems like I found the offender here... https://github.com/playif/play_phaser/blob/ae6a08e5a6eb159149fac01e5831fd8572223a44/lib/loader/loader.dart#L1447
When the Loader is setting up stuff about a newly added file it calls this getAudioUrl if the file is an audio file...
getAudioURL(urls) {
//String extension;
if (urls is String) {
urls = [urls];
}
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
//extension = urls[i].toLowerCase();
//extension = extension.substr((Math.max(0, extension.lastIndexOf(".")) || Infinity) + 1);
if (this.game.device.canPlayAudio(url.split('.').last)) {
//return urls[i];
return url;
}
}
return null;
}
...and as you may gather from the above, the method will return null seemingly if the device cannot play the the type of file supplied. So then, Dartium can't play .mp3s?
Im trying to implement nicEdit with the nicupload plugin, but when I select a file to upload it says "Failed to upload image", and the server response says "Invalid Upload ID".
This is the code that calls the script and initializes:
<script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script>
<script type="text/javascript">//<![CDATA[
bkLib.onDomLoaded(function() {
new nicEditor({uploadURI : '../../nicedit/nicUpload.php'}).panelInstance('area1');
});
//]]>
</script>
The path to nicUpload.php is correct, and the code is the one that can be found in the documentation: http://nicedit.com/src/nicUpload/nicUpload.js
I made the upload folder changes, and set write permissions. According to the documentation (http://wiki.nicedit.com/w/page/515/Configuration%20Options), thats all, but i keep getting errors. Any ideas?
After looking for an solution a long time (lot of posts without real solution), i now fixed the code myself. I'm now able to upload an image to my own server. Thx to firebug and eclipse ;-)
The main problem is that the nicUpload.php is old and not working with the current nicEdit-Upload function.
Missing is the error handling, feel free to add this...
Add the nicEditor to your php file and configure it to use the nicEdit.php:
new nicEditor({iconsPath : 'pics/nicEditorIcons.gif', uploadURI : 'script/nicUpload.php'}
Download the nicEdit.js uncompressed and change the following lines in nicEdit.js:
uploadFile : function() {
var file = this.fileInput.files[0];
if (!file || !file.type.match(/image.*/)) {
this.onError("Only image files can be uploaded");
return;
}
this.fileInput.setStyle({ display: 'none' });
this.setProgress(0);
var fd = new FormData();
fd.append("image", file);
fd.append("key", "b7ea18a4ecbda8e92203fa4968d10660");
var xhr = new XMLHttpRequest();
xhr.open("POST", this.ne.options.uploadURI || this.nicURI);
xhr.onload = function() {
try {
var res = JSON.parse(xhr.responseText);
} catch(e) {
return this.onError();
}
//this.onUploaded(res.upload); // CHANGE HERE
this.onUploaded(res);
}.closure(this);
xhr.onerror = this.onError.closure(this);
xhr.upload.onprogress = function(e) {
this.setProgress(e.loaded / e.total);
}.closure(this);
xhr.send(fd);
},
onUploaded : function(options) {
this.removePane();
//var src = options.links.original; // CHANGE HERE
var src = options['url'];
if(!this.im) {
this.ne.selectedInstance.restoreRng();
//var tmp = 'javascript:nicImTemp();';
this.ne.nicCommand("insertImage", src);
this.im = this.findElm('IMG','src', src);
}
var w = parseInt(this.ne.selectedInstance.elm.getStyle('width'));
if(this.im) {
this.im.setAttributes({
src : src,
width : (w && options.image.width) ? Math.min(w, options.image.width) : ''
});
}
}
Change the nicUpload.php like this
<?php
/* NicEdit - Micro Inline WYSIWYG
* Copyright 2007-2009 Brian Kirchoff
*
* NicEdit is distributed under the terms of the MIT license
* For more information visit http://nicedit.com/
* Do not remove this copyright message
*
* nicUpload Reciever Script PHP Edition
* #description: Save images uploaded for a users computer to a directory, and
* return the URL of the image to the client for use in nicEdit
* #author: Brian Kirchoff <briankircho#gmail.com>
* #sponsored by: DotConcepts (http://www.dotconcepts.net)
* #version: 0.9.0
*/
/*
* #author: Christoph Pahre
* #version: 0.1
* #description: different modification, so that this php file is working with the newest nicEdit.js (needs also modification - #see)
* #see http://stackoverflow.com/questions/11677128/nicupload-says-invalid-upload-id-cant-make-it-works
*/
define('NICUPLOAD_PATH', '../images/uploadedImages'); // Set the path (relative or absolute) to
// the directory to save image files
define('NICUPLOAD_URI', '../images/uploadedImages'); // Set the URL (relative or absolute) to
// the directory defined above
$nicupload_allowed_extensions = array('jpg','jpeg','png','gif','bmp');
if(!function_exists('json_encode')) {
die('{"error" : "Image upload host does not have the required dependicies (json_encode/decode)"}');
}
if($_SERVER['REQUEST_METHOD']=='POST') { // Upload is complete
$file = $_FILES['image'];
$image = $file['tmp_name'];
$id = $file['name'];
$max_upload_size = ini_max_upload_size();
if(!$file) {
nicupload_error('Must be less than '.bytes_to_readable($max_upload_size));
}
$ext = strtolower(substr(strrchr($file['name'], '.'), 1));
#$size = getimagesize($image);
if(!$size || !in_array($ext, $nicupload_allowed_extensions)) {
nicupload_error('Invalid image file, must be a valid image less than '.bytes_to_readable($max_upload_size));
}
$filename = $id;
$path = NICUPLOAD_PATH.'/'.$filename;
if(!move_uploaded_file($image, $path)) {
nicupload_error('Server error, failed to move file');
}
$status = array();
$status['done'] = 1;
$status['width'] = $size[0];
$rp = realpath($path);
$status['url'] = NICUPLOAD_URI ."/".$id;
nicupload_output($status, false);
exit;
}
// UTILITY FUNCTIONS
function nicupload_error($msg) {
echo nicupload_output(array('error' => $msg));
}
function nicupload_output($status, $showLoadingMsg = false) {
$script = json_encode($status);
$script = str_replace("\\/", '/', $script);
echo $script;
exit;
}
function ini_max_upload_size() {
$post_size = ini_get('post_max_size');
$upload_size = ini_get('upload_max_filesize');
if(!$post_size) $post_size = '8M';
if(!$upload_size) $upload_size = '2M';
return min( ini_bytes_from_string($post_size), ini_bytes_from_string($upload_size) );
}
function ini_bytes_from_string($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
function bytes_to_readable( $bytes ) {
if ($bytes<=0)
return '0 Byte';
$convention=1000; //[1000->10^x|1024->2^x]
$s=array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB');
$e=floor(log($bytes,$convention));
return round($bytes/pow($convention,$e),2).' '.$s[$e];
}
?>
You can manually pass an id to your script: e.g nicUpload.php?id=introPicHeader and it will become introPicHeader.jpg (or appropriate extension) in the images folder you defined.
However, I have noticed that this script is broken and cannot access the configuration option uploadURI if specified directly in nicEdit.js during the nicEditorAdvancedButton.extend({. This causes access to an relatively pathed "Unknown" resource, causing an error.
The documentation implies otherwise and the fact that the nicURI was specified here for imgur.com (maybe as a default) gave me the impression I could also add a uploadURI reference to the nicUpload.php script in a single place rather than on every editor instantiation.
Update
This works if you pass it during instantiation, which I guess does allow for easy dynamic id population.
Unfortunately, the nicUpload.php is riddled with errors and it's output is not JSON. The editor expects to parse JSON and finds a script tag and errors with unexpected token "<".
There are a raft of other errors which I will attempt to identify:
In nicEdit.js
A.append("image") should be infact A.append("nicImage")
this.onUploaded(D.upload) should become this.onUploaded(D)
this.onUploaded(D) should be moved to within the try block after var D=JSON.parse(C.responseText) to fix variable scope issues
B.image.width needs to become B.width
In nicUpload.php
JSON output is not formed correctly, comment out html output and output just json_encode($status).
JSON output needs to return a key/value pair named links rather than url although renaming the var D=B.links to var D=B.url in nicEdit.js would also suffice as a fix.
Both php and javascript code leaves a lot to be desired, I get many errors regularly and have been fixing them myself.
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.
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!