Making plugin for a YouTube Channel

Looking for a template to make plug-ins for YouTube
Is there an easy way to make a Plex plugin for a YouTube channel?

I actually have 6 related channels filled with content (for a theatre) that I'd love to have in a plug-in.

Any help is appreciated!

Thanks,

Eliot

Hey there!

YouTube provides RSS feeds on their website, but I personally don’t like how they look (in words of content). So I browsed over Yahoo Pipes and found a pipe that converted a YouTube feed to a somewhat cleaner one. I cloned that pipe to make some extra changes for some of my own Plex plugins.



YouTube feeds are limited to 25 items, so are my pipes…



A playlist (input the playlist id):


http://pipes.yahoo.com/pipes/pipe.run?_id=e06ab7419ac935fab1eb3eedfdcde873&_render=rss&playlistid=YOUR_PLAYLIST_ID_HERE


Last **uploads** of a specific user (input the username):

http://pipes.yahoo.com/pipes/pipe.run?_id=846e037a24c97cf3e0c5564bae2d9f01&_render=rss&userid=INSERT_USERNAME_HERE


Both pipes collect data like title and description. They also lookup the higer resolution preview image and create a link to youtubemp4.plexapp.net (which redirects directly to the requested video - so you don't have to worry about creating a Site Config file for your plugin).

Here is an example of such a feed: [http://pipes.yahoo.com/pipes/pipe.run?_id=...erid=AVForumsTV](http://pipes.yahoo.com/pipes/pipe.run?_id=846e037a24c97cf3e0c5564bae2d9f01&_render=rss&userid=AVForumsTV)

Now that the input is "clean" and contains all we need, it's pretty easy to use it in a plugin. Here's a little piece of Python code you can start from:


from PMS import *<br />
from PMS.Objects import *<br />
from PMS.Shortcuts import *<br />
import rfc822, time<br />
<br />
################################################################################<br />
####################<br />
<br />
PLUGIN_TITLE					= 'Demo plugin'<br />
PLUGIN_PREFIX				   = '/video/demoplugin'<br />
YOUTUBE_RSS					 = 'http://pipes.yahoo.com/pipes/pipe.run?_id=846e037a24c97cf3e0c5564bae2d9f01&_render=rss&userid=AVForumsTV'<br />
<br />
CACHE_INTERVAL				  = 3600<br />
<br />
# Default artwork and icon(s)<br />
PLUGIN_ARTWORK				  = 'art-default.png'<br />
PLUGIN_ICON_DEFAULT			 = 'icon-default.png'<br />
<br />
################################################################################<br />
####################<br />
<br />
def Start():<br />
  Plugin.AddPrefixHandler(PLUGIN_PREFIX, MainMenu, PLUGIN_TITLE)<br />
<br />
  Plugin.AddViewGroup('Details', viewMode='InfoList', mediaType='items')<br />
<br />
  # Set the default MediaContainer attributes<br />
  MediaContainer.title1		 = 'Demo plugin'<br />
  MediaContainer.viewGroup	  = 'Details'<br />
  MediaContainer.art			= R(PLUGIN_ARTWORK)<br />
<br />
  # Set the default cache time<br />
  HTTP.SetCacheTime(CACHE_INTERVAL)<br />
<br />
################################################################################<br />
####################<br />
<br />
def MainMenu():<br />
  dir = MediaContainer(title2='YouTube RSS demo')<br />
<br />
  feed = XML.ElementFromURL(YOUTUBE_RSS, errors='ignore').xpath('//channel/item')<br />
<br />
  for item in feed:<br />
	title	   = item.xpath('./title')[0].text<br />
<br />
	description = item.xpath('./description')[0].text<br />
<br />
	# Description is HTML formatted and contains both the image and summary.<br />
	description = XML.ElementFromString(description, isHTML=True)<br />
	thumb	   = description.xpath('.//img')[0].get('src')<br />
	summary	 = description.xpath('.//p')[0].text<br />
<br />
	date		= item.xpath('./pubDate')[0].text<br />
	date		= rfc822.parsedate(date)<br />
	date		= time.strftime('%b %d, %Y - %H:%M', date)<br />
<br />
	video	   = item.xpath('./enclosure')[0].get('url')<br />
<br />
	dir.Append(VideoItem(video, title=title, subtitle=date, summary=summary, thumb=thumb))<br />
<br />
  return dir

This is excellent help!



I will look into it this week or next as we prep to promo our next season!


  • Eliot


Here is a general purpose template you can use as well. Allows more than one feed to be specified and will automatically merge them and sort by date.



This assumes you’re using V1 of the framework



<br />
# PMS plugin framework<br />
from PMS import *<br />
from PMS.Objects import *<br />
from PMS.Shortcuts import *<br />
from datetime import datetime<br />
import time<br />
import re<br />
<br />
####################################################################################################<br />
<br />
# also make sure to edit the Info.plist to give it a unique name<br />
PLUGIN_PREFIX = "/video/baratsandbereta"<br />
<br />
# add more than one feed if you want, it will combine them and sort by date<br />
FEEDS         = [<br />
    'http://gdata.youtube.com/feeds/base/users/BaratsAndBereta/uploads?alt=rss&v=2&max-results=50',<br />
]<br />
<br />
NAME          = 'Barats and Bereta'<br />
<br />
# make sure to replace artwork with what you want<br />
ART           = 'art-default.png'<br />
ICON          = 'icon-default.png'<br />
<br />
####################################################################################################<br />
<br />
yt_videoURL         = "http://www.youtube.com/get_video?video_id="<br />
def Start():<br />
    Plugin.AddPrefixHandler(PLUGIN_PREFIX, Menu, NAME, ICON, ART)<br />
    Plugin.AddViewGroup("InfoList", viewMode="InfoList", mediaType="items")<br />
    Plugin.AddViewGroup("List", viewMode="List", mediaType="items")<br />
    MediaContainer.art = R(ART)<br />
    MediaContainer.title1 = NAME<br />
    DirectoryItem.thumb = R(ICON)<br />
<br />
def Menu():<br />
<br />
    dir = MediaContainer(viewGroup="InfoList",title2="Episodes")<br />
    dir = parseFeeds(FEEDS,dir)<br />
    return dir<br />
<br />
def parseFeeds(feeds,dir):<br />
  parsed = []<br />
<br />
  for feed in feeds:<br />
      feed = RSS.FeedFromURL(feed,cacheTime=Constants.CACHE_1HOUR)<br />
      count = 1<br />
<br />
      for e in feed['entries']:<br />
<br />
          date = datetime.now().strftime("%Y-%m-%d")<br />
          try:<br />
              date = datetime.fromtimestamp(time.mktime(e['updated_parsed'])).strftime("%Y-%m-%d")<br />
          except:<br />
              pass<br />
          url = e['link']<br />
          title = e['title']<br />
          summary_html = e['summary_detail']['value']<br />
          summary_xml = XML.ElementFromString(summary_html, isHTML=True)<br />
<br />
          thumb = R(ICON)<br />
          try:<br />
              thumb = summary_xml.xpath('//img')[0].get('src')<br />
          except:<br />
              pass<br />
<br />
          summary = ''<br />
          try:<br />
              summary = summary_xml.xpath('//span')[0].text<br />
          except:<br />
              pass<br />
<br />
          duration = 0<br />
          try:<br />
            dur_parts = summary_xml.xpath('//span')[-2].text.split(':')<br />
            dur_parts.reverse()<br />
            i = 0<br />
            for p in dur_parts:<br />
                duration = duration + int(p)*(60**i)<br />
                i = i + 1<br />
            duration = duration * 1000<br />
          except:<br />
              pass<br />
<br />
          parsed.append({<br />
            'url': url,<br />
            'title': title,<br />
            'summary': summary,<br />
            'duration': duration,<br />
            'thumb': thumb,<br />
            'subtitle': date,<br />
          })<br />
<br />
  parsed.sort(cmp = lambda x, y: cmp(y.get('subtitle',''), x.get('subtitle','')))<br />
  for e in parsed:<br />
      dir.Append(Function(VideoItem(VidRedirect, title=e['title'], summary=e['summary'], duration=e['duration'], thumb=e['thumb'], subtitle=e['subtitle']),url=e['url']))<br />
  return dir<br />
<br />
def VidRedirect(sender,url=''):<br />
<br />
    ytPage = HTTP.Request(url)<br />
    <br />
    t = re.findall('"t": "([^"]+)"', ytPage)[0]<br />
    v = re.findall("var pageVideoId = '([^']+)';", ytPage)[0]<br />
    hd = re.findall("var isHDAvailable = ([^;]+);", ytPage)[0]<br />
    <br />
    fmt = "18"<br />
    if hd == "true":<br />
      fmt = "22"<br />
      <br />
    u = yt_videoURL + v + "&t=" + t + "&fmt=" + fmt<br />
    return Redirect(u)<br />


What does this mean “using the version 1 framework”?



If I’m using the newest version of Plex will this work?



So far, it doesn’t work…




latest version of plex should work. There is an old plugin API (version '0') and the one that should be used is version '1'. In your Info.plist there should be something that looks like this:


<br />
    <key>PlexFrameworkVersion</key><br />
    <string>1</string><br />


Wow, that was a fast response!



What I done to create this plugin was…make a copy of the Yoututube plugin…change the '/code/init.py file with your code. Change a few lines to give it a unique name…change the name of the bundle and then upload it. I’m not a Python person (yet) so I’m just going through the motions at the moment.



I’m not sure if I’m far off track or not.



Do you have this script uploaded someplace as a complete piece of code in a bundle that I can work with?



Thanks






Ahh, looks like the youtube plugin is actually a version '0' plugin. Try downloading a different plugin.. like Funny or Die and then do the same thing. Make sure to edit the Info.plist to have a unique path and plugin name as well.


Here is an example using a version of this snippet I posted. Note that I only need one youtube channel, I don't need to blend them... This also lets me properly page through results.

I've attached a plugin example

Ok, I was able to your new pack of files and then work with the script you posted in the forum to make everything come together. I won’t say I learned much but I’m becoming aware (I’m a web programmer…php, asp, actionscript3, etc). I hope to jump into some python soon so I can play with these things too.



PM me your paypal…I’ll tip (I do open source too).



Cheers and thanks



Just donate to the Plex project =)

Oh, and copying and pasting for this task IS NO MORE!

Take a look at my magic youtube user plugin generator:

http://perlster.com/tools/plex/skel/

Though I can't generate graphics automatically =)



I tried the plugin generator but didn't get it to work. I tried creating a feed using both options for Youtube (RSS and Atom). I installed the file and it looks initially like everything is going to work but once a clip is played I get an "Error could not read from input stream".

I can’t make the YouTube plugin generator work either. Also getting the “Error could not read from input stream”.

Is it possible to fix this great script?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.