Order Now AdSolution Sign Up | Login » Bits on the Run Sign Up | Login »

Forums

/

No, I Meant A YouTube Playlist

137 replies [Last post]

My wish for a YouTube Playlist script was a bit misunderstood here:
http://www.jeroenwijering.com/?thread=7362

See, YouTube.com has this thingy called a "Playlist". its a collection of YouTube videos that you create in your YouTube account. you can make several different youtube playlists on one YouTube account. They are named and stored in your YouTube account. Notice, when you're watching a video on the YouTube site, there's a link under the video which says "Add To Playlist". That's what i'm talking about.

this request is NOT for playing an arbitrary list of YouTube videos, or video ID's stored in a database, or YouTube favorites, or tagged videos. It's ONLY for playing an official "YouTube Playlist", saved on a YouTube user account.

YouTube does NOT provide an RSS feed for their playlists. As a result, you have to roll my own, to play them on the jw flv player. It's a matter of getting the actual flv url's for each vid, and then generating an xml file that the flv player likes.

Problem: i often add and remove videos from my YouTube playlist, and my list contains about 75 videos. So, of course I don't want to manually hardcode the xml file for the jw flv player every time i add or remove videos from my YouTube playlist. I want the flv player to always be up-to-date, without manually editing the flv xml file.

i think i figured out how, but it requires writing a php script to generate the xml on the fly.

Step 1: There are services which deliver an RSS feed from a YouTube playlist, such as ubeek.com. That gets your individual video ID's in xml form. the basic idea is to run a couple of batch processes on this feed, to transform it into something the flv player understands.

Step 2: the ubeek feed does NOT contain the actual flv's, just the YouTube ID's for each video. you need to replace the ID's with the flv's. The following service converts a single YouTube ID into an flv:
http://cache.googlevideo.com/get_video?video_id=kieyjfZDUIc

What's needed is a script to run that on each of the ID's output by ubeek, to get the flv's for all the videos in the playlist.

Step 3: you need to strip away the ubeek id's and titles.

Step 4: Last, you'd need jeroen's External_Feed.php script, since the flv's are not hosted on the same server as the player.

I think this might be an easy script to produce for an experienced php coder. i might attempt it, but it will take me decades. maybe someone can think of an easier way to achieve it. or, perhaps some kind soul would be willing to any small part of the script?

Suggestion: it's for the following site, so if your politics are such, you might be inspired to code this up to support the cause :)
picnictoimpeach.us

many thanks

@johnny why,

A while back i posted quite a few scripts to convert various RSS feeds to XSPF playlists.

That's the easy part. The hard part is that the sites arbitrarily change their code; then the script is broken. I figured that since I did 99% of the work, the user could maintain the script. I simply don't have the time.

The script for YouTube reads a simple text file:

http://youtube.com/watch?v=fcy8QcS21PA
http://youtube.com/watch?v=Zi_760pnGtg
http://youtube.com/watch?v=sLNZ0QuNtmg
http://youtube.com/watch?v=VWBM6kcWswM
http://youtube.com/watch?v=Gpd0fhwVGyY
http://youtube.com/watch?v=wcbPLWrE3zA
http://youtube.com/watch?v=8W-Iv5Js16k

Then it gets the working URL and creates the XSPF playlist.

It could read your YouTube playlist if it has similar links. I don't have a YouTube playlist, so I don't now what the format of it is.

You don't need an external feed script. Only the playlist file falls under the Flash security restriction. If you used the external feed, it would be your bandwidth DOUBLE (once in, once out), that was being used.

I might be inspired to help...

Can you provide me with a YouTube playlist?

your scripts might cover part of the solution. do you use the google cache service to get the urls? i believe it's the most reliable way.

we're not dealing with a a list of discreet youtube video id's, as in your example.

here's the youtube playlist feed:

