Need some help with a channel.

Hi I need some help. I am trying to build a very basic channel thing for watching my thheadend channels trough PMC / PHT via PMS.

When I say very basic i just need to parse an xml file (that for the time being I am coding by hand). And with the info from the xml file build a list with my channels. No EPG or icons or anything like that at the moment.

 

Well here is what I have done so far 

###################################################################################################
NAME = 'TVHeadend'
ART = 'art-default.jpg'
ICON = 'icon-default.png'
PLUGIN_PREFIX = '/video/tvheadend'
structure = 'stream/channelid'
htsurl = 'http://%s:%s@%s:%s/%s/' % (Prefs['tvheadend_user'], Prefs['tvheadend_pass'], Prefs['tvheadend_host'], Prefs['tvheadend_port'], structure)
####################################################################################################

def Start():
Plugin.AddPrefixHandler(PLUGIN_PREFIX, MainMenu, NAME, ICON, ART)

    ObjectContainer.art = R(ART)
    #objectContainer.title1 = NAME

    TrackObject.thumb = R(ICON)

####################################################################################################

def MainMenu():

    oc = ObjectContainer(no_cache = True)
    oc.add(DirectoryObject(key = Callback(ChannelsMenu, title = L('Channels')), title = L('Channels')))
    oc.add(DirectoryObject(key = Callback(XmlMenu, title = L('Xml')), title = L('Xml')))
    oc.add(PrefsObject(title = L('Preferences')))

    return oc

def ChannelsMenu(title):
oc = ObjectContainer(view_group=‘InfoList’)

    oc = ObjectContainer(title1="Channels")
    mo = MediaObject(parts=[PartObject(key=HTTPLiveStreamURL("%s25" % (htsurl)))])
    vco = VideoClipObject(title="C More Sport", url='%s25' % (htsurl))
    vco.add(mo)
    oc.add(vco)

    return oc

def XmlMenu(title):
oc = ObjectContainer(view_group=‘InfoList’)
oc = ObjectContainer(title1=“Channels”)
from xml.dom import minidom
xmldoc = minidom.parse(‘channels.xml’)
itemlist = xmldoc.getElementsByTagName(‘channel’)
##code below is just what i used to see that could print out what was in the xml file in python.
#print len(itemlist)
#print itemlist[0].attributes[‘name’].value
#for s in itemlist :
#print s.attributes[‘name’].value

    return oc

So the part with "

def ChannelsMenu(title):
oc = ObjectContainer(view_group='InfoList')

oc = ObjectContainer(title1="Channels")
mo = MediaObject(parts=[PartObject(key=HTTPLiveStreamURL("%s25" % (htsurl)))])
vco = VideoClipObject(title="C More Sport", url='%s25' % (htsurl))
vco.add(mo)
oc.add(vco)

"
Is working to start C More Sport within PHT/PMC
 
However what I want to do is to use my XML file that currently looks like this (it should also include the idnumber number for the channel, not sure how to add that info to in the xml file.)

        
                
                
                
                
        

to build a menu with all channels listed in the xml file.

 

Two problems i have is that I don't know where I should have the xml file in the plugin structure right now the log complains that it does not find it.

 

2013-07-03 15:38:43,491 (7fed26ed2700) :  DEBUG (runtime:143) - Calling function 'XmlMenu'
2013-07-03 15:38:43,533 (7fed26ed2700) :  CRITICAL (sandbox:303) - Exception when calling function 'XmlMenu' (most recent call last):
  File "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-ins/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/code/sandbox.py", line 294, in call_named_function
    result = f(*args, **kwargs)
  File "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-ins/tvheadend.bundle/Contents/Code/__init__.py", line 46, in XmlMenu
    xmldoc = minidom.parse('channels.xml')
  File "/usr/lib/plexmediaserver/Resources/Python/lib/python2.7/xml/dom/minidom.py", line 1914, in parse
    return expatbuilder.parse(file)
  File "/usr/lib/plexmediaserver/Resources/Python/lib/python2.7/xml/dom/expatbuilder.py", line 922, in parse
    fp = open(file, 'rb')
