做本地团购网站怎么样,免费ppt模板下载 清新,三明市住房和城乡建设局网站,seo职位具体做什么http://bbs.htpc1.com/thread-198731-1-1.html xbmc视频插件采用python语言编程#xff0c;插件启动后会下载网页#xff0c;截取其中的一些内容#xff08;文字或网址#xff09;#xff0c;交给xbmc或显示视频的目录#xff0c;或播放视频。
学习本教程必须具备python… http://bbs.htpc1.com/thread-198731-1-1.html xbmc视频插件采用python语言编程插件启动后会下载网页截取其中的一些内容文字或网址交给xbmc或显示视频的目录或播放视频。
学习本教程必须具备python、html的基础知识。
python是一种简单易学的计算机语言网上的《简明Python教程》看一两天就能入门如果有其它语言编程基础的话还有个《HTML教程》也是很容易学习的。
本教程中的代码在v10版、v11版的xbmc中都能正常运行。
目录 一、插件的结构 二、做一个hello world版的插件 三、构建多级目录 四、下载和处理网页 五、进一步改进 一、插件的结构
每个插件保存在各自的文件夹里打开xbmc插件的安装目录addons可以看到很多安装好的插件的文件夹。
一个典型的视频插件的文件夹里通常要有这三个文件 addon.xml说明文件用来告诉xbmc该插件所提供的内容以及安装要求 icon.png图标文件256x256像素xbmc插件清单旁边显示的就是这个图标 *.pypython主程序文件名字随便起addon.xml中有一项会用到这个文件名。 如果插件的子程序和用到的数据较多可以在下面再开子文件夹来保存。
重点看addon.xml的结构 首先第一行申明这是一个xml文件且是utf-8编码的接着是addon元素在addon和/addon之间有一个或多个extension元素每个extension告诉xbmc这个插件扩展了哪一部分的功能只有最后一个extension比较特别只是用来向用户做个说明。
addon元素有4个属性id, version, name, provider-name id属性插件id必须是唯一的小写插件zip文件解压后以id命名文件夹所以不能重名建议以plugin.类别.唯一名的形式命名类别可以是video, audio, script等 version属性插件版本号格式为x.x.xxbmc用来确定是否应升级插件 name属性插件名称 provider-name属性插件作者。
extension元素通过point属性告诉xbmc该插件扩展的类型有多种类型用python写的视频插件属xbmc.python.pluginsource类型同时还应加上一个library属性告诉xbmc启动插件时运行哪个python程序。providesvideo/provides告诉xbmc这是对视频功能的扩展。最后一个xbmc.addon.metadata类型的extension元素用来说明插件的运行环境、摘要、详情、申明等英文的必须有中文的可有可无。
插件做好后把所有文件压缩进zip文件包中发行xbmc在安装插件时会检查其中的addon.xml确认格式无误后才把它解压到addons目录下成为一个可用的插件。 二、做一个hello world版的插件
很多计算机语言的教程开篇都有“hello world”的最简单的例子让读者马上体验一下该编程语言的特点在这里我们也做一个最简单的xbmc插件只要会复制粘贴就能做出来。它显示一个“Hello, World!的菜单点击菜单可看一则网络视频。
做法 1、在xbmc的插件目录addons下新建一个子目录plugin.video.hello它的目录名也是插件的id名用来存放插件的3个文件
2、把下面的icon.png文件拷进新建的目录
3、用记事本编辑和保存一个名为addon.xml的文件内容如下?xml version1.0 encodingUTF-8 standaloneyes?
addon idplugin.video.hello namehelloworld演示 version0.0.1 provider-nameTau extension pointxbmc.python.pluginsource libraryhelloworld.py providesvideo/provides /extension extension pointxbmc.addon.metadata platformall/platform summaryhello world plugin/summary summary langzhhelloworld演示插件/summary descriptionhello world plugin, python script/description description langzhhelloworld演示插件python脚本/description disclaimerFor demonstration only/disclaimer /extension
/addon 复制代码4、再用记事本生成一个名为helloworld.py的文件内容如下# -*- coding: utf-8 -*-
# helloworld.py
# hello world demo import xbmcplugin, xbmcgui urlhttp://tv1.btv.com.cn/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4 handleint(sys.argv[1])
listitemxbmcgui.ListItem(Hello, World!)
xbmcplugin.addDirectoryItem(handle, url, listitem)
xbmcplugin.endOfDirectory(handle) 复制代码注意以上两个文本文件都必须以utf-8的编码方式保存。记事本用“文件-另存为”保存文件选择“编码”为“UTF-8。注意复制时不能“添油加醋”在语句前加点空格什么的。
启动xbmc进入视频扩展功能就可以看到一个新加入的插件”helloworld演示“进入插件看看是什么效果。
helloworld.py程序的说明 前3行为注释同时第1行说明本文件采用utf-8编码 import导入xbmc的两个库即xbmc对外提供的对外编程接口API使用其中的类、函数可以操控xbmc的界面 handle...从命令行参数中获得句柄句柄是xbmc启动插件脚本时赋予脚本的一个整数值 xbmcgui.ListItem(...创建一个ListItem类的实例对象它带有Hello, World!的文本标签 xbmcplugin.addDirectoryItem(...把上面的ListItem对象和视频网址url作为一个菜单项添加到菜单上 xbmcplugin.endOfDirectory(...告诉xbmc菜单项已全部添加完毕可以显示了。
小试验 把程序的最后一行去掉会怎么样 把url换成普通网页的网址会怎么样 不用担心尽管试你的xbmc没那么容易崩溃。
跟贴请附上试验报告 三、构建多级目录上
假设有这样一个视频网站网站首页上有3大栏目进入大栏目可看到5个小栏目小栏目再进去可以看到10个视频链接。针对网站这样的布局很容易设想出要做的视频插件要有3级目录进入到第3级也就是末级才开始观看视频。
在做这样的插件前我们必须首先学习xbmcplugin.addDirectoryItem(这个函数的用法这是构建目录时用到的最为关键的一个函数。
先看函数的原型原文在这里) addDirectoryItem(handle, url, listitem [,isFolder, totalItems]) -- Callback function to pass directory contents back to XBMC. - Returns a bool for successful completion.
handle : integer - handle the plugin was started with. url : string - url of the entry. would be plugin:// for another virtual directory listitem : ListItem - item to add. isFolder : [opt] bool - Truefolder / Falsenot a folder(default). totalItems : [opt] integer - total number of items that will be passed.(used for progressbar) 这个函数向xbmc传递目录的内容即往目录上添加目录项返回值表示是否成功。
函数有5个输入参数其中前3个必需后2个可选。
handle: 整数值句柄xbmc启动插件时赋予插件一个句柄 url 字符串视频的网址。如果是另一个目录的话则必须以plugin://打头plugin://后跟插件id名意思是下一级子目录由这个插件生成 listitem ListItem对象要加入的目录项ListItem对象中有很多属性和方法用来存放一个视频的标题、图片、路径等详细见这里这里我们只设置它的label属性 isFolder 布尔值True表示本项是个目录点下去还有子目录False表示本项是末级目录缺省值是False totalItems 整数值要加入的目录项的总数xbmc用来确定目录生成时进度条的进度不给这个参数进度条上无进度显示
为加深对这个函数的理解请你做个小试验把下面的代码复制到helloworld.py中启动xbmc进入helloworld插件看看再去查看xbmc的运行日志文件xmbc.log仔细研究日志中BEGIN和“END”之间的日志记录把url的值换成另一个再试一次再去看日志记录有什么不同直到试完5个替换值然后把xbmcplugin.addDirectoryItem(中的isFolder参数的值由True换成False再来一次再看看日志记录。经过这样的试验后基本上你就可以搞清楚xbmcplugin.addDirectoryItem(这个函数该怎么用才能正确地生成目录而不会出错。# -*- coding: utf-8 -*-
# helloworld.py
# hello world demo2 import xbmcplugin, xbmcgui urlplugin://plugin.video.hello
#urlplugin://plugin.noname.noname
#urlplugin://plugin.video.tudou/
#urlplugin://plugin.video.hello/abc/index.htm?urlexamplename123
#urlhttp://tv1.btv.com.cn/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4 print BEGIN: sys.argv[0]|sys.argv[1]|sys.argv[2]|
handleint(sys.argv[1])
listitemxbmcgui.ListItem(Hello, World!)
xbmcplugin.addDirectoryItem(handle, url, listitem, True)
xbmcplugin.endOfDirectory(handle)
print END 复制代码程序说明 增加了两个print语句一个打印插件脚本启动时xbmc传递给脚本的3个参数另一个报告脚本执行完毕。
在xbmc中运行插件程序和一般环境中运行python程序不同是没有调试器可用的程序的运行状况又不能显示到xbmc界面上程序的调试只能靠在程序中加些print语句打印变量值再到xbmc的日志记录中去查看。
同样跟贴也请附上试验报告把xbmc.log中的有关记录贴上来也行 三、构建多级目录下
经过上一篇的小试验我们了解了xbmc调用python脚本生成目录的机制以及xbmcplugin.addDirectoryItem(的用法现在做一个小结 1、插件脚本生成完目录后会退出不再运行等到点击某个目录项xbmc又再次调用脚本生成新的目录但是也有可能不再调用脚本而是直接播放视频这取决于生成该目录项时所使用的isFolder参数是True还是False 2、如果生成目录项时的isFolder参数是True目录项点击后xbmc会根据生成目录项时的另一个参数url调用对应的脚本生成下一级目录 3、xbmc调用脚本时会传递3个参数 sys.argv[0]: 格式plugin://插件id名/部分网址首次调用时无部分网址 sys.argv[1]: 句柄通常是0末级目录是-1 sys.argv[2]: 部分网址问号以后首次调用时为空白 显然要形成多级目录需要xbmc在用户的操作下多次调用脚本而我们可以通过精心设置url的值把生成目录所需要的有关参数传递给即将运行的脚本如网页的网址和处理模式、目录的名称等。
这里作为举例说明我把url设计成这种形式plugin://插件id名/?下一级目录的级数因为我的脚本只需要知道目录级数就能把目录做出来。
下面的代码就是针对开头提到那个假想网站所作它生成3X5X10的目录对应网站的3大栏目、5小栏目、10个视频的架构# -*- coding: utf-8 -*-
# helloworld.py
# hello world demo3 import xbmcplugin, xbmcgui # 各级目录的名称项目数
dirs[(大栏目, 3), (小栏目, 5), (视频, 10)] # 准备构建目录要用到的handle, url, isFolder变量
handleint(sys.argv[1])
dir_level0
isFolderTrue
if sys.argv[2]!: dir_levelint(sys.argv[2][1:])
urlsys.argv[0]?str(dir_level1)
if dir_level2: # 如果是最后一级目录 isFolderFalse urlhttp://tv1.btv.com.cn/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4 # 构建n条目录项
for i in range(dirs[dir_level][1]): listitemxbmcgui.ListItem(dirs[dir_level][0]str(i1)) xbmcplugin.addDirectoryItem(handle, url, listitem, isFolder) # 目录构建完了显示吧
xbmcplugin.endOfDirectory(handle) 复制代码多级目录做好了哪位帮忙发个屏幕截图上来 四、下载和处理网页
上一篇我们把多级目录做出来了不过是个“死”的目录要想做成一个“活”的目录还需要下载网页从中取出有关内容做为目录项的名字这样在网站更新时目录也一样会有变化。
在python里下载网页只需下面2条语句就搞定了import urllib
urllib.urlopen(http://live.sympy.org).readlines() 复制代码下载了网页剩下的就是过滤出我们想要的内容python里提供了正则表达式这一强大的文本处理工具。我们构造一个正则表达式让它去匹配网页中的具有某种特征的字符串把这些字符串取出来就做成了我们的目录。这有点象把一块有很多洞洞的板放在一幅画上我们只看露出来的那部分画。这部分代码在插件脚本中占大头也最繁琐要不停地尝试直到找到合适的正则表达式。
这里以“BTV在线”网站为例说明。首先观察网站的架构很象我们说过的“大小栏目-视频”架构仔细看各网页页面布局、风格都差不多。
再打开网页源文件看发现有关“大小栏目-视频”部分的html标签也很“整齐”显然网站内容是服务器端的程序自动生成的而非人工编辑生成的这真是方便了用程序进行处理。
以下在python的交互环境下逐条输入执行 import urllib fileurllib.urlopen(http://www.btv.com.cn/btvindex/xw/node_15140.htm) datafile.read() file.close() len(data)
31424 import re r1re.compile(div classtab_L(.?)div classtab_R, re.DOTALL) m1r1.search(data) m1
_sre.SRE_Match object at 0xb7307360 data2m1.group() r2re.compile(ul(.?)/ul, re.DOTALL) m2r2.findall(data2) len(m2)
40 r3re.compile(a .*href(.?).*(.?)/a, re.DOTALL) m3r3.search(m2[0]) m3
_sre.SRE_Match object at 0xb72e9c38 m3.groups()
(content/2012-04/01/content_4452273.htm, \xe6\xb8\x85\xe6\x98\x8e\xe6\x97\xb6\xe8\x8a\x82 \xe5\xa4\x96\xe5\x9b\xbd\xe4\xbd\xbf\xe8\x8a\x82\xe4\xbd\x93\xe9\xaa\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe6\x96\x87\xe5\x8c\x96) print m3.group(2)
清明时节 外国使节体验中国文化 复制代码到这里各目录项的url和名字弄出来了。看起来似乎我一下子就找到了那个正则表达式不是3个每个逐步地缩小过滤的范围。
实际上上面的代码是在通过多次试错成功后整理出来的期间要通过Web Developer或者Firebug之类的网页工具观察网页的结构这两个都是firefox上的插件确定出查找数据的步骤和方法。
3个正则表达式div classtab_L(.?)div classtab_R
li(.?)/li
a .*href(.?).*(.?)/a 复制代码第1个把要找的数据定位到某个div块内第2个分出n条可做为目录的数据第3个取出目录项的url和名称。嘿嘿似乎有(.?)这个东东就够用了它能取出俩字符串之间的内容。
看来可以动手写脚本了且慢我们才分析了一个网页怎么就知道这3个正则表达式适用于所有的网页呢还要多看几个网页才行...
果然发现有一类网页上面的正则表达式不管用了必须重新设计比如这个就是很快我们又设计了一组正则表达式去处理这个网页等我们把整个网站看完了有可能需要n组正则表达式。
为应对这种情况设计插件脚本时要考虑有个参数传递给脚本告诉它用哪组正则表达式干活。程序的架构基本上是每一类网页设一个函数处理有n类网页就有n个函数。
不多说了放上我写好的“BTV在线”插件0.0.1版装好就能用 五、进一步改进
1、直接播放视频listitemxbmcgui.ListItem(queries[name])
xbmc.Player().play(url, listitem) 复制代码这样可以少一级目录用xbmc库中的函数操控xbmc播放器如果视频有好几段需要给播放器做一个playlist。
2、用urllib2库下载网页requrllib2.Request(url)
req.add_header(User-Agent, user_agent)
responseurllib2.urlopen(req)
dataresponse.read()
response.close() 复制代码把xbmc伪装成IE下载网页还可以改Referer标头如果网站有防盗链措施的话。
3、网页的解压缩、编码转换import gzip, StringIO
datagzip.GzipFile(StringIO.StringIO(data)).read() 复制代码有些网站的网页需要做这样的处理
4、给目录加上图标listitemxbmcgui.ListItem(name, thumbnailImagethumbnail)
xbmcplugin.addDirectoryItem(handle, query, listitem, True, total_items) 复制代码如果网站上有好看的图片为什么不把它加到目录上呢
5、异常处理try: dataget_data(base)
except: error(func(): get_data()) 复制代码给容易发生异常的语句加上try/except避免出错时xbmc提示“脚本错误”。
6、分页name下一页
matchre.search(.*a .*href(.?)name/a, data)
if match: listitemxbmcgui.ListItem(name) xbmcplugin.addDirectoryItem(handle, query, listitem, True) 复制代码增加一个“下一页”的目录项
最后是改进后的“BTV在线”插件0.0.2版用了记得要报告使用情况哦 plugin.video.btv.zip (20.51 KB) 下载次数: 31
2012-4-3 11:56
本教程全文完
编写过程中得到了ailingtfl的支持和配合在此表示感谢 文章来源于“HTPC原动力论坛” http://bbs.htpc1.com/thread-198731-8-1.html