[url=http://www.ubeek.com/youtube/index.cfm?playlistID=9A337BB0628CF018&playlistName=&playlistDescription...]http://www.ubeek.com/youtube/index.cfm?playlistID=9A337BB0628CF018&playlistName=&playlistDescription...[/url]

here's the actual playlist:

[url=http://www.youtube.com/view_play_list?p=9A337BB0628CF018]http://www.youtube.com/view_play_list?p=9A337BB0628CF018[/url]

it's just a single ID, in this case:
9A337BB0628CF018

the link points only to the first page of the playlist-- there are about 10 more pages of videos. so we use ubeek to get the feed of all the videos in the playlist.

the player's Read Me explains, "a playlist should always reside on the same server as the SWF file, due to security restrictions of the Flash Player (there is a small workaround, the "external_feed.php". so, i guess you're right about that!

here's what i THINK is the correct approach:

PART 1: get the ubeek feed

PART 2: LOOP on each video in the ubeek output
--convert the urls in the ubeek output into flv urls with the google service
--rename or reformat any elements, as required
--strip off unneeded parts of the ubeek output
--add any missing xml elements

PART 3: strip off unneeded elements in the ubeek head or foot.

thanks again for your interest. perhaps we can make something.

cheers

Why bother with ubeek or the google service. The video URL is right in the YouTube playlist. Just read the 10 or 20 or 50 pages, process the URL and build your playlist with the resultant URLs.

I posted this a while back, but it still works:

Here's how to get the YouTube FLV URL.

1. Read the video page w/ file_get_contents, e.g. this one:

http://www.youtube.com/watch?v=S4YthjAuidY

2. Parse through the source code and find the line containing: /player2.swf?video_id=

In our example the line reads: (but note, when you run it, the contents will be different):

SWFObject("/player2.swf?video_id=S4YthjAuidY&l=232&t=OEgsToPDskIGsXB_3JO6T9DYXnZFv1A-&sk=gqGisC6NueBuAjl7Sh0MqQU&sw=0.1",

3. Below is the part you need in order to find out the correct stream server for the video:

S4YthjAuidY&l=232&t=OEgsToPDskIGsXB_3JO6T9DYXnZFv1A-&sk=gqGisC6NueBuAjl7Sh0MqQU&sw=0.1

4. Take this information and create a new URL:

http://youtube.com/get_video.php?video_id=S4YthjAuidY&l=232&t=OEgsToPDskIGsXB_3JO6T9DYXnZFv1A-&sk=gq...

5. FOPEN this URL and process the $http_response_headers array. $http_response_header[9] holds the steaming server URL. You get something like:

Location :http://ash-v177.ash.youtube.com/get_video?video_id=S4YthjAuidY

Which you convert into: http://ash-v177.ash.youtube.com/get_video?video_id=S4YthjAuidY.flv

This URL plays fine with the JW Player.

You are actually at about step 4. with the YouTube playlist page.

will, your suggestion is to "just read the 10 or 20 or 50 pages". i think you're saying to return the html of every single page of every single video in the playlist, and then parse out the html of each page. with a playlist containing tens or hundreds of videos, that seems inefficient, especially when ubeek provides a ready feed of all the ID's in a single call. i prefer the KISS method, but that's just me. i'm stupid and lazy, so i'd rather tap existing functions, if possible, rather than write my own.

i started a SourceForge project for this problem:
[url=https://sourceforge.net/projects/jwflvytplaylist]https://sourceforge.net/projects/jwflvytplaylist[/url]

cheers

You're absolutely right —— until one day ubeek returns a 404! Because they got a C&D from Google, or they ran out of money, or whatever...

Then you are screwed, and I'm happily watchng my videos.

Sorry, I'll never depend on a service that has no substantial underpinnings.

i don't know how ubeek gets its feed-- how do you know they're not using your method?

why would they get a C&D?

seems to me any method has risks, even yours. YouTube might change the structure of their website in such a way that your method would fail.

if ubeek goes out, i'll deal with it then. maybe YouTube will be providing their own playlist feed by then. if not, i'll rework my script as necessary, maybe using your method.

in the meantime, i'd rather make my life easier with an existing function call. not really into gratuitous coding, just because ubeek might theoretically stop working at some point in the future.

even if it stops working two weeks from now, i'll deal with it then, but at least i'll have my website functionality in the short-term.

hihi...your scripts are realy good, i did created my own but because of the 50 limit i did use yours ( http://www.ubeek.com/youtube/index.cfm?playlistID=9A337BB0628CF018&playlistName=&playlistDescription... ).
Is it true that there is a 100 limit? did somone tested it? I didnt found a playlist with more than 100 but will search for it and ive feedback if noone is faster than me...

But now i got a bigger problem. Then i get every single video id from a playlist i want also get the names of that video...and then i compare the count of names and ids i get differtent counts. (4 name less than id) for example i got 92 videoids but only 89 names.

Has someone the same problem or an idea for a solution? would be great...the example link is:

http://monkeymobb.de/kasi_use/cc/lTracks.php?l=9A337BB0628CF018

would be great if someone can look on it...

...chillis

seems playlists need update every 2 hours

see multiprocess for quik update

big playlist not deliver all video dont know why
i'm too making BIG playlist plus 200 for test yet

[1] do replace my.site.net with own domain 2 place

[2] put most playlist in $playlists array

[3] do put name of script in aftr GET

[4] hit YouTube by call to multiprocess.php

(can also do othr work by you mostly very useful - be careful max out T3 easy)

multiprocess.php

<?php

// multiprocess.php v2.0
// request many playlists simultaneously
// adapted from source: http://www.ibm.com/developerworks/library/os-php-multitask/index.html

header ("content-type: text/html");

print "<pre>\n";
print "Program starts at " . date('h:i:s') . "\n";

$timeout = 240;
$result = array();
$sockets = array();
$playlists = array('9A337BB0628CF018', '6F0C5EFD04A883BE', 'DBF02FC57B3479C3');
$read_block = 8192;

// Issue all requests simultaneously; there's no blocking
$id = 0;

foreach($playlists as $playlistid)
{
$s = stream_socket_client("tcp://my.site.net:80", $errno, $errstr, $timeout);

if ($s)
{
$sockets[$id++] = $s;
$http_message = "GET /YouTube_Playlist_XSPF.php?playlistid=" . $playlistid . " HTTP/1.0\r\nHost: my.site.net\r\n\r\n";
fwrite($s, $http_message);
}
else
{
print "Stream " . $id . " failed to open correctly.";
}
}

while (count($sockets))
{
$read = $sockets;
stream_select($read, $w = null, $e = null, $timeout);

if (count($read))
{
// stream_select generally shuffles $read
// so we need to compute from which socket(s) we're reading
foreach ($read as $r)
{
$id = array_search($r, $sockets);
$data = fread($r, $read_block);

// A socket is readable either because it has data to read, OR because it's at EOF
if (strlen($data) == 0)
{
print "Stream " . $id . " closes at " . date('h:i:s') . "\n";
fclose($r);
unset($sockets[$id]);
}
else
{
$result[$id] .= $data;
}
}
}
else
{
// A time-out means that *all* streams have failed to receive a response
echo " Time-out!\n";
break;
}
}

// use this code to return the playlists to your browser as text
/*
foreach($result as $playlist)
{
if (preg_match("/<\?xml(.*)/s", $playlist, $match));
{
print_r($match[0]);
}
}
*/

?>

seems mr Tube is broke the playlist

find = if (preg_match('/<title>(.*?)<\/title>/', $junk, $match))

new = if (preg_match('/<title type=\'text\'>(.*?)<\/title>/', $junk, $match))

...thanks, i will try that out and give feedback soon...

ahh, and i found some big playlists

with 200 videos: http://de.youtube.com/view_play_list?p=45AF5802CD5C1963
and 100 videos: http://youtube.com/view_play_list?p=5C06802F841BE277

...later then

--hihi

at first i tried that, but on php4 this was not possible...than i turned to php5 and i get the message that i should --fd-setSize to 2024 or something like that, but in case i have no access to php.ini or cgi compilation i can not do so...

the other thing is that you said: seems mr Tube is broke the playlist

--so i will never get all the names of my list, but i ever get all authors or thumbnails, justnot the name...must be a bug...

now i do it all in flash. i import that " http://www.ubeek.com/youtube/index.cfm?playlistID=9A337BB0628CF018&playlistName=&playlistDescription... " as xml with load() function and it works i ever get all the names of the videos, 100% succesfully in the moment...only thing is i can only get 100Video list or lower, then i got 101 or more vids in my list i can not use that link---than i should better create a temporarry xml on my own server, but that will decreas the performance of the page...so...is there an alternative to ubeek-script with mor than 100 videos but in xml-format like that ubeekSource???

...later then...chillis

what's umg?

say what? -what do you mean

-- is there an api like that from ubeek with more than 100 videos...

umg = universalmusicgroup

means different getting uri for video uri

johny, you have one in you playlist

chilis, now youtube limits to 100 items from playlist api

you making request http://gdata.youtube.com/feeds/api/playlists/E4E005279265AF65?start-index=101&max-results=50

now youtube api return empty

is really playlist 200 itm

thx - your right

global, you work too fast for me. does one of the scripts above retrieve > 100 vids from YouTube? which is the correct script to use? are you using ubeek now? thx

me i dont use ubeek, right now...but i would like to. but to do that the ubeekserver need a crossdomain.xml, to allow the access from flash directly...i know that he dont have that, maybe it is possible to reach the admin and ask him for that?

i would like to use ubeek, because there is that 100 limit anyway, and so i dont have to perform two tasks with php. and the second reason is ubeeks's output is in XML-strucrure - so it is easier to import and translate in flash.

when i import ubeek in php and give it back to flash there are mistakes with the results of the name (see problem above)...so for 100% correct results i need to import that ubeek app into flash directly.

do anybody know the admin of that server? or do anybody have an other solution for that (import more than 100 vids / importing to php without differnts in the results of names and vids)?

would be nice when we can discuss that one more time...thanks.

johny, google data API only return max 100 items, refuse to do 101+

youtube change format some small place old playlist broken badd

new "YouTube_Playlist_XSPF.php" v3.1 now working today

chillis, can you try v3.1 is making XSPF format for flash j w players

is XSPF playlist XML format good for you? or what you need?

<?php

// YouTube_Playlist_XSPF.php v3.1 20071221
// playlists need to be updated at least every 2 hours
// call with: http://some.site.org/YouTube_Playlist_XSPF-3.1?playlistid=9A337BB0628CF018

$update_interval = 2;
$cachedirectory  = 'cache/';

// for command line argument passing
if (isset($_SERVER['argv'][1]))
{
 
$_GET['playlistid'] = $_SERVER['argv'][1];
}

$playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "9A337BB0628CF018";

// max-results is limited to 50 per request, total of 100 for playlists
//               http://gdata.youtube.com/feeds/api/playlists/ 9A337BB0628CF018  ?start-index=1&max-results=50
$playlisturl1 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=1&max-results=50";
$playlisturl2 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=51&max-results=50";

// create cache filename
$patterns     = array('#gdata#', '#/#', '#:#', '#\.#', '#http#', '#youtube#', '#com#', '#feeds#', '#api#', '#playlists#', '#\?start-index=1&max-results=50#');
$replacements = array(       '',    '',    '',     '',       '',          '',      '',        '',      '''playlists_',                                 '');
$filename = preg_replace($patterns, $replacements, $playlisturl1);

for (

$i=0; $i < $update_interval; $i++)
{
 
$cachefilename = (date('YmdH') - $i) . '_' . $filename . ".xml";
  if (
file_exists($cachedirectory . $cachefilename))
  {
    if (!isset(
$_SERVER['argv'][1]))
    {
     
header ("content-type: text/xml");
      print
file_get_contents($cachedirectory . $cachefilename);
    }
    exit;
  }
}

$cachefilename = date('YmdH') . '_' . $filename . ".xml";

$playlistcontent1 = file($playlisturl1);
$playlistcontent2 = file($playlisturl2);
$playlistcontent  = array_merge($playlistcontent1, $playlistcontent2);

$contentstring = "";
foreach(
$playlistcontent as $value)
{
 
$contentstring .= rtrim($value);
}

$contentarray = explode("<entry>", $contentstring);

$track = 0;
$type  = '';

// construct XSPF playlist headers
$playlist  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
\n";
$playlist .= "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
$playlist .= "  <trackList>\n";

// construct XSPF playlist tracks
while($junk = next($contentarray))
{
  $track++;
  $playlist .= "    <track>\n";

  if ((preg_match('/<title>(.*?)<\/title>/', $junk, $match)) || (preg_match('/<title type=\'text\'>(.*?)<\/title>/', $junk, $match)))
  {
    $playlist .= "      <title>" . $match[1] . "</title>\n";
  }
  if (preg_match('/<name>(.*?)<\/name>/', $junk, $match))
  {
    $playlist .= "      <author>" . $match[1] . "</author>\n";
    if ($match[1] == 'universalmusicgroup')
    {
      $type = 'UMG';
    }
  }
  //                                                                                       <media:thumbnail url='http://img.youtube.com/vi/izoZ-hjbKJQ/0.jpg
  if (preg_match('/<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=\'(.*?)0.jpg/', $junk, $match))
  {
    $playlist .= "      <image>" . $match[1] . "0.jpg</image>\n";
  }
  //               <media:content url=\'http:\/\/www.youtube.com\/v\/ds6oTHYmqRc\' type
  if (preg_match('/<media:content url=\'http:\/\/www.youtube.com\/v\/(.*?)\' type/', $junk, $match))
  {
    $videoid = $match[1];
    //                          http://youtube.com/v/ds6oTHYmqRc.swf
    $page = @file_get_contents('http://youtube.com/v/' . $videoid . '.swf');
    if ((preg_match('/&t=(.*?)&/', $http_response_header[4], $match)) || (preg_match('/&t=(.*)/', $http_response_header[4], $match)))
    {
      $playlist .= "      <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
    }
  }
  else if (preg_match('/<media:player url=\'http:\/\/www.youtube.com\/watch\?v=(.*?)\'/', $junk, $match))
  {
    $videoid = $match[1];
    $page = @file_get_contents('http://youtube.com/watch?v=' . $videoid);
    // check html in $page for: var swfArgs = {video_id:'lNvWoi0TesY',l:'217',t:'OEgsToPDskKER2zcpXlSd7ZzYDMp35hB',sk:'ASVXJ-JA-T6kbJT7maMDnwC',sw:'0.05',tk:'SZEt22MOl18ADaQJ-c9onimRL-HKw9HxGyYbBkoyguEPPDq_ttbaow=='};
    preg_match('/t:\'(.*?)\'/', $page, $match);
    //                            http://www.youtube.com/get_video.php?video_id=   lNvWoi0TesY  &    t=OEgsToPDskKER2zcpXlSd7ZzYDMp35hB
    $playlist .= "      <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
  }
  $playlist .= "      <meta rel=\"type\">flv</meta>\n";
  $playlist .= "      <annotation>Track " . $track . "</annotation>\n";
  $playlist .= "    </track>\n";

  if (($track > 19) && ($type == 'UMG'))
  {
    break;
  }
}

// construct XSPF playlist footers
$playlist .= "  </trackList>\n";
$playlist .= "</playlist>\n";

if (!isset($_SERVER['argv'][1]))
{
  header ("content-type: text/xml");
  print $playlist;
}

// check cache - write to cache
if (!file_exists($cachedirectory . $cachefilename))
{
  $fh = fopen($cachedirectory . $cachefilename, 'a');

  fwrite($fh, $playlist);

  fclose($fh);
}

// cleanup cache
@$directory_handle = dir($cachedirectory);

if ($directory_handle)
{
  while (false !== ($currentfile = $directory_handle->read()))
  {
           // 200712050018_playlists_9A337BB0628CF018.xml
    if (preg_match('/(\d{10})_playlists_.*?.xml/', $currentfile, $match))
    {
      $currentdate = date('YmdH');

      // if file is older than current hour - update interval, delete file
      if ($match[1] < $currentdate - $update_interval + 1)
      {
        unlink($cachedirectory . $currentfile);
      }
    }
  }
  $directory_handle->close();
}

?>

...very nice, thank you - i will try that out and give feedback soon...later then

global, your new script is still using gdata.youtube.com/feeds/api/playlists
so this script is limited to 100 vids, correct?

it does not seem to work for me:
http://picnictoimpeach.us/yt/async.htm

in the above page, global5.php5 is your latest script, copied and posted with no changes.

johny, im copypaste my script an shes working lkie champion

for you at [url=http://picnictoimpeach.us/yt/global5.php5]global5.php5[/url] i'm thinking some header already sent by you server

so try comment out header line here in this code (you see "//")

if (!isset($_SERVER['argv'][1]))
{
  // header ("content-type: text/xml");
  print $playlist;
}

i think mybe ok this way you no need header for jw player

i commented out the line you said. no change. after delay, i get a black screen on the player. jump the location bar to middle of video, still just black screen. no video.

i'm still having same error from line 124 header ("content-type: text/xml");
did you reloaded to your server?

did you tryed url to global5.php5 in your browser?

This is briliant stuff. Thank you global. Promise you'll stay and make updates if youtube breaks this script.

tanks mr robertpb

some fixes already make in script

mr tube can change anyday

best is you learn some php (specialy regex code) so you can chase mr tube youself

other code (google api, playlist) is more stable

will do, I'm ok @ PHP, but will have to brush up on my regular expressions. So you mean that the google video API is more stable?

I'll have to look into using this..

I think this looks promising.

http://franticindustries.com/2007/01/17/create-a-joint-youtube-and-google-video-playlist/

now at:
http://www.feedbeat.com

I am going to look at this site (which is free) and see if I can generate playlists that can be played by the jwplayer.

Wow, it worked. Warning, don't use IE7 on the site, I guess it's too "hip" to support that browser. Using Firefox, I was able to create a video list, it gives you a custom URL for your RSS, then boom right into the JWPlayer.

Wowsers! Maybe someone else out there will chase the Tube. How long will that service be free though.

hiiiiiiiiiiiiiii
how r u

<img src="http://www.google.co.in/logos/holiday07_4.gif">

global, any ideas why your script is not working? at [url=http://picnictoimpeach.us/yt/async.htm]http://picnictoimpeach.us/yt/async.htm[/url]

not sure what you mean by "reload my server"-- its shared hosting, and i never have to reload the server.

[url=http://picnictoimpeach.us/yt/global5.php5]http://picnictoimpeach.us/yt/global5.php5[/url] is your script, above, no changes:

<?php

// YouTube_Playlist_XSPF.php v3.1 20071221
// playlists need to be updated at least every 2 hours
// call with: http://some.site.org/YouTube_Playlist_XSPF-3.1?playlistid=9A337BB0628CF018

$update_interval = 2;
$cachedirectory = 'cache/';

// for command line argument passing
if (isset($_SERVER['argv'][1]))
{
$_GET['playlistid'] = $_SERVER['argv'][1];
}

$playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "9A337BB0628CF018";

// max-results is limited to 50 per request, total of 100 for playlists
// http://gdata.youtube.com/feeds/api/playlists/ 9A337BB0628CF018 ?start-index=1&max-results=50
$playlisturl1 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=1&max-results=50";
$playlisturl2 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=51&max-results=50";

// create cache filename
$patterns = array('#gdata#', '#/#', '#:#', '#\.#', '#http#', '#youtube#', '#com#', '#feeds#', '#api#', '#playlists#', '#\?start-index=1&max-results=50#');
$replacements = array( '', '', '', '', '', '', '', '', '', 'playlists_', '');
$filename = preg_replace($patterns, $replacements, $playlisturl1);

for (

$i=0; $i < $update_interval; $i++)
{
$cachefilename = (date('YmdH') - $i) . '_' . $filename . ".xml";
if (
file_exists($cachedirectory . $cachefilename))
{
if (!isset(
$_SERVER['argv'][1]))
{
header ("content-type: text/xml");
print
file_get_contents($cachedirectory . $cachefilename);
}
exit;
}
}

$cachefilename = date('YmdH') . '_' . $filename . ".xml";

$playlistcontent1 = file($playlisturl1);
$playlistcontent2 = file($playlisturl2);
$playlistcontent = array_merge($playlistcontent1, $playlistcontent2);

$contentstring = "";
foreach(
$playlistcontent as $value)
{
$contentstring .= rtrim($value);
}

$contentarray = explode("<entry>", $contentstring);

$track = 0;
$type = '';

// construct XSPF playlist headers
$playlist = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
\n";
$playlist .= "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
$playlist .= " <trackList>\n";

// construct XSPF playlist tracks
while($junk = next($contentarray))
{
$track++;
$playlist .= " <track>\n";

if ((preg_match('/<title>(.*?)<\/title>/', $junk, $match)) || (preg_match('/<title type=\'text\'>(.*?)<\/title>/', $junk, $match)))
{
$playlist .= " <title>" . $match[1] . "</title>\n";
}
if (preg_match('/<name>(.*?)<\/name>/', $junk, $match))
{
$playlist .= " <author>" . $match[1] . "</author>\n";
if ($match[1] == 'universalmusicgroup')
{
$type = 'UMG';
}
}
// <media:thumbnail url='http://img.youtube.com/vi/izoZ-hjbKJQ/0.jpg
if (preg_match('/<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=\'(.*?)0.jpg/', $junk, $match))
{
$playlist .= " <image>" . $match[1] . "0.jpg</image>\n";
}
// <media:content url=\'http:\/\/www.youtube.com\/v\/ds6oTHYmqRc\' type
if (preg_match('/<media:content url=\'http:\/\/www.youtube.com\/v\/(.*?)\' type/', $junk, $match))
{
$videoid = $match[1];
// http://youtube.com/v/ds6oTHYmqRc.swf
$page = @file_get_contents('http://youtube.com/v/' . $videoid . '.swf');
if ((preg_match('/&t=(.*?)&/', $http_response_header[4], $match)) || (preg_match('/&t=(.*)/', $http_response_header[4], $match)))
{
$playlist .= " <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
}
}
else if (preg_match('/<media:player url=\'http:\/\/www.youtube.com\/watch\?v=(.*?)\'/', $junk, $match))
{
$videoid = $match[1];
$page = @file_get_contents('http://youtube.com/watch?v=' . $videoid);
// check html in $page for: var swfArgs = {video_id:'lNvWoi0TesY',l:'217',t:'OEgsToPDskKER2zcpXlSd7ZzYDMp35hB',sk:'ASVXJ-JA-T6kbJT7maMDnwC',sw:'0.05',tk:'SZEt22MOl18ADaQJ-c9onimRL-HKw9HxGyYbBkoyguEPPDq_ttbaow=='};
preg_match('/t:\'(.*?)\'/', $page, $match);
// http://www.youtube.com/get_video.php?video_id= lNvWoi0TesY & t=OEgsToPDskKER2zcpXlSd7ZzYDMp35hB
$playlist .= " <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
}
$playlist .= " <meta rel=\"type\">flv</meta>\n";
$playlist .= " <annotation>Track " . $track . "</annotation>\n";
$playlist .= " </track>\n";

if (($track > 19) && ($type == 'UMG'))
{
break;
}
}

// construct XSPF playlist footers
$playlist .= " </trackList>\n";
$playlist .= "</playlist>\n";

if (!isset($_SERVER['argv'][1]))
{
header ("content-type: text/xml");
print $playlist;
}

// check cache - write to cache
if (!file_exists($cachedirectory . $cachefilename))
{
$fh = fopen($cachedirectory . $cachefilename, 'a');

fwrite($fh, $playlist);

fclose($fh);
}

// cleanup cache
@$directory_handle = dir($cachedirectory);

if ($directory_handle)
{
while (false !== ($currentfile = $directory_handle->read()))
{
// 200712050018_playlists_9A337BB0628CF018.xml
if (preg_match('/(\d{10})_playlists_.*?.xml/', $currentfile, $match))
{
$currentdate = date('YmdH');

// if file is older than current hour - update interval, delete file
if ($match[1] < $currentdate - $update_interval + 1)
{
unlink($cachedirectory . $currentfile);
}
}
}
$directory_handle->close();
}

?>

johny, only comment out two lines for headers, you don't need
// header ("content-type: text/xml");
2 place

If you want to get more than 100 of your playlist entries at a time, you can use this url (substitute the hashes with the playlist ID) : http://www.youtube.com/api2_rest?method=youtube.videos.list_by_playlist&id=#####&per_page=200

You can get the playlist ID from the http://youtube.com/my_playlists page.

from: http://www.youtube.com/dev

Legacy API Information
The older API is still functional, but officially deprecated. If you're developing new projects on the YouTube platform, we strongly recommend using the new API to ensure support.

@Yansky: this. is great, but i wonder...i tried the list id 7B60A94FCDA71233 and it sais that there are 200 videos in the list but i only get 100 outputs in the list...do you know why or how it works. mybe you got an example id whrere it is working?
I only got these two and it is ever the same...

7B60A94FCDA71233 and 45AF5802CD5C1963 both should have 200 vids in the list...

thanks and i wish a happy new year to all of you

Hi from Spain.
I am very interesting to use playlist in one of my websites.
Mi english its poor. If somebody here understand spanish, please contact with me at contacto@webcam2tv.com

Thanks.

wwwwihhkhdjdlkjug;wngieok,ncjjhcpp;
gfdkaowojtunfbvkc,dlfjchxlzncbvodpoiof
igf;ajjfguoeifwwfeop-ojoeju
fugawretrggcghbn

Hey Global, can your script be modified to scrape search results for a specific term instead of a playlists? And once I have the FLV links can I save them to my DB and be done with it, or do the links periodically change, and I would need to run the script now and then to update them?

Thanks!
Gabe

First of all, Global doesn't do screen-scrapers anymore. That's too '90s technology. And they are very heavy on the maintenance.

Use the Google Data API for YouTube here: http://code.google.com/apis/youtube/overview.html

Specifically here: http://code.google.com/apis/youtube/developers_guide_protocol.html#SearchingVideosKeywords

Request search results instead of a playlist; parse the results; build an XSPF playlist.

Game over, all your base are belong to Google.

Hey YouTube, I took a look at those APIs provided by google, but there doesn't seem to be any way to access the FLV, am I missing something?

Three steps:

(1) Get the URI for the "watch" page: http://youtube.com/watch?v=yqaUHyEhGoM

(2) Make a request with it. In the returned headers or in the HTML, get the "t" parameter like this: OEgsToPDskIJ7-_v3uCp2Sao3eagbiS6

(3) Assemble a URI like this: http://youtube.com/get_video.php?video_id=yqaUHyEhGoM&t=OEgsToPDskIJ7-_v3uCp2Sao3eagbiS6

(4) Make a request with it. The final URI for the FLV will be in the returned "Location" header. Like this: Location: http://nyc-v123.nyc.youtube.com/get_video?video_id=yqaUHyEhGoM

(5) Use it like that with a "type" flashvar of "flv" or tack ".flv" on the end of the URI like this: http://nyc-v123.nyc.youtube.com/get_video?video_id=yqaUHyEhGoM.flv

See the examples posted above for doing this three step process with YouTube playlists.

Thanks for the help YouTube. I now have a script for grabbing the flv, but it doesn't work for most videos. It seems that after step 3 many videos don't have the FLV location in their header.

The links below will display the t-param, header info, and flv location (if available):

[this one works] http://pickstation.com/youtube_scrape.php?url=http://www.youtube.com/watch?v=SAQZ0BDXn48
[this one doesn't] http://pickstation.com/youtube_scrape.php?url=http://www.youtube.com/watch?v=irp8CNj9qBI

You can see my script here: http://pickstation.com/youtube_scrape.phps
If you have any ideas on what may be wrong with my script that would be great.

Thanks!
Gabe

Nevermind, I'm an idiot. I had the video id for the working link hardcoded into the script. Works great now.

http://pickstation.com/youtube_scrape.php?id=l1u43KDiWD0

Does anyone know if the resulting FLV link expires at any point? It would be nice if I could just save that link to my DB and not worry about updating all the links periodically.

can anybody help me to extract the title and author using gdata from youtube,and put in a file??

What is your original source of the link and what sort of a request are you making to the YouTube Google Data API?

i use this function for the author:

function getauthor($videoid){
$yt_xml_author_string = file_get_contents("http://www.youtube.com/api2_rest?method=youtube.videos.get_details&dev_id=BnvzCjJ_Bzw&video_id=".$videoid);
$yt_xml_author_start = explode("<title>",$yt_xml_author_string,2);
$yt_xml_author_end = explode("</title>",$yt_xml_author_start[1],2);
$yt_author = addslashes($yt_xml_author_end[0]);
return $yt_author;
}

So how do you incorporate YouTube_Playlist_XSPF.php v3.1 into multiple playlist page?
http://home5.inet.tele.dk/nyboe/flash/mediaplayer/multipleplaylists.htm

v1ktor

I am trying to play YouTube playlists on the new 3.16 player. Can anyone help with this?

I am not too familiar with the API and related programming.

How do I use this where i have a PHP website and I want to be able to access the YouTube playlist and associated videos to be shown on the local site in the FLV player?

Thx

Basically, get global's code from 21.12.2007 and call that script from your player as the 'file' flashvar value.s1.addVariable("file","YouTube_Playlist_XSPF.php?playlistid=" + playlist);where playlist is the YouTube playlist id like this:

<body onload="createjwplayer('player1','9A337BB0628CF018');">

See the 03.12.2007 post for the full details.

Thx AJAX.. I will look into this and try it!

AJAX do you have an example site with this script being used with 3.16??? This would be of help Thx!

Hi I tried this:

`
<script type="text/javascript" src="swfobject.js"></script>

<script type="text/javascript">
function createplayer() {
var s = new SWFObject("mediaplayer.swf","playerID","400","245","7");
s.addParam("allowfullscreen","true");
s.addVariable("file","youtube_playlist.php?playlistid=CAEA82831F4E96C2");
s.addVariable("width","400");
s.addVariable("height","245");
s.addVariable("displayheight","225");
s.addVariable("overstretch","fit");
s.write("placeholder");
}

</script>
`
This gives me the player on the page but plays nothing.

Any ideas what am I doing wrong?

Hi AJAX,

Many Thx for your reply.

I looked at your source and tried to re-create the solution to get this to work.

But It does not for some reason. Here is the source-code I created:

YouTube_playlist.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

<head>

<title>YouTube Playlist</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style type="text/css">
body
{
font-family: arial, helvetica, serif;
background: #FFFFFF;
padding: 8px;
margin: 0px;
}

button
{
float: left;
position: relative;
top: 0px;
left: 0px;
width: 180px;
font-size: 70%;
text-align: center;
}

div.playlistname
{
position: absolute;
top: 8px;
left: 8px;
font-size: 8pt;
}

div.playlistcount
{
position: absolute;
top: 8px;
left: 486px;
font-size: 8pt;
}

div.player
{
position: absolute;
top: 30px;
left: 8px;
width: 540px;
}
</style>

<script type='text/javascript' src='swfobject.js'></script>

<script type='text/javascript' src='playlistCount.js'></script>

<script type='text/javascript'>
function createPlayer(player, playlist)
{
var s1 = new SWFObject('mediaplayer.swf', 'mpl', '540', '655', '7');
s1.addVariable('width', '540');
s1.addVariable('height', '655');
s1.addVariable('displaywidth', '540');
s1.addVariable('displayheight', '404');

//...YouTube Playlist
s1.addVariable('file', 'youtube_playlist.php?playlistid=' + playlist);

//s1.addVariable('type', 'flv');
//s1.addVariable('useaudio', 'true');
//s1.addVariable('bwfile', '100k.jpg');
//s1.addVariable('bwstreams', '128,256,512,1024,1536');
//s1.addVariable('bwstreams', '100,256');
//s1.addVariable('file', 'video.flv');

s1.addVariable('usecaptions', 'true');
//s1.addVariable('captions', 'captions.xml');

//s1.addVariable('overstretch', 'true'); // expands to fit h & v "true" -will stretch them proportionally to fill the display
s1.addVariable('overstretch', 'false'); // expands to fit h or v "false" -will stretch them to fit
//s1.addVariable('overstretch', 'fit'); // expands to fit h & v "fit" -will stretch them disproportionally to fit both height and width
//s1.addVariable('overstretch', 'none'); // displays native size "none" -will show all items in their original dimensions

s1.addVariable('autostart', 'false');
s1.addVariable('shuffle', 'false');
s1.addVariable('repeat', 'true');
//s1.addVariable('thumbsinplaylist', 'false');

//...Interaction flashvars
s1.addVariable('linkfromdisplay', 'true');
s1.addVariable('linktarget', '_blank');

//...Appearance flashvars
s1.addVariable('bufferlength', '2');
s1.addVariable('showdigits', 'true');
s1.addVariable('showicons', 'false');
s1.addVariable('showstop', 'true');

s1.addVariable('backcolor', '0xFFFFFF'); // face of buttons
s1.addVariable('frontcolor', '0x404040'); // button symbols & playlist text
s1.addVariable('lightcolor', '0x808080'); // highlighted playlist item
s1.addVariable('screencolor', '0xFFFFFF'); // screen background color

//...Statistics flashvars
//s1.addVariable('callback', 'statistics.php');
// s1.addVariable('callback', 'statistics_CSV-3.php');

s1.addVariable('logo', 'smalllogo.png');
s1.write(player);

//...Good
//loadXMLDocpC('playlist.xml');

loadXMLDocpC('youtube_playlist.php?playlistid=' + playlist);
};
</script>

</head>

<body onload="createPlayer('player1', '95DCE71CEE658EDC'); dT();">

<div id="playlistname" class="playlistname">
 
</div>
<div id="playlistcount" class="playlistcount">
 
</div>
<div class="player">
<button onClick="createPlayer('player1', '95DCE71CEE658EDC');">Top Ten</button>
<button onClick="createPlayer('player1', '06506D40D21DBC28');">Asian Pop</button>
<button onClick="createPlayer('player1', 'CAEA82831F4E96C2');">Bhangra</button>
<button onClick="createPlayer('player1', '084C69332ECD1282');">Bollywood</button>
<button onClick="createPlayer('player1', 'EB4C529EEEE81295');">Fashion</button>
<button onClick="createPlayer('player1', '9BA4E4CBB3A5C386');">Food</button>
<button onClick="createPlayer('player1', 'B6535E091D2BC943');">Health & Beauty</button>
<button onClick="createPlayer('player1', 'ED787F760C7E2013');">Sport</button>

<div id="player1" class="player1">
<a href="http://www.macromedia.com/go/getflashplayer">Get the Flash Plugin</a>
to see this gallery.
</div>
</div>

</body>

</html>

I found playlistCount.php as follows:

var xmlhttp;
var xmlDoc;

function loadXMLDocpC(XMLFile)
{
xmlhttp = null;

pl = document.getElementById('playlistname');
pl.innerHTML = 'Playlist: ' + XMLFile;

if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
}

if (xmlhttp!=null)
{
xmlhttp.onreadystatechange = loadedpC;
xmlhttp.open('GET', XMLFile, true);
xmlhttp.send(null);
}
else
{
alert('Sorry, your browser just blew up!');
return;
}
}

function loadedpC()
{
if((xmlhttp.readyState == 4) && (xmlhttp.status == 200))
{
xmlDoc = xmlhttp.responseXML.documentElement;
playlistTracks = xmlDoc.getElementsByTagName('track').length;

le = document.getElementById('playlistcount');
le.innerHTML = 'Tracks: ' + playlistTracks;
tr = document.getElementById('tracks');
tr.innerHTML = 'Tracks: ' + playlistTracks;
}
}

and my YouTube playlist player php is :

<?php

// YouTube_Playlist_XSPF.php v3.1 20071221
// playlists need to be updated at least every 2 hours
// call with: http://some.site.org/YouTube_Playlist_XSPF-3.1?playlistid=9A337BB0628CF018

$update_interval = 2;
$cachedirectory = 'cache/';

// for command line argument passing
if (isset($_SERVER['argv'][1]))
{
$_GET['playlistid'] = $_SERVER['argv'][1];
}

$playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "CAEA82831F4E96C2";

// max-results is limited to 50 per request, total of 100 for playlists
// http://gdata.youtube.com/feeds/api/playlists/ 9A337BB0628CF018 ?start-index=1&max-results=50
$playlisturl1 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=1&max-results=50";
$playlisturl2 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=51&max-results=50";

// create cache filename
$patterns = array('#gdata#', '#/#', '#:#', '#\.#', '#http#', '#youtube#', '#com#', '#feeds#', '#api#', '#playlists#', '#\?start-index=1&max-results=50#');
$replacements = array( '', '', '', '', '', '', '', '', '', 'playlists_', '');
$filename = preg_replace($patterns, $replacements, $playlisturl1);

for ($i=0; $i < $update_interval; $i++)
{
$cachefilename = (date('YmdH') - $i) . '_' . $filename . ".xml";
if (file_exists($cachedirectory . $cachefilename))
{
if (!isset($_SERVER['argv'][1]))
{
header ("content-type: text/xml");
print file_get_contents($cachedirectory . $cachefilename);
}
exit;
}
}

$cachefilename = date('YmdH') . '_' . $filename . ".xml";

$playlistcontent1 = file($playlisturl1);
$playlistcontent2 = file($playlisturl2);
$playlistcontent = array_merge($playlistcontent1, $playlistcontent2);

$contentstring = "";
foreach($playlistcontent as $value)
{
$contentstring .= rtrim($value);
}

$contentarray = explode("<entry>", $contentstring);

$track = 0;
$type = '';

// construct XSPF playlist headers
$playlist = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$playlist .= "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
$playlist .= " <trackList>\n";

// construct XSPF playlist tracks
while($junk = next($contentarray))
{
$track++;
$playlist .= " <track>\n";

if ((preg_match('/<title>(.*?)<\/title>/', $junk, $match)) || (preg_match('/<title type=\'text\'>(.*?)<\/title>/', $junk, $match)))
{
$playlist .= " <title>" . $match[1] . "</title>\n";
}
if (preg_match('/<name>(.*?)<\/name>/', $junk, $match))
{
$playlist .= " <author>" . $match[1] . "</author>\n";
if ($match[1] == 'universalmusicgroup')
{
$type = 'UMG';
}
}
// <media:thumbnail url='http://img.youtube.com/vi/izoZ-hjbKJQ/0.jpg
if (preg_match('/<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=\'(.*?)0.jpg/', $junk, $match))
{
$playlist .= " <image>" . $match[1] . "0.jpg</image>\n";
}
// <media:content url=\'http:\/\/www.youtube.com\/v\/ds6oTHYmqRc\' type
if (preg_match('/<media:content url=\'http:\/\/www.youtube.com\/v\/(.*?)\' type/', $junk, $match))
{
$videoid = $match[1];
// http://youtube.com/v/ds6oTHYmqRc.swf
$page = @file_get_contents('http://youtube.com/v/' . $videoid . '.swf');
if ((preg_match('/&t=(.*?)&/', $http_response_header[4], $match)) || (preg_match('/&t=(.*)/', $http_response_header[4], $match)))
{
$playlist .= " <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
}
}
else if (preg_match('/<media:player url=\'http:\/\/www.youtube.com\/watch\?v=(.*?)\'/', $junk, $match))
{
$videoid = $match[1];
$page = @file_get_contents('http://youtube.com/watch?v=' . $videoid);
// check html in $page for: var swfArgs = {video_id:'lNvWoi0TesY',l:'217',t:'OEgsToPDskKER2zcpXlSd7ZzYDMp35hB',sk:'ASVXJ-JA-T6kbJT7maMDnwC',sw:'0.05',tk:'SZEt22MOl18ADaQJ-c9onimRL-HKw9HxGyYbBkoyguEPPDq_ttbaow=='};
preg_match('/t:\'(.*?)\'/', $page, $match);
// http://www.youtube.com/get_video.php?video_id= lNvWoi0TesY & t=OEgsToPDskKER2zcpXlSd7ZzYDMp35hB
$playlist .= " <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&t=" . $match[1] . "</location>\n";
}
$playlist .= " <meta rel=\"type\">flv</meta>\n";
$playlist .= " <annotation>Track " . $track . "</annotation>\n";
$playlist .= " </track>\n";

if (($track > 19) && ($type == 'UMG'))
{
break;
}
}

// construct XSPF playlist footers
$playlist .= " </trackList>\n";
$playlist .= "</playlist>\n";

if (!isset($_SERVER['argv'][1]))
{
header ("content-type: text/xml");
print $playlist;
}

// check cache - write to cache
if (!file_exists($cachedirectory . $cachefilename))
{
$fh = fopen($cachedirectory . $cachefilename, 'a');

fwrite($fh, $playlist);

fclose($fh);
}

// cleanup cache
@$directory_handle = dir($cachedirectory);

if ($directory_handle)
{
while (false !== ($currentfile = $directory_handle->read()))
{
// 200712050018_playlists_9A337BB0628CF018.xml
if (preg_match('/(\d{10})_playlists_.*?.xml/', $currentfile, $match))
{
$currentdate = date('YmdH');

// if file is older than current hour - update interval, delete file
if ($match[1] < $currentdate - $update_interval + 1)
{
unlink($cachedirectory . $currentfile);
}
}
}
$directory_handle->close();
}

?>

I would appreciate any help to get this working. All I get is the loading screen and then a blank. The YouTube playlists are valid and all work on YouTube.

Here is my test page:

http://www.desiblitz.com/vtest/YouTube_Playlist.html

THX!!!!!!

I noticed I did not have a 'cache' directory for the php playlist script. I have created it and in it do exist XML playlists for the YouTube lists.

But still no play of the videos in the playlist in the player :-(

Thx for your ongoing help with this AJAX .. much appreciated ...

Here is an example XML playlist that was created in the cache dir.

<?xml version="1.0" encoding="utf-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track>
<title>Bollywood Fashion Show Promo</title>
<author>jamesesposito</author>
<image>http://img.youtube.com/vi/jQJRGMnkPGw/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=jQJRGMnkPGw&t=OEgsToPDskIYdc1a96Z9DXIeme7NYhOo</location>
<meta rel="type">flv</meta>
<annotation>Track 1</annotation>
</track>
<track>
<title>Shreyas Talpade - Fashion Show Om Shanti Om</title>
<author>erosentertainment</author>
<image>http://img.youtube.com/vi/aW_1vO2E8to/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=aW_1vO2E8to&t=</location>
<meta rel="type">flv</meta>
<annotation>Track 2</annotation>
</track>
<track>
<title>Indian fashion show at lakme fashion week</title>
<author>hotornotdotin</author>
<image>http://img.youtube.com/vi/2vdhT1QKs7E/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=2vdhT1QKs7E&t=OEgsToPDskLyCk__4HtlvDTBIvVr58M0</location>
<meta rel="type">flv</meta>
<annotation>Track 3</annotation>
</track>
<track>
<title>FIRST FACES-2 INDIA FASHION WEEK</title>
<author>FashionTV</author>
<image>http://img.youtube.com/vi/cOcpfoz_4OE/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=cOcpfoz_4OE&t=OEgsToPDskLCPfrphKYveXwKl95MXBsd</location>
<meta rel="type">flv</meta>
<annotation>Track 4</annotation>
</track>
<track>
<title>Kareena Saif Deepika Manish Malhotra at Lakme Fashion Week</title>
<author>erosentertainment</author>
<image>http://img.youtube.com/vi/0es8TeIDp2w/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=0es8TeIDp2w&t=</location>
<meta rel="type">flv</meta>
<annotation>Track 5</annotation>
</track>
</trackList>
</playlist>

i suspect that you are missing an essential piece of the puzzle. If you look in those XML files, you should see location elements that look like this:<location>http://www.youtube.com/get_video.php?video_id=6ppY1_uSjGs&t=OEgsToPDskLe-2gEMsbegxtKPFUhgARF</location>

The "t" parameter is essential. If it is missing, the player can't get the video file.

Sometimes YouTube changes their code slightly, and the script no longer gets the correct URI. I'll have a look at it the playlist ID that isn't working.

I'll check the code that you posted above, but that will take a while to do.

Also, you don't need the playlistCount.js anymore because there is a JavaScript function length = thisMovie('mpl').getLength(); that gets the playlist length, that is available now.

The constant changes at YouTube occasionally break these scripts. As soon as the official YouTube API is stable and has the playlists available, I am going to slim these scripts down to use it. Then, hopefully, it won't break too often.

AJAX, the call to the script is as follows in the HTML file:

//...YouTube Playlist
s1.addVariable('file', 'youtube_playlist.php?playlistid=' + playlist);

Do I now remove the playlistCount.js line????? if it is not needed?

Here is an example track from the XML playlist:

<track>
<title>Bollywood Fashion Show Promo</title>
<author>jamesesposito</author>
<image>http://img.youtube.com/vi/jQJRGMnkPGw/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=jQJRGMnkPGw&t=OEgsToPDskIYdc1a96Z9DXIeme7NYhOo</location>
<meta rel="type">flv</meta>
<annotation>Track 1</annotation>
</track>

I see it has the 't' parameter set....

If you call yor playlist generator in your browser with this URI: http://www.desiblitz.com/vtest/youtube_playlist.php?playlistid=9A337BB0628CF018 you will see that you have some kind of error on line 124.

Yes, you can remove the playCount.js line and use the getLength() function to get the playlist length wherever that is in the code???

Your URI: http://www.youtube.com/get_video.php?video_id=jQJRGMnkPGw&t=OEgsToPDskIYdc1a96Z9DXIeme7NYhOo posted above returns "The page does not exist" from Youtube. Paste it in your browser and try it.

Try the one that I posted above with an ID of 9A337BB0628CF018 I'm sure that it returns good video URIs.

Hi AJAX,

When I put

http://www.desiblitz.com/vtest/youtube_playlist.php?playlistid=9A337BB0628CF018

in my browser I got :

Warning: Cannot modify header information - headers already sent by (output started at /home/desiblitz/domains/desiblitz.com/public_html/vtest/youtube_playlist.php:2) in /home/desiblitz/domains/desiblitz.com/public_html/vtest/youtube_playlist.php on line 36
>>>>> etc.

not an error on line 124.

Is this due to two HTML headers? one in the HTML and other in the PHP player? Because line 36 in the youtube_playlist.php file is :

36: header ("content-type: text/xml");
37: print file_get_contents($cachedirectory . $cachefilename);

When I put the following in my browser:

http://www.youtube.com/get_video.php?video_id=jQJRGMnkPGw&t=OEgsToPDskIYdc1a96Z9DXIeme7NYhOo

I get a blank screen and 'Done' at the bottom (Im using Firefox).

When I run your playlist code, copied and pasted exactly from your post, it runs fine and returns a valid playlist.

URI: http://willswonders.myip.org:8085/php/Sam.php?playlistid=084C69332ECD1282

playlist:

<?xml version="1.0" encoding="utf-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track>
<title>Kareena Saif Deepika Manish Malhotra at Lakme Fashion Week</title>
<author>erosentertainment</author>
<image>http://img.youtube.com/vi/0es8TeIDp2w/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=0es8TeIDp2w&t=</location>
<meta rel="type">flv</meta>
<annotation>Track 1</annotation>
</track>
<track>
<title>Pehli Nazar Race Bollywood Atif Aslam -FULL SONG/VID</title>
<author>asianlick1</author>
<image>http://img.youtube.com/vi/eFYk1HHhs60/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=eFYk1HHhs60&t=OEgsToPDskJbvh372awrQ7lCTARfAYh7</location>
<meta rel="type">flv</meta>
<annotation>Track 2</annotation>
</track>
<track>
<title>Zara Zara Touch Me - Race*Katrina Saif</title>
<author>awesomearien</author>
<image>http://img.youtube.com/vi/FlCO6PmSIWA/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=FlCO6PmSIWA&t=OEgsToPDskIGiRkPmJB_Y0CeIpo0Vln8</location>
<meta rel="type">flv</meta>
<annotation>Track 3</annotation>
</track>
<track>
<title>Rakhi Sawant Krazzy 4 - Dekhta Hai Tu Kya (The Making)</title>
<author>erosentertainment</author>
<image>http://img.youtube.com/vi/ZltQzBK8DR8/0.jpg</image>
<location>http://www.youtube.com/get_video.php?video_id=ZltQzBK8DR8&t=</location>
<meta rel="type">flv</meta>
<annotation>Track 4</annotation>
</track>
</trackList>
</playlist>

And some but not all of the video URIs are valid. That's normal for YouTube.

Try copying and pasting them in your browser, you should get a file named get_video.php or get_video.flv that is the video file.

I don't know why your server gives that error, something with the configuration that is sending it's own output or headers before the script does. Try commenting out the headers in the script. You will still get a valid XML playlist that the Flash player will use.

Oh, one thing that will screw up the header is if you have any white space before the first "<?php". Even one space or carriage return will trigger that "Headers already sent..." error.

You might change the "&" to just "&" when you paste those video URIs in your browser. Some browsers don't like the "&amp:".

AJAX!!! It was the carriage return in my youtube_playlist.php file!!!! It's workin now!

You are a star! Thx for your help with this ...

http://www.desiblitz.com/vtest/YouTube_Playlist.html

I have not changed the

"Yes, you can remove the playCount.js line and use the getLength() function to get the playlist length wherever that is in the code???"

As I don't know where that is ... can you tell me please?

Plus, that stats.php .. ?? Can you please tell me how I can use that?

THX again!

Replace this:loadXMLDocpC('youtube_playlist.php?playlistid=' + playlist);with this:

pL = document.getElementById('playlistcount');
pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();

You also need to enable the JavaScript API in your player code:

s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'mpl');

and put the API interface code in the head of your HTML

  <script language="javascript">
    function thisMovie(movieName)
    {
      if(navigator.appName.indexOf('Microsoft') != -1)
      {
        return window[movieName];
      }
      else
      {
        return document[movieName];
      }
    };
  </script>

To use the stats, get a stats script from this thread: http://www.jeroenwijering.com/?thread=6080 or this thread: http://www.jeroenwijering.com/?thread=4815

There are many stats scripts. Some are self-contained with PHP graphs, some feed Flash graphs, some just dump to a CSV file that you can load into Excel or any other analysis program that accepts CSV files.

Then uncomment the 'callback' line in your player code and put the correct script name as the 'callback' flashvar value.

The way this:

pL = document.getElementById('playlistcount');
pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();

works is: the first line gets a reference to the HTML element with an id of 'playlistcount' (a div in this case). Then the second line writes to the innerHTML (the content) of that HTML element. It writes 'Tracks: " + (concatenate) the value received back from a call to the player asking it how many tracks it counted in the playlist. thisMovie('mpl') is a reference to the player's name and the getLength() simply asks the player for the playlist length.

Thx a lot for this and your explanations ... I will now make the changes ... as you have described :-)

I tried the above, took out the playCount.js. And added the above code. I then get this error: The playlist and is working appears but I still get this error :

thisMovie("mpl").getLength is not a function

Here is my add in the player code:

// s1.addVariable('callback', 'statistics_CSV-3.php');
s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'mpl'); .............

// loadXMLDocpC('wp-content/videos/player/playlist_player.php?playlistid=' + playlist);
pL = document.getElementById('playlistcount');
pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();
};

I added the API to a .js file in the HTML header ...

Any ideas?

Can you also tell me how I can reduce the height size of the video player screen?

I've tried changing the parameters as follows (displayheight 380) but it does not change :

var s1 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'mpl', '500', '600', '7');
s1.addVariable('width', '500');
s1.addVariable('height', '600');
s1.addVariable('displaywidth', '500');
s1.addVariable('displayheight', '380');

That's happening because the player isn't ready to respond to the getLength() request.

So replace this code:

          pL = document.getElementById('playlistcount');
          pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();

with this:playerLoaded = true;and replace the JavaScript API code with this:

  <script language="javascript">
    var playerLoaded = false;

      function getUpdate(typ, pr1, pr2, pid)
      {
        if((typ == 'state') && ((pr1 == 0) || (pr1 == 2)) && (playerLoaded))
        {
          pL = document.getElementById('playlistcount');
          pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();
          playerLoaded = false;
        }
      };

    function thisMovie(movieName)
    {
      if(navigator.appName.indexOf('Microsoft') != -1)
      {
        return window[movieName];
      }
      else
      {
        return document[movieName];
      }
    };
  </script>

AJAX,

Thx that worked ;-)

Regarding the screen display height size of the player? ... Is this the only place where I change the size?

var s1 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'mpl', '500', '600', '7');
s1.addVariable('width', '500');
s1.addVariable('height', '600');
s1.addVariable('displaywidth', '500');
s1.addVariable('displayheight', '380');

Yes, that will give you a display area of 500x380 with 200 for the playlist. You don't need to use displaywidth.

Each track with thumbnails is 41px so you should make your height 605 for a full, fifth playlist track.

AJAX,

Thx for this got it working. Now I have another little challenge with this.

I would like to create another smaller player for a different page which plays only one of the playlists.

So, to do this, I put the createplayer JS into a createPlayer.js file which has the (large) player creation code for the multiplaylist player and this code for the small player:

function createPlayerSmall(player, playlist)
{
// overall size of player
var s1 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'mpl', '300', '400', '7');
// width and height of player and playlist
s1.addVariable('width', '300');
s1.addVariable('height', '400');
// width and height of screen
s1.addVariable('displaywidth', '300');
s1.addVariable('displayheight', '240');

//...YouTube Playlist
s1.addVariable('file', 'wp-content/videos/player/playlist_player.php?playlistid=' + playlist);

//s1.addVariable('type', 'flv');
//s1.addVariable('useaudio', 'true');
//s1.addVariable('bwfile', '100k.jpg');
//s1.addVariable('bwstreams', '128,256,512,1024,1536');
//s1.addVariable('bwstreams', '100,256');

s1.addVariable('usecaptions', 'true');
//s1.addVariable('captions', 'captions.xml');
//s1.addVariable('overstretch', 'true'); // expands to fit h & v "true" -will stretch them proportionally to fill the display
s1.addVariable('overstretch', 'false'); // expands to fit h or v "false" -will stretch them to fit
//s1.addVariable('overstretch', 'fit'); // expands to fit h & v "fit" -will stretch them disproportionally to fit both height and width
//s1.addVariable('overstretch', 'none'); // displays native size "none" -will show all items in their original dimensions

s1.addVariable('autostart', 'false');
s1.addVariable('shuffle', 'false');
s1.addVariable('repeat', 'true');
//s1.addVariable('thumbsinplaylist', 'false');

//...Interaction flashvars
s1.addVariable('linkfromdisplay', 'true');
s1.addVariable('linktarget', '_blank');

//...Appearance flashvars
s1.addVariable('bufferlength', '2');
s1.addVariable('showdigits', 'true');
s1.addVariable('showicons', 'false');
s1.addVariable('showstop', 'true');

s1.addVariable('backcolor', '0xFFFFFF'); // face of buttons
s1.addVariable('frontcolor', '0x404040'); // button symbols & playlist text
s1.addVariable('lightcolor', '0x808080'); // highlighted playlist item
s1.addVariable('screencolor', '0xEEEEEE'); // screen background color

//...Statistics flashvars
//s1.addVariable('callback', 'statistics.php');
// s1.addVariable('callback', 'statistics_CSV-3.php');
s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'mpl');

s1.addVariable('logo','wp-content/videos/player/smalllogo.png');
s1.write(player);

playerLoaded = true;
};

Then to call the player, I am using the following HTML/Javascript:

<script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>
<
div id="player2">

</div>

Also in the header of the HTML I have:
<script type='text/javascript' src='wp-content/videos/player/swfobject.js'></script>
<script type='text/javascript' src='wp-content/videos/player/apiFunc.js'></script>
<script type='text/javascript' src='wp-content/videos/player/createPlayer.js'></script>

I get the following error coming from the swfobject.js (which also is used by imageRotator on the same page):
n has no properties
n.innerHTML=this.getSWFHTML();return true;

Any ideas????????????? THX

Are you using a unique name/id for each player.

Something like 'mpl1' and 'mpl2"

Youtube,

No I wasn't .. but I changed it .. and it still has not worked. There error is here in line 81 in swfobject.js

document.title=document.title.slice(0,47)+" - Flash Player Installation";
78this.addVariable("MMdoctitle",document.title);}}
79if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){
80var n=(typeof _20=="string")?document.getElementById(_20):_20;
81n.innerHTML=this.getSWFHTML();return true;
82}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}
83return false;}};

Are the any problems with the Image rotator and flash player being on same page????? Using the same swfobject.js?

No problem using the Image Rotator and the Media Player on the same page. You only need to load swfobject once.

Post your full code so I can take a look at it.

Hi AJAX,

Here is the code and solution as implemented currently. I get no player appearing on the page. It is blank. I use 'firebug' to debug using Firefox. Firebug identified the error:

n has no properties

write("player2") swfobject.js (line 81)
createPlayerSmall("player2", "95DCE71CEE658EDC")

n.innerHTML=this.getSWFHTML();return true;

1. HTML

In the head of html page.

<script type='text/javascript' src='wp-content/videos/player/apiFunc.js'></script>
<script type='text/javascript' src='wp-content/videos/player/createPlayer.js'></script>

Calling HTML code in different page:

<script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>
<div id="player2">

</div>
________________________________________________________________________________________________

2. createPlayer.js - two players : createPlayer and createPlayerSmall functions. It is CreatePlayerSmall called in this case.

function createPlayer(player, playlist)
{
// overall size of player
var s1 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'mpl1', '430', '600', '7');
// width and height of player and playlist
s1.addVariable('width', '430');
s1.addVariable('height', '600');
// width and height of screen
s1.addVariable('displaywidth', '430');
s1.addVariable('displayheight', '340');

//...YouTube Playlist
s1.addVariable('file', 'wp-content/videos/player/playlist_player.php?playlistid=' + playlist);

//s1.addVariable('type', 'flv');
//s1.addVariable('useaudio', 'true');
//s1.addVariable('bwfile', '100k.jpg');
//s1.addVariable('bwstreams', '128,256,512,1024,1536');
//s1.addVariable('bwstreams', '100,256');

s1.addVariable('usecaptions', 'true');
//s1.addVariable('captions', 'captions.xml');
//s1.addVariable('overstretch', 'true'); // expands to fit h & v "true" -will stretch them proportionally to fill the display
s1.addVariable('overstretch', 'false'); // expands to fit h or v "false" -will stretch them to fit
//s1.addVariable('overstretch', 'fit'); // expands to fit h & v "fit" -will stretch them disproportionally to fit both height and width
//s1.addVariable('overstretch', 'none'); // displays native size "none" -will show all items in their original dimensions

s1.addVariable('autostart', 'false');
s1.addVariable('shuffle', 'false');
s1.addVariable('repeat', 'true');
//s1.addVariable('thumbsinplaylist', 'false');

//...Interaction flashvars
s1.addVariable('linkfromdisplay', 'true');
s1.addVariable('linktarget', '_blank');

//...Appearance flashvars
s1.addVariable('bufferlength', '2');
s1.addVariable('showdigits', 'true');
s1.addVariable('showicons', 'false');
s1.addVariable('showstop', 'true');

s1.addVariable('backcolor', '0xFFFFFF'); // face of buttons
s1.addVariable('frontcolor', '0x404040'); // button symbols & playlist text
s1.addVariable('lightcolor', '0x808080'); // highlighted playlist item
s1.addVariable('screencolor', '0xEEEEEE'); // screen background color

//...Statistics flashvars
//s1.addVariable('callback', 'statistics.php');
// s1.addVariable('callback', 'statistics_CSV-3.php');
s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'mpl');

s1.addVariable('logo','wp-content/videos/player/smalllogo.png');
s1.write(player);

//...Good
// loadXMLDocpC('wp-content/videos/player/playlist_player.php?playlistid=' + playlist);
playerLoaded = true;
};

function createPlayerSmall(player, playlist)
{
// overall size of player
var s1 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'mpl2', '300', '400', '7');
// width and height of player and playlist
s1.addVariable('width', '300');
s1.addVariable('height', '400');
// width and height of screen
s1.addVariable('displaywidth', '300');
s1.addVariable('displayheight', '240');

//...YouTube Playlist
s1.addVariable('file', 'wp-content/videos/player/playlist_player.php?playlistid=' + playlist);

//s1.addVariable('type', 'flv');
//s1.addVariable('useaudio', 'true');
//s1.addVariable('bwfile', '100k.jpg');
//s1.addVariable('bwstreams', '128,256,512,1024,1536');
//s1.addVariable('bwstreams', '100,256');

s1.addVariable('usecaptions', 'true');
//s1.addVariable('captions', 'captions.xml');
//s1.addVariable('overstretch', 'true'); // expands to fit h & v "true" -will stretch them proportionally to fill the display
s1.addVariable('overstretch', 'false'); // expands to fit h or v "false" -will stretch them to fit
//s1.addVariable('overstretch', 'fit'); // expands to fit h & v "fit" -will stretch them disproportionally to fit both height and width
//s1.addVariable('overstretch', 'none'); // displays native size "none" -will show all items in their original dimensions

s1.addVariable('autostart', 'false');
s1.addVariable('shuffle', 'false');
s1.addVariable('repeat', 'true');
//s1.addVariable('thumbsinplaylist', 'false');

//...Interaction flashvars
s1.addVariable('linkfromdisplay', 'true');
s1.addVariable('linktarget', '_blank');

//...Appearance flashvars
s1.addVariable('bufferlength', '2');
s1.addVariable('showdigits', 'true');
s1.addVariable('showicons', 'false');
s1.addVariable('showstop', 'true');

s1.addVariable('backcolor', '0xFFFFFF'); // face of buttons
s1.addVariable('frontcolor', '0x404040'); // button symbols & playlist text
s1.addVariable('lightcolor', '0x808080'); // highlighted playlist item
s1.addVariable('screencolor', '0xEEEEEE'); // screen background color

//...Statistics flashvars
//s1.addVariable('callback', 'statistics.php');
// s1.addVariable('callback', 'statistics_CSV-3.php');
s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'mpl');

s1.addVariable('logo','wp-content/videos/player/smalllogo.png');
s1.write(player);

//...Good
// loadXMLDocpC('wp-content/videos/player/playlist_player.php?playlistid=' + playlist);
playerLoaded = true;
};

_____________________________________________________________________________________________

3. APIfunc.js

var playerLoaded = false;

function getUpdate(typ, pr1, pr2, pid)
{
if((typ == 'state') && ((pr1 == 0) || (pr1 == 2)) && (playerLoaded))
{
pL = document.getElementById('playlistcount');
pL.innerHTML = 'Tracks: ' + thisMovie('mpl').getLength();
playerLoaded = false;
}
};

function thisMovie(movieName)
{
if(navigator.appName.indexOf('Microsoft') != -1)
{
return window[movieName];
}
else
{
return document[movieName];
}
};
____________________________________________________________________________________________

4. swfobject.js is latest. Path of swfobject is from imagerotator swfobject.js not media player ... same version for both used.

SWFObject v1.4.4: Flash Player detection and embed - http://blog.deconcept.com/swfobject/

____________________________________________________________________________________________________

5. Loaded once. Error line 81. Error appears in the swfobject.js (image rotator one).

if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){
80var n=(typeof _20=="string")?document.getElementById(_20):_20;
81n.innerHTML=this.getSWFHTML();return true;
82}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}
83return false;}};

______________________________________________________________________________________________

THX for your help with this.

Since my last post. I noticed my Javascript ID and Object ID were different for both players. I have now corrected those for both players. But it still does not work.

I still get the same error.

I also put in the following for HTML:

<script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>
<div id="player2">
Video player
</div>

All I gets is 'Video Player' output on the page. Plus the error in firebug - 'n' has no properties.

Hi AJAX and YouTube,

I worked out what the problem was and thought I would share this with you and others. To get this to work I looked at an example here:

http://blog.deconcept.com/swfobject/forum/discussion/2/swfobject-faq/#Item_0

And it showed me the <div></div> for the player were ABOVE the call to the SWFobject code. So, I changed this:

script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>
<div id="player2">
Video player
</div>

TO THIS:

<div id="player2">
Video player
</div>
script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>

And changed my CreateSmallPlayer function to have s2.xxxx instead of s1.xxx for the variables ... e.g.

var s2 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'plyr2', '300', '400', '7');
// width and height of player and playlist
s2.addVariable('width', '300');
s2.addVariable('height', '400');
// width and height of screen
s2.addVariable('displaywidth', '300');
s2.addVariable('displayheight', '240');

......

and importantly ...

s2.write(player);

After the swap of the <div></div> in the HTML above the SWFObject call ... it worked!!! ....

ALSO - swfobject.js version 2.0 is out you can get it here:

http://code.google.com/p/swfobject/

@Sam,

Yes, you cannot write to an HTML element that has not been loaded yet.

That's why we put all JavaScript code in the head element and call the functions to load the player after the HTML has fully loaded.

I'm glad to see that you got your players working. That means that I can cross you off of my TODO list (you were next).

Yes, swfobject v2.0 seems to work well, even in the most complicated applications that I have.

AJAX,

Thx for your reply. I have problems with the full screen button not working since swfobject 2.0 was implemented. I put up this query in the swfobject thread. So, am looking to understand how I can get it to work...

Thx

@Sam,

fullscreen works with swfobject v2.0, did you set allowfullscreen in your params?:

        var params =
        {
        //menu:               'false',
          allowfullscreen:    'true',
          swliveconnect:      'true',
          wmode:              'opaque'
        };

AJAX,

I am having another little problem ...

<script type='text/javascript' src='wp-content/videos/player/apiFunc.js'></script>
<script type='text/javascript' src='wp-content/videos/player/createPlayer.js'></script>

These two lines in my header file are giving me a 404 error on another page I want to display the video player.

This works on my home page but when I use the same header for another page I get the 404 error...

The scripts are not being found??? As I get the error createSmallPlayer() not defined due to the scripts not being located..

I'm confused .. Any Ideas?

Just use a full URI:<script type='text/javascript' src='<strong>http://my.domain.com/path</strong>/wp-content/videos/player/apiFunc.js'></script>

If you are on virtual hosting, your real domain and path may not really be what you think it is, so make sure that you use the correct domain and path.

AJAX,

Thx for your swift reply.. The full URI worked.

With regards to the parameters ...I added it to createplayer.js like this :

var s2 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'plyr2', '300', '400', '7');
// add fullscreen
s2.addParam('allowfullscreen','true');
s2.addParam("swliveconnect", 'true');

And it worked...

Thx!!! for all your help...

I thought that you had converted to swfobject v2.0.

What are you doing using that obsolete code?

Anyway, good to hear that it worked.

AJAX,

I now have a problem on my main VIDEOS page. Please see here:

http:://www.desiblitz.com/videos

When u click on a button, it shows the playlist and thumbnails. When I click on a video I get a blank screen in the player. Nothing happens. The code for the player is :

<div id="video-page">
<div class="player">
<button onclick="createPlayer('player1', '95DCE71CEE658EDC');">Editors 10</button><br />
<button onclick="createPlayer('player1', '06506D40D21DBC28');">Asian Pop</button><br />
<button onclick="createPlayer('player1', 'CAEA82831F4E96C2');">Bhangra</button><br />
<button onclick="createPlayer('player1', 'B2BA8BBA11BBA5A0');">Punjabi Folk</button><br />
<button onclick="createPlayer('player1', '084C69332ECD1282');">Bollywood New</button><br />
<button onclick="createPlayer('player1', 'ECF5137376214422');">Bollywood Gold</button><br />
<button onclick="createPlayer('player1', 'D8935A73C02DC50C');">Classical</button><br />
<button onclick="createPlayer('player1', '255A81461ACEE507');">Ghazals</button><br />

<button onclick="createPlayer('player1', 'CBE6229288841CF0');">Qawwalis</button><br />
<button onclick="createPlayer('player1', 'EB4C529EEEE81295');">Fashion</button><br />
<button onclick="createPlayer('player1', '9BA4E4CBB3A5C386');">Food</button><br />
<button onclick="createPlayer('player1', 'B6535E091D2BC943');">Health & Beauty</button><br />
<button onclick="createPlayer('player1', 'ED787F760C7E2013');">Sport</button><br />
<button onclick="createPlayer('player1', '020296544BB29E41');">Funtastic</button><br />
<button onclick="createPlayer('player1', 'ED73EFF9BB8D5BFD');">News Blitz</button></p>
<div id="player1" class="player1"><<< Click on any of the categories to view the current selection of videos.</div>

</div>
</div>

And in the header are :
<script type='text/javascript' src='http://www.desiblitz.com/wp-content/videos/player/swfobject.js'></script>
<script type='text/javascript' src='http://www.desiblitz.com/wp-content/videos/player/apiFunc.js'></script>
<script type='text/javascript' src='http://www.desiblitz.com/wp-content/videos/player/createPlayer.js'></script>

But the smaller 2nd video player on the home page works. See it under 'Featured Videos'.

Any ideas?

I read on this thread that the http header has changed from 4 to 5 :

http://www.jeroenwijering.com/?thread=5484

So, I changed the playlist player code :

//if ((preg_match('/&t=(.*?)&/', $http_response_header[4], $match)) || (preg_match('/&t=(.*)/', $http_response_header[4], $match)))
if ((preg_match('/&t=(.*?)&/', $http_response_header[5], $match)) || (preg_match('/&t=(.*)/', $http_response_header[5], $match)))

This has worked.

@Sam,

You have to change the header from 4 to 5 in the playlist code:if ((preg_match('/&t=(.*?)&/', $http_response_header[5], $match)) || (preg_match('/&t=(.*)/', $http_response_header[5], $match)))Then load your playlist in your browser ( http://www.desiblitz.com/wp-content/videos/player/playlist_player.php?playlistid=CBE6229288841CF0 ) and you should have location elements that look like this:<location>http://www.youtube.com/get_video.php?video_id=SffvLFuHn0Q&t=OEgsToPDskKOGiA71N3DqhNjk_3o2s_J</location>I tried it and your playlist generator is working.

AJAX,

Thx .. I got it working!

Regarding the playing of YouTube playlists and players. Do I have to create different player functions for every time I want to create a new player on a different page? e.g. players to play different playlists based on conditional criteria like category - sports (playlist) videos for sports category selected on the site.

Or can I use the same function in my createplayer.js but sending it a different player DIV id?

Any value in the JavaScript functions can be replaced with a JavaScript variable.

So you can call the createPlayer function with variables for file, image, div, etc.

function createPlayer(aWidth, aDisplaywidth, aPlaceholder)
{
var s2 = new SWFObject('wp-content/videos/player/mediaplayer.swf', 'plyr2', aWidth, '400', '7');
// width and height of player and playlist
s2.addVariable('width', aWidth);
s2.addVariable('height', '400');
// width and height of screen
s2.addVariable('displaywidth', aDisplaywidth);
s2.addVariable('displayheight', '240');
......
s2.write(aPlaceholder);
}

called with:createPlayer('300', '300', 'placeholder');

Also, you might take a look at this demo to see how to create a player on demand from a link or an image:http://willswonders.myip.org:8085/php/Multiple%20Players.html

Thx for your reply.

Does the DIV id have any impact on the javascript ID? e.g. plyr2 in the above example?

<div id="player2">
Video player
</div>
script type='text/javascript'>
createPlayerSmall('player2', '95DCE71CEE658EDC');
</script>

The Youtube API doesn't yet support the higher resolution feeds.

Hi, my name is lynxx... here's my site: http://123.gotdns.com . actually I'm hosting it at home...
If you can't connect, then probably my pc is off, as I'm hosting at home...

Recently, I've found out how to use youtube and megavideo 's flv files to your jwplayer... Actually, I found this by trial and error...

You can do this for youtube, first get the link, then, go to keepvid.com and crack the link... YOu will get something like this:

http://www.youtube.com/get_video?video_id=3tXBjqmxkZg&t=OEgsToPDskK797PkJwOIPc10njluY6Cp

After you got this, just add "&type=flv" at the end part of the link.. It will look like this:

http://www.youtube.com/get_video?video_id=3tXBjqmxkZg&t=OEgsToPDskK797PkJwOIPc10njluY6Cp&type=flv

It will work on jwplayer playlist...

Give credits if it worked for you... I'm currently using it on my anime section..

AJAX,

Is there a way to search the playlists? And use the search bar on the player?

Since the playlists are in a folder and are XML files, would it be possible to create a php/javascript search script for the playlists?

Thx

I deleted a playlist with 92 videos from youtube how can i retrieve it back?
thanks

ps. how can i have a backup of my playlists for further carelessness?

Hi,

I've been trying to implement the YT playlist code on my site. To see what it produced I just ran it standalone with my playlist id and I get the problem noted further up the thread :

The XML page cannot be displayed

Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.

--------------------------------------------------------------------------------

Only one top level element is allowed in an XML document. Error processing resource 'http://www.mysite.co.uk/site/m...

<br />
-^

There are 24 videos in the playlist and it seems to be falling over on no 21 - not sure where that break is coming from.

Could anyone suggest what might be causing this please ?

Edit - Solved it !!

fvsdvsdcdcsdcsdcsdc

Does anyone know if something has changed in the YouTube API that has affected the way this PHP script converts <media:content url> or <media:player url> to <location>? I have implemented the script and everything is working great except for that the XML file has no <location> elements at all.

I noticed that the script that AJAX said was working in the 12.04.2008 post now does not generate <location>
http://willswonders.myip.org:8085/php/Sam.php?playlistid=084C69332ECD1282

But that same script does generate <location> with some playlist ID's, e.g.:
http://willswonders.myip.org:8085/php/Sam.php?playlistid=FA50FBC214A6CE87

However, I still get no <location> with either of the above playlist IDs with my script (I'm using the exact script from Global's post on 21.12.2007).

Does anybody (AJAX, if you're out there?) know anything about this?

update: I think I figured out what was going on. The syntax for the t variable in the YouTube pages seems to have changed.

I've commented out the <media:content url... part because I can't see the source of the swf file to fix this:

$page = @file_get_contents('http://youtube.com/v/' . $videoid . '.swf');
if ((preg_match('/&t=(.*?)&/', $http_response_header[4], $match)) || (preg_match('/&t=(.*)/', $http_response_header[4], $match)))

(though maybe someone else knows how to do that?)

And then in the <media:player url... part, I looked at the source of this page (http://youtube.com/watch?v=Pin8fbdGV9Y) and then changed:

preg_match('/t:\'(.*?)\'/', $page, $match);

to

preg_match('/\"t\": \"(.*?)\"/', $page, $match);

And that seems to do the trick.

The response header changed from [4] to [5]if ((preg_match('/&t=(.*?)&/', $http_response_header[5], $match)) || (preg_match('/&t=(.*)/', $http_response_header[5], $match)))

<media:player url...</strong> should look like this:else if (preg_match('/<media:player url=\'http:\/\/www.youtube.com\/watch\?v=(.*?)\'/', $junk, $match))

Full, messy, debug source here: <strong>http://willswonders.myip.org:8085/php/YouTube_Playlist_XSPF-3.1.php.txt

I am using the script provided above by Global to generate and embed xspf playlists originated from youtube playlists.

Everything works as it should only that after a certain time - about 45-60 minutes - the playlist localy cached becomes obsolete as the location urls listed in there are not any more valid, as per arrangemet of the youtube server. As a result the playlist keeps scrolling and scrolling and no reproduction of any video takes place anymore, needing to refresh the generation of the playlist.

I verified such behavior by testing the location urls immediately after the list was generated, which properly it would point to the flv file ( prompting "get_video" "which is a: video/flv" ) and testing the same url after a while and nothing would happen, indicating like this that the url of the flv file changed.

As a matter of fact, examining the url of the video downloaded from youtube it reveals that has a time stamp and expiry included:
http://chi-v248.chi.youtube.com/get_video?video_id=MWTsTvmHAFI&signature=B953151A2303F00C46C0D5215EC...
52D3889AA.9D2859BE90727584378617C44ABBC0E8E06B517B&ip=84.223.64.1&ipbits=16&expire=1213554120
&key=yt1&sver=2

So the question is, what I think it could solve the problem, how to force a reload of the script after a determined time and overwriting the local cached playlist, to make sure that the urls are freshly generated and the playlist ( generally of many videos ) keeps playing properly?

In light of this I also would consider the function of caching the generated xml files on the server for 2 hours in order to not overload the youtube server is also not neccesary as the xml files generated become obsolete after the above mentioned 45-60 minutes because of the automatically changed urls.

Please comment and suggest.

@jivatma

how about using the v.3.16 (+) player - it uses the youtube api ? - http://www.jeroenwijering.com/?page=wizard&example=6

then all you need is to enter the page url of the videos into the playlist - http://www.youtube.com/watch?v=MWTsTvmHAFI
this url format should be easy to construct from the youtube playlists also - and are (more) permanent...

Thanks andersen,

I am already using the v.3.16 player and the "YouTube_Playlist_XSPF.php" script does make use of the youtube api to generate the xspf lists.

In the beggining I thought of using that facility that you indicated but as I am using a playlist of several playlists I found the script of Global that creates them effortelesly simply by inserting the code of the youtube playlist instead of having to insert each individual movie url I wouldn't depart easily from such solution.

I have examined closely the page with all the possible implementations of the player (http://home5.inet.tele.dk/nyboe/flash/mediaplayer/) which has wonderful extensions and I congratulate you for the good work but still I am inclined to find some kind of solution for the above mentioned script as it creates a tv like experience which I am trying to do.

Any further suggestions?

@jivatma - ok, then how about the followng scheme:

use the javascript api, to check every time a video has finished, if more than a certain time has passed -
and then refresh the player, fetching the playlist again, in a new version with valid urls.
you can save the itemnumber of the current video first, to make sure to start with the next item in the fresh playlist...

Thanks again andersen.

Sounds good, any example of code that would do such a thing?

I also examined closely these examples that looked like they could accomplish what is desired:

# to load a new playlist after a timeout: redirectdaisychain and by playlist-length: redirectdaisychainbylength
# to quit playing after a timelimit: snippetplayer

and may be they do but my knowledge is not sufficient to combine Global's script with any of these and/or what you suggest.

So how do we go from here?

@jivatma - i think you are correct in that those demos are quite close to what you would need

unfortunately my provider doesnt permit the use of php (and i dont really know php) so i cant test the actual php part

but it should only be a matter of a few lines of script to refresh the playlist after a certain time...

can you please confirm that globals script is used by just pointing to it in the file flashvar ?
if so, i think i can make a test with a regular static playlist...

@andersen - this one below is the java script that creates the player and as you see the file flashvar is pointing to the php script that generates dynamically the xspf playlist:

s1.addVariable('file', 'http://www.mysite.com/playlist_player.php?playlistid=' + playlist);

Then that generated list resides in the cache of the browser and provides the location urls of the flv movies. The desired goal is to call that script again after x minutes in order to generate a fresh xspf list. How would this be accomplished without refreshing the whole page?

This is the whole java script:

function createPlayer(player, playlist)
{
// overall size of player
var s1 = new SWFObject('http://www.mysite.com/mediaplayer.swf', 'plyr1', '430', '600', '7');
// add fullscreen
s1.addParam('allowfullscreen','true');
s1.addParam('allowscriptaccess','always');
// s1.addParam("swliveconnect", 'true');
// width and height of player and playlist
s1.addVariable('width', '430');
s1.addVariable('height', '600');
// width and height of screen
s1.addVariable('displaywidth', '430');
s1.addVariable('displayheight', '340');

//Playlist
s1.addVariable('file', 'http://www.mysite.com/playlist_player.php?playlistid=' + playlist);
s1.addVariable('usecaptions', 'true');
s1.addVariable('overstretch', 'false');
s1.addVariable('autostart', 'true');
s1.addVariable('shuffle', 'true');
s1.addVariable('repeat', 'true');
//...Interaction flashvars
s1.addVariable('linkfromdisplay', 'true');
s1.addVariable('linktarget', '_blank');

//...Appearance flashvars
s1.addVariable('bufferlength', '2');
s1.addVariable('showdigits', 'true');
s1.addVariable('showicons', 'false');
s1.addVariable('showstop', 'true');

s1.addVariable('backcolor', '0xFFFFFF'); // face of buttons
s1.addVariable('frontcolor', '0x404040'); // button symbols & playlist text
s1.addVariable('lightcolor', '0x808080'); // highlighted playlist item
s1.addVariable('screencolor', '0xEEEEEE'); // screen background color

s1.addVariable('enablejs', 'true');
s1.addVariable('javascriptid', 'plyr1');

s1.addVariable('logo','http://www.mysite.com/smalllogo.png');
s1.write(player);

// call to API
playerLoaded = true;
};

My site is the exact replica more or less of
http://www.desiblitz.com/videos

here is code that refreshes the playlist before playing the next item, if a certain time has passed since starting to play -
you can see it in action here - http://home5.inet.tele.dk/nyboe/flash/mediaplayer/refreshlist.htm

<HTML><HEAD><TITLE>refresh list example</TITLE>

<SCRIPT src="swfobject.js" type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
var currentItem;
var currentState;
var timerFlag;
var playFlag;
var timerID;
var oldItem;

function sendEvent(typ,prm) { thisMovie("playerID").sendEvent(typ,prm); };

function getUpdate(typ,pr1,pr2,swf) {
if(typ == "item") { currentItem = pr1; }
else if(typ == "state") {
currentState = pr1;
if ((currentState==3)&&(timerFlag)) {
oldItem = currentItem;
createplayer('playlist_mixmedia.xml', false);
playFlag = true;
}
else if ((currentState==0)&&(playFlag)&&(! timerFlag)) {
sendEvent('playitem', oldItem+1);
}
}
};

function thisMovie(movieName) {
if(navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
};

function createplayer(theFile, go) {
var s = new SWFObject("mediaplayer.swf","playerID","400","345","7");
s.addParam("allowfullscreen", "true");
s.addParam("allowscriptaccess", "always");

s.addVariable("file", theFile);
s.addVariable("width", "400");
s.addVariable("height", "345");
s.addVariable("displayheight", "225");

s.addVariable("enablejs", "true");
s.addVariable("javascriptid", "playerID");

if (go) { s.addVariable("autostart", "true"); }
s.addVariable("repeat", "true");
s.addVariable("shuffle", "false");

s.write("placeholder");

playFlag = false;
timerFlag = false;
clearTimeout(timerID);
timerID = setTimeout("timerFlag = true", 150000);  //2:30 minutes
}
</SCRIPT>
</HEAD>
<BODY onload="createplayer('playlist_mixmedia.xml', true)">

<DIV id=placeholder>
<A href="http://www.macromedia.com/go/getflashplayer">get flash</A> to see this player.
</DIV>

</BODY>
</HTML>

please note this demo refreshes every 2:30 minutes (150000 milliseconds) and uses a static playlist.xml

Thank you so much andersen!

I am experimenting with it and it does play a dynamic playlist also, the one generated by Global's script. I haven't seen yet if the playlist gets refreshed properly resolving the problem, as I have to wait for a while to see if the error is being reproduced, but one thing I noticed so far is that most long videoclips stop all of a sudden after a few minutes playing and then next video starts, which is not normal.

I have changed the timeout to 1800000 - 30 minutes. Would that have anything to do with it?

@andersen

The problem mentioned above seems to have disappeared, may be because I assigned more disk space in my cache folder.

So I tested the script and it works properly. After an item of the list finishes playing, if the predetermined time has expired the list, as of a magic, refreshes. I am very happy about this and thanks again!

The only issue is that if the reproduction is in full-screen mode the refreshing of the playlist minimizes the player, I wonder if there is a solution for that.

Now what is wanted is to combine the above script with multiple playlists controlled by links similar to the one at: "http://home5.inet.tele.dk/nyboe/flash/mediaplayer/multipleplaylists.htm" ( not drop down menu, just links ) do you think is possible?

@andersen

Any answer?? Andersen your above script functions so nicely and I am trying hard to make it work for different playlists but the only way I have figured out so far by my self is creating one page for each playlist and then linking to these pages in an iframe mode, whereas, with your expert help I am sure you could come up with a script allowing for several playlists on the same page, including the function of the above - playlist refreshing script.

As a matter of fact I have found an other script, that allows you to create rss feeds from youtube playlists, which is even quicker than the one of Global above, and it works nicely with the wonderful JW FLV MEDIA PLAYER 3.16 (Thank you jeroen!!).
For those interested It is found here:
http://furyy.planet.ee/ytube/ - it can be installed also on one's own server and does miracles! But the list generated still suffer from the same problem, that after a certain time - 60 minutes - the links to the movies become obsolete as the youtube-google server changes automatically their url. Therefore the need to use your nice script to regenerate automatically the playlist.

So Andersen if you have any chance to look into it I would appreciate very much, thanks!

@andersen - sorry to disappoint you, I couldn't find any help from hese threads.

I know how to embed the player with multiple playlists in the normal way, is quite straightforward I think.

What I have trouble with is how to do it implementing your script - refresh playlist after a certain time - above.

In the function GetUpdate is included:
createplayer('playlist_mixmedia.xml', false);

So this means the script can be called only for one playlist called "playlist_mixmedia.xml" or whatever right?

If not, how is it done? Have some patience please and explain in a simple, step by step way or even better please create a sample page - multiple playlists refreshing automatically after a certain period of time - to see. Thank you very much.

this is the creating function, where i have left most out, leaving only a few relevant essentials:

function createplayer(theFile, go) {
...
s.addVariable("file", theFile);
...
if (go) { s.addVariable("autostart", "true"); }
...
}

this tells you that the function takes a filename and a boolean value (true/false) as argument...

as you should not create the player empty - the following creates the player onload, with a default file and tells it to autostart <BODY onload="createplayer('playlist_mixmedia.xml', true)"> all the above is already in the script -

here follows two example links that when clicked will recreate the player with the defined playlists and autostart the playing

<a href="javascript:createplayer('playlistA.xml',  true)">playlist A</a>
<br>
<a href="javascript:createplayer('playlistB.xml',  true)">playlist B</a>

so all you need, is to place links in the page, links that call the createplayer with the filename you want to load and autostart...

@andersen

I did this but when the time expires and the playlist refreshes will not refresh the actual playing list but will refresh only the playlist that is written at the string createplayer('playlist_mixmedia.xml', false); of the "function getUpdate" as in this part of your script below:

function getUpdate(typ,pr1,pr2,swf) {
if(typ == "item") { currentItem = pr1; }
else if(typ == "state") {
currentState = pr1;
if ((currentState==3)&&(timerFlag)) {
oldItem = currentItem;
createplayer('playlist_mixmedia.xml', false);
playFlag = true;
}
else if ((currentState==0)&&(playFlag)&&(! timerFlag)) {
sendEvent('playitem', oldItem+1);
}
}
};

You can see it in action here:
http://www.prabhupada.org/jaya/playlist/playlist.htm

The time expires in half a minute, so after that the refreshing takes place and you can see that the list refreshes but it is not the playlist being played that gets refreshed but the one which is written in that portion of the script indicated above.

ouch ! - sorry i forgot - so you have to add a variable to hold the filename: (note all three places)

<HTML><HEAD><TITLE>refresh multiple lists example</TITLE>

<SCRIPT src="swfobject.js" type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
var currentItem;
var currentState;
var timerFlag;
var playFlag;
var timerID;
var oldItem;
var theFileName;

function sendEvent(typ,prm) { thisMovie("playerID").sendEvent(typ,prm); };

function getUpdate(typ,pr1,pr2,swf) {
if(typ == "item") { currentItem = pr1; }
else if(typ == "state") {
currentState = pr1;
if ((currentState==3)&&(timerFlag)) {
oldItem = currentItem;
createplayer(theFileName, false);
playFlag = true;
}
else if ((currentState==0)&&(playFlag)&&(! timerFlag)) {
sendEvent('playitem', oldItem+1);
}
}
};

function thisMovie(movieName) {
if(navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
};

function createplayer(theFile, go) {
theFileName = theFile;

var s = new SWFObject("mediaplayer.swf","playerID","400","345","7");
s.addParam("allowfullscreen", "true");
s.addParam("allowscriptaccess", "always");

s.addVariable("file", theFile);
s.addVariable("width", "400");
s.addVariable("height", "345");
s.addVariable("displayheight", "225");

s.addVariable("enablejs", "true");
s.addVariable("javascriptid", "playerID");

if (go) { s.addVariable("autostart", "true"); }
s.addVariable("repeat", "true");
s.addVariable("shuffle", "false");

s.write("placeholder");

playFlag = false;
timerFlag = false;
clearTimeout(timerID);
timerID = setTimeout("timerFlag = true", 150000); //2:30 minutes
}
</SCRIPT>
</HEAD>
<BODY onload="createplayer('playlistA.xml', true)">

<DIV id=placeholder>
<A href="http://www.macromedia.com/go/getflashplayer">get flash</A> to see this player.
</DIV>

<a href="javascript:createplayer('playlistA.xml', true)">playlist A</a>
<br>
<a href="javascript:createplayer('playlistB.xml', true)">playlist B</a>

</BODY>
</HTML>

@andersen

Great!! This works properly!

Thank you for your patience and for being available Andersen. I wish I knew the use of the java language as good as you! It's amazing how this flah player can be extended in so many ways, plus being free and having such nice support from selfless members of the community as your good self, makes it even more valuable and attractive!

Congratulations and best wishes!!
Jivatma

Hi there,

Have had this running happily on 4 of my sites for a while now but a user just reported that the videos no longer play (the playlist and thumbnails are displayed as before but when you click on the play button nothing happens. I heard YT have changed their API again or something like that - can anyone advise me what I need to change to make it work again please ?

Thanks

Just checked the playlist generator, it's working fine.

If you are using it with a v4.1.x player, find this line of code:  $playlist .= "      <meta rel=\"type\">flv</meta>\n";
and change it to:  $playlist .= "      <meta rel=\"type\"><strong>video</strong></meta>\n";

Have you seen Veewow (www.veewow.com) it lets you embed videos from YouTube, MySpace and Google video in to playlists. The playlists auto run, so it is great for music playlists, you can just listen to them in the background whilst doing other things. This is my fave list, 55 tracks, http://is.gd/2rZF.

Where is the PlayList gen "YouTube_Playlist_XSPF.php" ?

I've been trying to follow this discussion and copy/pasted a lot of scripts, but get a lot
of errors on the way. It seems stupid to ask anyone to go through the same script with
same or new errors.
Could anyone share a zip-file with the above playlist function?

An idea for 'problems' like this; why not provide a conclusion at the end of the post.
Would be nice for people having the same problems and sometimes you need
to read the whole thread if you want to piece together a working script.

(This is a great forum btw)

@HRS,

Exactly which script are you looking for?

I can make YouTube_Playlist_XSPF-3.2.php of 09-08-08 available if that's what you want.

@kLink. Yeah, it's something like that I'm looking for. If you would help me with that, I would be so grateful.
+ it would be nice to access easily for new users that may come by.

 
@HRS,

Most YouTube playlists will play directly in the v4.2 players, but in case yours won't, here's YouTube_Playlist_XSPF-3.2.php:

<?php

// YouTube_Playlist_XSPF-3.2.php 20080909 - compatible with v4.2.x player
// playlists need to be updated at least every 2 hours
// call with:                     http://my.domain.com/YouTube_Playlist_XSPF-3.2.php?playlistid=9A337BB0628CF018
//      file: encodeURIComponent('http://my.domain.com/YouTube_Playlist_XSPF-3.2.php?playlistid=B8D6FA74D3F2629C),

$debug_output    = true;
$update_interval = 2;
$cachedirectory  = '/Program Files/Apache Group/Apache2/Will\'s Wonders/php/cache/';

// debug('Playlist ID', $_GET['playlistid']);

// for command line argument passing
if (isset($_SERVER['argv'][1]))
{
  $_GET['playlistid'] = $_SERVER['argv'][1];
}

// debug('Playlist ID', $_GET['playlistid']); exit;

// my playlist
$playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "B8D6FA74D3F2629C";
// johnyradio 9A337BB0628CF018
// $playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "9A337BB0628CF018";
// ToothandNail 4F7A36C13B0C5764
// $playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "4F7A36C13B0C5764";
// UMG 5C06802F841BE277
// $playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "5C06802F841BE277";
// WatchMojo 2C9178C3EFE262EF
// $playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "2C9178C3EFE262EF";
// National Geographic - top videos
// $playlistid = (isset($_GET["playlistid"])) ? strval($_GET["playlistid"]) : "B4EF96652BFE5853";

// max-results is limited to 50 per request, total of 100 for playlists
//              http://gdata.youtube.com/feeds/api/playlists/45C563323B344971   ?start-index=1&max-results=50
$playlisturl1 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=1&max-results=50";
$playlisturl2 = "http://gdata.youtube.com/feeds/api/playlists/" . $playlistid . "?start-index=51&max-results=50";

// create cache filename
$patterns     = array('#gdata#', '#/#', '#:#', '#\.#', '#http#', '#youtube#', '#com#', '#feeds#', '#api#', '#playlists#', '#\?start-index=1&max-results=50#');
$replacements = array(       '',    '',    '',     '',       '',          '',      '',        '',      '',  'playlists_',                                 '');
$filename     = preg_replace($patterns, $replacements, $playlisturl1);

// debug('   Playlist ID', $playlistid);
// debug('  Playlist URL', $playlisturl);
// debug('Cache Filename', $cachefilename);
// exit;

for ($i=0; $i < $update_interval; $i++)
{
  $cachefilename = (date('YmdH') - $i) . '_' . $filename . ".xml";
  if (file_exists($cachedirectory . $cachefilename))
  {
    if (!isset($_SERVER['argv'][1]))
    {
      header ("content-type: text/xml");
      print file_get_contents($cachedirectory . $cachefilename);
    }
    exit;
  }
}

$cachefilename = date('YmdH') . '_' . $filename . ".xml";

$playlistcontent1 = file($playlisturl1);
$playlistcontent2 = file($playlisturl2);
$playlistcontent  = array_merge($playlistcontent1, $playlistcontent2);

$contentstring = "";
foreach(
$playlistcontent as $value)
{
  $contentstring .= rtrim($value);
}

$contentarray = explode("<entry>", $contentstring);

// debug('Playlist Content', $playlistcontent);
// debug('Content String',   $contentstring);
// debug('Content Array',    $contentarray);
// exit;

$track = 0;
$type  = '';

// construct XSPF playlist headers
$playlist  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$playlist .= "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
$playlist .= "  <trackList>\n";

// construct XSPF playlist tracks
while($junk = next($contentarray))
{
  $track++;
  $playlist .= "    <track>\n";

  if ((preg_match('/<title>(.*?)<\/title>/', $junk, $match)) || (preg_match('/<title type=\'text\'>(.*?)<\/title>/', $junk, $match)))
  {
    $playlist .= "      <title>" . $match[1] . "</title>\n";
  }
  if (preg_match('/<name>(.*?)<\/name>/', $junk, $match))
  {
    $playlist .= "      <author>" . $match[1] . "</author>\n";
    if ($match[1] == 'universalmusicgroup')
    {
      $type = 'UMG';
    }
  }
  //                                                                                       <media:thumbnail url='http://img.youtube.com/vi/izoZ-hjbKJQ/0.jpg
  if (preg_match('/<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=.*?<media:thumbnail url=\'(.*?)0.jpg/', $junk, $match))
  {
    $playlist .= "      <image>" . $match[1] . "0.jpg</image>\n";
  }
  //               <media:content url=\'http:\/\/www.youtube.com\/v\/ds6oTHYmqRc\' type
  if (preg_match('/<media:content url=\'http:\/\/www.youtube.com\/v\/(.*?)\' type/', $junk, $match))
  {
    $videoid = $match[1];
    //                          http://youtube.com/v/ds6oTHYmqRc.swf
    $page = @file_get_contents('http://youtube.com/v/' . $videoid . '.swf');
    if ((preg_match('/&t=(.*?)&/', $http_response_header[5], $match)) || (preg_match('/&t=(.*)/', $http_response_header[5], $match)))
    {
      $playlist .= "      <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&amp;t=" . $match[1] . "</location>\n";
    }
  }
  else if (preg_match('/<media:player url=\'http:\/\/www.youtube.com\/watch\?v=(.*?)\'/', $junk, $match))
  {
    $videoid = $match[1];
    $page = @file_get_contents('http://youtube.com/watch?v=' . $videoid);
    // check html in $page for: var swfArgs = {video_id:'lNvWoi0TesY',l:'217',t:'OEgsToPDskKER2zcpXlSd7ZzYDMp35hB',sk:'ASVXJ-JA-T6kbJT7maMDnwC',sw:'0.05',tk:'SZEt22MOl18ADaQJ-c9onimRL-HKw9HxGyYbBkoyguEPPDq_ttbaow=='};
    preg_match('/t:\'(.*?)\'/', $page, $match);
    //                            http://www.youtube.com/get_video.php?video_id=   lNvWoi0TesY  &    t=OEgsToPDskKER2zcpXlSd7ZzYDMp35hB
    $playlist .= "      <location>http://www.youtube.com/get_video.php?video_id=" . $videoid . "&amp;t=" . $match[1] . "</location>\n";

// debug(       'Page', $page);
// debug(   'Match[1]', $match[1]);
// exit;

  }
  $playlist .= "      <meta rel=\"type\">video</meta>\n";
  $playlist .= "      <annotation>Track " . $track . "</annotation>\n";
  $playlist .= "    </track>\n";

  if (($track > 19) && ($type == 'UMG'))
  {
    break;
  }
}

// construct XSPF playlist footers
$playlist .= "  </trackList>\n";
$playlist .= "</playlist>\n";

if (!isset($_SERVER['argv'][1]))
{
  header ("content-type: text/xml");
  print $playlist;
}

// check cache - write to cache
if (!file_exists($cachedirectory . $cachefilename))
{
  $fh = fopen($cachedirectory . $cachefilename, 'a');

  fwrite($fh, $playlist); 

  fclose($fh);
}

// cleanup cache
@$directory_handle = dir($cachedirectory);

if ($directory_handle)
{
  while (false !== ($currentfile = $directory_handle->read()))
  {
           // 200712050018_playlists_9A337BB0628CF018.xml
    if (preg_match('/(\d{10})_playlists_.*?.xml/', $currentfile, $match))
    {
      $currentdate = date('YmdH');

// debug('Current Date', $currentdate);
// debug('Current File', $currentfile);
// debug('    Match[1]', $match[1]);

      // if file is older than current hour - update interval, delete file
      if ($match[1] < $currentdate - $update_interval + 1)
      {
        unlink($cachedirectory . $currentfile);
      }
    }
  }
  $directory_handle->close();
}

function debug($title, $value)
{
  global $debug_output;

  if ($debug_output)
  {
    print "<pre>";
    if (is_array($value))
    {
      print $title . ":\n";
      print_r($value);
    }
    else
    {
      print $title . ": " . $value;
    }
    print "</pre>\n";
  }
}

?>

Oh My gosh that is challenging.....

Ok, so I read through pages and pages of info on this and found a very simple solution. All you need to do is change the playlist link YouTube gives you like this:

From:
http://www.youtube.com/view_play_list?p=F4DF7B5DEE6ACA06

To:
http://gdata.youtube.com/feeds/api/playlists/F4DF7B5DEE6ACA06

Where the part after playlists/ is you playlist ID.

Hope that helps!

This makes it very easy.

http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html#Retrieving_a_playlist

use this line for the playlis but replace the numbers with the numbers from your own playlist

example

http://gdata.youtube.com/feeds/api/playlists/8BCDD04DE8F771B2?v=2

becomes

http://gdata.youtube.com/feeds/api/playlists/5330860B46313E95?v=2

<embed
src="/embed/player.swf"
width="470"
height="470"
bgcolor="undefined"
allowscriptaccess="always"
allowfullscreen="true"
flashvars="file=http://gdata.youtube.com/feeds/api/playlists/5330860B46313E95?v=2&playlist=bottom"
/>

Thanks Patrick and Bushalicious. I was able to embed a playlist to my blogger. That is fantastic! If I could remove the Youtube logo without any complicated script, I would be very happy.

Oh, I just found out one little annoying thing. It only shows a partial list of 25 entries instead of 41 in my player?

How do I remove the 25 limitation?

Solved: by adding the string: ?max-results=50

For Example:
http://gdata.youtube.com/feeds/api/playlists/FFF0AD7E85FCBE3A?max-results=50

Is it possible to get rid of the Youtube's huge logo or make it smaller, just by manipulating the embedding code or the xml playlist? I don't know php. I think blogger or googlepages do not support it.

Here's a working example using the YouTube api and JW 4.x.

http://www.trbailey.net/javascript/JW_API.html

:)

-Tom

Too bad I don't understand any of this.