IOError: [Errno 2] No such file or directory: 'channels.xml'

The other is that I can't figure out the code how to make it build a menu with the info from the xml file.

I have very little to no knowledge of programming so this is a very high learning curve for me.

 

Any help on this?

 

Oh and while we are at it The Preference menu does not show for some reason. And I know that it was working before when I started this project a very long time ago.

DefaultPrefs.json

[
    {
        "id": "tvheadend_user",
        "label": "Username",
        "type": "text",
        "default": ""
    },
    {
        "id": "tvheadend_pass",
        "label": "Password",
        "type": "text",
        "option": "hidden",
        "default": ""
    },
    {
        "id": "tvheadend_host",
        "label": "HOST",
        "type": "text",
        "default": ""
    },
    {
        "id": "tvheadend_port",
        "label": "port",
        "type": "text",
        "default": "9981"
    }
]

 

 

In regards to the xml file:

1) Place it in the plugin's resource folder. Then you can access it like so:

xml_file = Resource.Load('channels.xml')
xml_content = XML.ElementFromString(xml_file)

2) As you can see above, the channel framework has build in XML parsing so that you don't need to import minidom. (XML.ELementFromURL is also available).

3) You can add multiple keys to an xml element, like so:

<?xml version="1.0" ?> 

      
            
            
            
            
      

As far as building a menu from the xml data goes, a "for" loop is the most common tool. You can see here how it is used in the channel for The Colbert Report. In that case, it is parsing an HTML page rather than XML but, there are only minor functional differences in terms of how it is handled in channel code. You can read more about using xpath to parse xml/html content in Gerk's blog post here.

I can't think of a reason off the top of my head why the prefs menu wouldn't show up. Hopefully that's just a passing glitch and will rectify itself  ;)

Thanks for help. I have been trying to understand and poked around with the info you gave me but no luck yet.

I am not sure how to adapted the code from colbert and apply it to mine. 

Scratching my head against a wall here .

Made some changes to the code and I thought I got the part right with "for" and "xpath" and "stuff".

but when I push the Channels link I get "No Items are available"

I thought that I just should attempt with a start to get it list the channels but not add any code for playing the channels yet just so I know I am parsing the xml correct.

log says 

2013-07-04 15:44:32,240 (7f259d36a700) :  DEBUG (runtime:714) - Handling request GET /:/prefixes
2013-07-04 15:44:32,242 (7f259d36a700) :  DEBUG (runtime:811) - Found route matching /:/prefixes
2013-07-04 15:44:32,244 (7f259d36a700) :  DEBUG (runtime:911) - Response: [200] MediaContainer, 741 bytes
2013-07-04 15:44:32,451 (7f2591a14700) :  DEBUG (runtime:714) - Handling request GET /video/tvheadend/:/function/GetChannels?function_args=Y2VyZWFsMQoxCmRpY3QKMQp1MTMKSFRTLVRWaGVhZGVuZHM5CnByZXZUaXRsZXIwCg__
2013-07-04 15:44:32,467 (7f2591a14700) :  DEBUG (runtime:811) - Found route matching /video/tvheadend/:/function/GetChannels
2013-07-04 15:44:32,467 (7f2591a14700) :  DEBUG (runtime:143) - Calling function 'GetChannels'
2013-07-04 15:44:32,469 (7f2591a14700) :  DEBUG (runtime:911) - Response: [200] MediaContainer, 310 bytes

New Code

####################################################################################################
NAME = 'TVHeadend'
ART = 'art-default.jpg'
ICON = 'icon-default.png'
PLUGIN_PREFIX = '/video/tvheadend'
structure = 'stream/channelid'
htsurl = 'http://%s:%s@%s:%s/%s/' % (Prefs['tvheadend_user'], Prefs['tvheadend_pass'], Prefs['tvheadend_host'], Prefs['tvheadend_port'], structure)
xml_file = Resource.Load('channels.xml')

#Texts
TEXT_TITLE = u’HTS-TVheadend’
TEXT_CHANNELS = u’Channels’

