Get complete playlist listing for a YouTube User v

2019-02-17 22:23发布

问题:

So, here's my code for getting a youtube user's public playlists:

function getyoutubeplaylists($userName) {
$yt = connectyoutube();
$yt->setMajorProtocolVersion(2);
$playlistListFeed = $yt->getPlaylistListFeed($userName);
foreach ($playlistListFeed as $playlistListEntry) {
    $playlist['title'] = $playlistListEntry->title->text;
    $playlist['id'] = $playlistListEntry->getPlaylistID();
    $playlists[] = $playlist;
    $playlistVideoFeed = $yt->getPlaylistVideoFeed($playlistListEntry->getPlaylistVideoFeedUrl());
    foreach ($playlistVideoFeed as $videoEntry) {
        $playlist_assignment['youtube_id'] = substr($videoEntry->getVideoWatchPageUrl(),31,11);
        $playlist_assignment['id'] = $playlist['id'];
        $playlist_assignments[] = $playlist_assignment;
    }
}
$everything['playlists'] = $playlists;
$everything['playlist_assignments'] = $playlist_assignments;
return $everything;
}

Problem is, this only gets the first page or results. Any ideas on how to use the Zend Gdata to retrieve the next page of results?

The raw gdata XML shows the URLs needed:

<link rel="self" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/pennstate/playlists?start-index=1&amp;max-results=25"/>
<link rel="next" type="application/atom+xml" href="http://gdata.youtube.com/feeds/api/users/pennstate/playlists?start-index=26&amp;max-results=25"/>

However, getPlaylistListFeed doesn't seem to have any parameters to specify "start-index" or "max-results".

回答1:

It sounds like you want to follow the Dev Guide example on pagination.



回答2:

This is a useful Zend function for retrieving not only the next page but all available entries for a feed.

 $playlistListFeed = $yt->retrieveAllEntriesForFeed($yt->getPlaylistListFeed($userName));


回答3:

Since I wasted all day "just trying to get a list of my videos to show on my website", I thought I'd paste up some sample code that just taught me a lot. And as expected, Zend_Gdata_YouTube:: is already in Magento installations. The code below will present a unified list of "videos", where playlists appear the same in the list as the other videos alongside each other. Update: I made a Magento extension out of my answer.

This is just a generic php I dropped into var/export. At the top, you have to include app/Mage.php.

<?
$userName='cacycleworksdotcom';
$yt = new Zend_Gdata_YouTube();
//////////////////////////////////////////////////////////////////////
// Get playlists.
$playlistListFeed = $yt->retrieveAllEntriesForFeed($yt->getPlaylistListFeed($userName));
$playlist=Array();
$videoEntry=NULL;
$playlistvideos=Array();

Here, you've got an array of Zend objects in $playlistListFeed.

foreach ($playlistListFeed as $idx=>$playlistListEntry) {
    // process each playlist
    $playlists[$idx]['title'] = $playlistListEntry->title->text;
    $url=$playlistListEntry->getSelfLink()->href;
    $id=explode("/PL",$url);
    $playlists[$idx]['id'] = $id[1];
    $playlistVideoFeed = $yt->getPlaylistVideoFeed($playlistListEntry->getPlaylistVideoFeedUrl());
    $playlists[$idx]['time']=0;
    $playlists[$idx]['views']=0;
    $playlists[$idx]['rating']=0;

Now, within the playlist, I look at the videos of this playlist and gather stats on each one. I sum their times to get a total playtime and then capture the highest view count and rating from the videos in the playlist.

    foreach ($playlistVideoFeed as $videoEntry) {
        // info of each video inside this playlist
        $_id=substr($videoEntry->getVideoWatchPageUrl(),31,11);
        $playlistvideos[]=$_id;
        $_url=$videoEntry->getVideoWatchPageUrl();
        $playlists[$idx]['videos'][$_id]=$_url;
        $playlists[$idx]['time']+=$videoEntry->getVideoDuration();
        $_views=$videoEntry->getVideoViewCount();
        if( $_views > $playlists[$idx]['views'] )
            $playlists[$idx]['views']=$_views;
        $_rating=$videoEntry->getRating()->average;
        if( $_rating > $playlists[$idx]['rating'] )
            $playlists[$idx]['rating']=$_rating;
    }

I ended up using the XML to get the thumbnail data.

    $xml=$playlistListEntry->getXML();
    // $playlists[$idx]['xml']=$xml;    // store original XML for now
    $xml = simplexml_load_string($xml); // transfer into object
    $attrs=$xml->group->thumbnail[1];
    $playlists[$idx]['thumb']=(string)$attrs['url'];
    //                                1st vid id         playlist id
    // http://www.youtube.com/watch?v=mcnIAErKc-g&list=PLEDADE9CA0E65BA78
    $videoid=array_keys( $playlists[$idx]['videos']);
    $videoid=$videoid[0];
    $playlists[$idx]['url'] = "http://www.youtube.com/watch?v=$videoid&list=PL".$playlists[$idx]['id'];     
}

The playlists are handled, now let's get the remaining videos that aren't in playlists:

