xbmc插件编写教程.docx_第1页
xbmc插件编写教程.docx_第2页
xbmc插件编写教程.docx_第3页
xbmc插件编写教程.docx_第4页
xbmc插件编写教程.docx_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、插件的结构每个插件保存在各自的文件夹里,打开xbmc插件的安装目录addons,可以看到很多安装好的插件的文件夹。一个典型的视频插件的文件夹里通常要有这三个文件:addon.xml:说明文件,用来告诉xbmc该插件所提供的内容以及安装要求;icon.png:图标文件,256x256像素,xbmc插件清单旁边显示的就是这个图标;*.py:python主程序文件,名字随便起,addon.xml中有一项会用到这个文件名。 如果插件的子程序和用到的数据较多,可以在下面再开子文件夹来保存。重点看addon.xml的结构: 首先第一行申明这是一个xml文件,且是utf-8编码的,接着是元素,在和之间,有一个或多个元素,每个告诉xbmc这个插件扩展了哪一部分的功能,只有最后一个比较特别,只是用来向用户做个说明。元素有4个属性:id, version, name, provider-nameid属性:插件id,必须是唯一的,小写,插件zip文件解压后,以id命名文件夹,所以不能重名,建议以plugin.的形式命名,类别可以是video, audio, script等;version属性:插件版本号,格式为x.x.x,xbmc用来确定是否应升级插件;name属性:插件名称;provider-name属性:插件作者。元素通过point属性告诉xbmc该插件扩展的类型,有多种类型,用python写的视频插件属xbmc.python.pluginsource类型,同时还应加上一个library属性告诉xbmc启动插件时运行哪个python程序。video告诉xbmc这是对视频功能的扩展。最后一个xbmc.addon.metadata类型的元素用来说明插件的运行环境、摘要、详情、申明等,英文的必须有,中文的可有可无。插件做好后,把所有文件压缩进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的文件,内容如下: video all hello world plugin helloworld演示插件 hello world plugin, python script helloworld演示插件,python脚本 For demonstration only 4、再用记事本生成一个名为helloworld.py的文件,内容如下:# -*- coding: utf-8 -*-# helloworld.py# hello world demoimport xbmcplugin, xbmcguiurl=/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4handle=int(sys.argv1)listitem=xbmcgui.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 directorylistitem : ListItem - item to add.isFolder : opt bool - True=folder / False=not 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表示本项是末级目录,缺省值是FalsetotalItems: 整数值,要加入的目录项的总数,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 demo2import xbmcplugin, xbmcguiurl=plugin:/plugin.video.hello#url=plugin:/plugin.noname.noname#url=plugin:/plugin.video.tudou/#url=plugin:/plugin.video.hello/abc/index.htm?url=example&name=123#url=/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4print BEGIN: +sys.argv0+|+sys.argv1+|+sys.argv2+|handle=int(sys.argv1)listitem=xbmcgui.ListItem(Hello, World!)xbmcplugin.addDirectoryItem(handle, url, listitem, True)xbmcplugin.endOfDirectory(handle)print END程序说明:增加了两个print语句,一个打印插件脚本启动时xbmc传递给脚本的3个参数,另一个报告脚本执行完毕。在xbmc中运行插件程序和一般环境中运行python程序不同,是没有调试器可用的,程序的运行状况又不能显示到xbmc界面上,程序的调试只能靠在程序中加些print语句打印变量值,再到xbmc的日志记录中去查看。三、构建多级目录(下)经过上一篇的小试验,我们了解了xbmc调用python脚本生成目录的机制,以及xbmcplugin.addDirectoryItem()的用法,现在做一个小结:1、插件脚本生成完目录后会退出不再运行,等到点击某个目录项,xbmc又再次调用脚本生成新的目录,但是也有可能不再调用脚本,而是直接播放视频,这取决于生成该目录项时所使用的isFolder参数是True还是False;2、如果生成目录项时的isFolder参数是True,目录项点击后,xbmc会根据生成目录项时的另一个参数url调用对应的脚本生成下一级目录;3、xbmc调用脚本时会传递3个参数:sys.argv0: 格式:plugin:/插件id名/部分网址,首次调用时无部分网址sys.argv1: 句柄,通常是0,末级目录是-1sys.argv2: 部分网址(问号以后),首次调用时为空白显然要形成多级目录,需要xbmc在用户的操作下多次调用脚本,而我们可以通过精心设置url的值,把生成目录所需要的有关参数传递给即将运行的脚本,如网页的网址和处理模式、目录的名称等。这里作为举例说明,我把url设计成这种形式:plugin:/插件id名/?下一级目录的级数,因为我的脚本只需要知道目录级数就能把目录做出来。下面的代码就是针对开头提到那个假想网站所作,它生成3X5X10的目录,对应网站的3大栏目、5小栏目、10个视频的架构# -*- coding: utf-8 -*-# helloworld.py# hello world demo3import xbmcplugin, xbmcgui# 各级目录的名称,项目数dirs=(大栏目, 3), (小栏目, 5), (视频, 10)# 准备构建目录要用到的handle, url, isFolder变量handle=int(sys.argv1)dir_level=0isFolder=Trueif sys.argv2!=: dir_level=int(sys.argv21:)url=sys.argv0+?+str(dir_level+1)if dir_level=2: # 如果是最后一级目录 isFolder=False url=/asset/2012/03/27/BTV1_20120327_183405049_742928_23560.mp4# 构建n条目录项for i in range(dirsdir_level1): listitem=xbmcgui.ListItem(dirsdir_level0+str(i+1) xbmcplugin.addDirectoryItem(handle, url, listitem, isFolder)# 目录构建完了,显示吧xbmcplugin.endOfDirectory(handle)四、下载和处理网页上一篇我们把多级目录做出来了,不过是个“死”的目录,要想做成一个“活”的目录,还需要下载网页,从中取出有关内容做为目录项的名字,这样在网站更新时,目录也一样会有变化。在python里下载网页,只需下面2条语句就搞定了:import urlliburllib.urlopen().readlines()下载了网页,剩下的就是过滤出我们想要的内容,python里提供了正则表达式这一强大的文本处理工具。我们构造一个正则表达式让它去匹配网页中的具有某种特征的字符串,把这些字符串取出来,就做成了我们的目录。这有点象把一块有很多洞洞的板放在一幅画上,我们只看露出来的那部分画。这部分代码在插件脚本中占大头,也最繁琐,要不停地尝试,直到找到合适的正则表达式。这里以“BTV在线”网站为例说明。首先观察网站的架构,很象我们说过的“大小栏目-视频”架构,仔细看各网页页面,布局、风格都差不多。再打开网页源文件看,发现有关“大小栏目-视频”部分的html标签也很“整齐”,显然网站内容是服务器端的程序自动生成的,而非人工编辑生成的,这真是方便了用程序进行处理。以下在python的交互环境下逐条输入执行 import urllib file=urllib.urlopen(/btvindex/xw/node_15140.htm) data=file.read() file.close() len(data)31424 import re r1=pile(.+?), re.DOTALL) m1=r1.search(data) m1 data2=m1.group() r2=pile(.+?), re.DOTALL) m2=r2.findall(data2) len(m2)40 r3=pile(.+?), re.DOTALL) m3=r3.search(m20) m3 m3.groups()(content/2012-04/01/content_4452273.htm, xe6xb8x85xe6x98x8exe6x97xb6xe8x8ax82 xe5xa4x96xe5x9bxbdxe4xbdxbfxe8x8ax82xe4xbdx93xe9xaax8cxe4xb8xadxe5x9bxbdxe6x96x87xe5x8cx96) print m3.group(2)清明时节 外国使节体验中国文化到这里各目录项的url和名字弄出来了。看起来似乎我一下子就找到了那个正则表达式,不,是3个,每个逐步地缩小过滤的范围。实际上上面的代码是在通过多次试错成功后整理出来的,期间要通过Web Developer或者Firebug之类的网页工具观察网页的结构(这两个都是firefox上的插件),确定出查找数据的步骤和方法。3个正则表达式:(.+?)(.+?)(.+?)第1个把要找的数据定位到某个块内,第2个分出n条可做为目录的数据,第3个取出目录项的url和名称。嘿嘿,似乎有(.+?)这个东东就够用了,它能取出俩字符串之间的内容。看来可以动手写脚本了,且慢,我们才分析了一个网页,怎么就知道这3个正则表达式适用于所有的网页呢?还要多看几个网页才行.果然,发现有一类网页,上面的正则表达式不管用了,必须重新设计,比如这个就是,很快我们又设计了一组正则表达式去处理这个网页,等我们把整个网站看完了,有可能需要n组正则表达式。为应对这种情况,设计插件脚本时,要考虑有个参数传递给脚本,告诉它用哪组正则表达式干活。程序的架构基本上是每一类网页设一个函数处理,有n类网页就有n个函数。不多说了,放上我写好的“BTV在线”插件0.0.1版,装好就能用。五、进一步改进1、直接播放视频listitem=xbmcgui.ListItem(queriesname)xbmc.Player().play(url, listitem)这样可以少一级目录,用xbm

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论