####################################################################################################

def Start():
Plugin.AddPrefixHandler(PLUGIN_PREFIX, MainMenu, NAME, ICON, ART)

    ObjectContainer.art = R(ART)
    TrackObject.thumb = R(ICON)

####################################################################################################

@handler(’/video/tvheadend’, TEXT_TITLE, thumb=ICON, art=ART)
def MainMenu():

    menu = ObjectContainer(title1=TEXT_TITLE)
    menu.add(DirectoryObject(key=Callback(GetChannels, prevTitle=TEXT_TITLE), title=TEXT_CHANNELS,))
    menu.add(PrefsObject(title='Preferences'))

    return menu

def GetChannels(prevTitle):

    xml_content = XML.ElementFromString(xml_file)
    channelname = xml_content.xpath("//channel[@class='name']")
    channelList = ObjectContainer(title1=prevTitle, title2=TEXT_CHANNELS)


    for s in channelname:
            channelList.add(s)

    return channelList

Looks like you're just adding the text strings for the names of the channels to your ObjectContainer. The channel framework expects ObjectContainers to contain objects, like you did in your original ChannelsMenu(). The documentation discusses the different defined types of objects here

I would recommend something to the effect of:

def GetChannels(prevTitle):
    xml_content = XML.ElementFromString(xml_file)
    channels = xml_content.xpath("//channel")
    channelList = ObjectContainer(title1=prevTitle, title2=TEXT_CHANNELS)


    for channel in channels:
            name = channel.get('name')
            id = channel.get('id')
            mo = MediaObject(parts=[PartObject(key=HTTPLiveStreamURL("%s%s" % (htsurl, id)))])
            vco = VideoClipObject(title=name, url='%s%s' % (htsurl, id))
            vco.add(mo)
            channelList.add(vco)

    return channelList

You sir are a genius =)

It works like a charm now thank you.

I will probably soon be back with more stupid questions =)

B)

So here is the code for my TVheadend channel: https://github.com/moxz/tvheadend.bundle

For the time being it only works in PHT/PMC.

It has a very experimental support for transcoding via tvheadend. This requires a git version of tv headend with transcoding enabled at build time.

To enable encoding in TVheadend do the following

Edit tvheadendscr/src/plumbing/transcoding.c and set the variable enable_transcoding to 1 instead of 0.

before configure and build.

The channel.xml file has to be edited by hand to suit your channels and their id's and icons.

Thanks to everyone that has written channels that I have borrowed code from and big thanks to Mikedm139 that wrote the missing link to read out the code from the xml file.

Wanted something like this for ages, thanks for starting this! I just added a feature that you can now fetch the channels directly from tvheadend instead of using the channel.xml file.

Never used github before, but made a fork and send you a pull request. :)

Wanted something like this for ages, thanks for starting this! I just added a feature that you can now fetch the channels directly from tvheadend instead of using the channel.xml file.

Never used github before, but made a fork and send you a pull request. :)

Great work.

I have merged your code. This is far better than I hoped for a week ago =)

Great work.

I have merged your code. This is far better than I hoped for a week ago =)

Thanks :) I have just added tag support and send you another pull request. Should also work if you dont have tags as you can now select between: Tags, Channels in the menu option.

My good I was trying to understand how to fix tags all day long and you fix it =)

Merge request is done.

\o/ Been pondering how i can get the plugin to work with Plex on my samsung tv, for some reason it starts streaming, but the tv doest understand it, it seems. (havent tried transcoding yet though)

\o/ Been pondering how i can get the plugin to work with Plex on my samsung tv, for some reason it starts streaming, but the tv doest understand it, it seems. (havent tried transcoding yet though)

My guess is that the samsung can't handle the stream. So I guess we need transcoding.

I haven't gotten my tvheadend to encode to h264 with aac yet I get errors on aac even tough I have a perfectly working ffmpeg with aac support.

Still working on it.

Moved to http://forums.plexapp.com/index.php/topic/73746-hts-tvheadend-channel/

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