//////////////////////////////////////////////////////////////////////
// Videos themselves
$idx=count($playlists);
$userFeed = $yt->getUserUploads($userName);
foreach ($userFeed as $videoEntry) {
    $idx++;
    $_id=substr($videoEntry->getVideoWatchPageUrl(),31,11);
    if( ! in_array($_id, $playlistvideos) ) {
        $_url=$videoEntry->getVideoWatchPageUrl();
        $playlists[$idx]['id']=$_id;
        $playlists[$idx]['url']=$_url;
        $playlists[$idx]['title']=$videoEntry->title->text;
        $playlists[$idx]['views']=$videoEntry->getVideoViewCount();
        $playlists[$idx]['rating']=$videoEntry->getRating()->average;
        $thumbs=$videoEntry->getVideoThumbnails();
        // these need resizing to width="320" height="180"
        $playlists[$idx]['thumb']=$thumbs[0]['url'];
        $playlists[$idx]['time']=$videoEntry->getVideoDuration();
    } // else { echo "$_id already in playlist\n";  }
}

Here we have an array of our youtube videos, at the top are the playlsits ordered by oldest first, followed by the user's videos not appearing in playlists in same oldest first order. So I found this simple sort code to change the order. Great article there about sorting and worth a read if you're here trying to sort multidimensional arrays.

//////////////////////////////////////////////////////////////////////
// http://www.the-art-of-web.com/php/sortarray/
function orderBy($data, $field) {
    $code = "return strnatcmp(\$a['$field'], \$b['$field']);";
    //  swap $a and $b to make descending instead of ascending
    usort($data, create_function('$b,$a', $code)); //('$a,$b', $code));
    return $data;
}
$playlists = orderBy($playlists, 'views');
//////////////////////////////////////////////////////////////////////
echo "\n\n";
print_r($playlists);

Here is the code that helped me get started working with these goofy GData YouTube Zend objects:

echo "\n\n";
show_methods($videoEntry);
echo "\n\n";
show_methods($playlistListFeed[0]);
echo "\n\n";
show_methods($playlistListFeed);

function show_methods( $_a ) {
    echo "<h3>Methods for ".get_class($_a)."</h3>";
    $_a= get_class_methods($_a);
    $_a=array_unique($_a);
    array_multisort(&$_a);
    $i=0;
    foreach( $_a as $method ) {
        $i++;
        printf("%-30.30s",$method);
        if($i%5==0)
            echo "\n";
    }
}

Here are two of the array entries to show the structure. Note that playlists have a videos key with an array of the videos inside it. Testing for the videos key can tell you it's a playlist. The url is what your user can click on to open the video or playlist on the youtube site.

[1] => Array
    (
        [title] => Ducatitech.com "HowTo" Adjust your Valves
        [id] => 970EC735D36A95E8
        [time] => 855
        [views] => 144847
        [rating] => 4.9322033
        [videos] => Array
            (
                [dIj3nSJGPZw] => http://www.youtube.com/watch?v=dIj3nSJGPZw&feature=youtube_gdata_player
                [3WQY1MRlmH4] => http://www.youtube.com/watch?v=3WQY1MRlmH4&feature=youtube_gdata_player
            )

        [thumb] => http://i.ytimg.com/vi/dIj3nSJGPZw/mqdefault.jpg
        [url] => http://www.youtube.com/watch?v=dIj3nSJGPZw&list=PL970EC735D36A95E8
            )

        [thumb] => http://i.ytimg.com/vi/mcnIAErKc-g/mqdefault.jpg
        [url] => http://www.youtube.com/watch?v=mcnIAErKc-g&list=PLEDADE9CA0E65BA78
    )
[7] => Array
    (
        [id] => 80yCiFkOB9g
        [url] => http://www.youtube.com/watch?v=80yCiFkOB9g&feature=youtube_gdata_player
        [title] => Ducatitech.com: ExactFit Timing Belt Tensile Test
        [views] => 7589
        [rating] => 4.25
        [thumb] => http://i.ytimg.com/vi/80yCiFkOB9g/0.jpg
        [time] => 625
    )

And finally, the kind of stuff you get out of show_methods():

Methods for Zend_Gdata_YouTube_VideoEntry

__construct                   __get                         __isset                       __set                         __toString                    
__unset                       addVideoDeveloperTag          delete                        encode                        ensureMediaGroupIsNotNull     
flushNamespaceLookupCache     getAlternateLink              getAuthor                     getCategory                   getComments                   
getContent                    getContributor                getControl                    getDOM                        getEditLink                   
getEtag                       getExtensionAttributes        getExtensionElements          getFeedLink                   getFlashPlayerUrl             
getHttpClient                 getId                         getLicenseLink                getLink                       getLocation                   
getMajorProtocolVersion       getMediaGroup                 getMediaSource                getMinorProtocolVersion       getNextLink                   
getNoEmbed                    getPreviousLink               getPublished                  getRacy                       getRating                     
getRecorded                   getRights                     getSelfLink                   getService                    getSource                     
getStatistics                 getSummary                    getText                       getTitle                      getTitleValue                 
getUpdated                    getVideoCategory              getVideoCommentFeedUrl        getVideoComplaintsLink        getVideoDescription           
getVideoDeveloperTags         getVideoDuration              getVideoGeoLocation           getVideoId                    getVideoRatingInfo            
getVideoRatingsLink           getVideoRecorded              getVideoResponsesLink         getVideoState                 getVideoTags                  
getVideoThumbnails            getVideoTitle                 getVideoViewCount             getVideoWatchPageUrl          getWhere                      
getXML                        isVideoEmbeddable             isVideoPrivate                lookupNamespace               registerAllNamespaces