HOW-TO:Video addon: Difference between revisions

From Official Kodi Wiki
Jump to navigation Jump to search
Takoi (talk | contribs)
This page is not at place to dump links to external tutorials
Roman VM (talk | contribs)
No edit summary
 
(4 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{mininav|[[Development]]|[[Add-on development]]|[[Python development]]|[[Python examples]]}}
{{mininav|[[Development]]|[[Add-on development]]|[[Python development]]}}
<br />
<br />


Line 12: Line 12:


=Installing=
=Installing=
For this example we will use 2 nice basic video Add-on tutorials You can find the source-code here:
You can find the Add-on source code here:


https://github.com/romanvm/plugin.video.example
https://github.com/romanvm/plugin.video.example


You can either download as a zip and install both of these inside the kodi GUI from the install from zip feature. Or extract the zip into your userdata/add-ons folder.
You need to download an installable zip from "Releases" section of the repo and install it from the '''Addons''' section of kodi GUI  
by clicking a "package" icon in the top left corner and selecting "Instal from ZIP".
 
Note that Kodi no longer supports "drop in" installing by copying addon files into '''addon''' sub-directory of the Kodi profile directory.


=Testing=
=Testing=
Line 22: Line 25:
System >> Add-Ons >> Enabled Add-Ons >> Video Add-Ons >> Example Kodi video Plugin. You should now be able to watch some test videos hosted from an internet web server.
System >> Add-Ons >> Enabled Add-Ons >> Video Add-Ons >> Example Kodi video Plugin. You should now be able to watch some test videos hosted from an internet web server.


[[File:Videotutorial1.jpg]]
[[File:Plugin-video-example.jpg.jpg]]


=Explanation=
=Explanation=
Line 43: Line 46:
So now we come to the actual Add-On code, this is where most of your Add-on is written and is a simple text file containing python code.
So now we come to the actual Add-On code, this is where most of your Add-on is written and is a simple text file containing python code.


First we initialize the Add-on and import and bits we need
Since this is a very simple Add-On, all its code are located in https://github.com/romanvm/plugin.video.example/blob/master/main.py file that is the Add-On entry point.
Read the comments in the file that explain what each part of the code does.


<syntaxhighlight lang="python" enclose="div">
More complex Add-Ons may include additional modules and packages. In this case a good practice is to put only minimal code in your Add-On entrypoint and keep the rest
    import sys
of the code in importable modueles.
    from urlparse import parse_qsl
    import xbmcgui
    import xbmcplugin
</syntaxhighlight>


Now we do something else...
=Changing the code=


<syntaxhighlight lang="python" enclose="div">
Hopefully by now you have managed to run the Add-On, understand the structure and can see what the code can do. Now lets trying changing it a little!
    # Get the plugin url in plugin:// notation.
    __url__ = sys.argv[0]
    # Get the plugin handle as an integer number.
    __handle__ = int(sys.argv[1])
</syntaxhighlight>


Here we use a fixed set of properties simply for demonstrating purposes. In a "real life" plugin you will need to get info and links to video files/streams from some web-site or online service.
Since we already have the Add-on installed we can go directly to the Kodi userdata folder and edit the python directly. You can also have Kodi open at this time ready to run the Add-on when required. Just switch between your text editor and Kodi any time.


<syntaxhighlight lang="python" enclose="div">
Note that all the data for video strams are located in movies.json file. This allows to separate media information from the actual Python code.
VIDEOS = {'Animals': [{'name': 'Crab',
                      'thumb': 'http://www.vidsplay.com/vids/crab.jpg',
                      'video': 'http://www.vidsplay.com/vids/crab.mp4',
                      'genre': 'Animals'},
                      {'name': 'Alligator',
                      'thumb': 'http://www.vidsplay.com/vids/alligator.jpg',
                      'video': 'http://www.vidsplay.com/vids/alligator.mp4',
                      'genre': 'Animals'},
                      {'name': 'Turtle',
                      'thumb': 'http://www.vidsplay.com/vids/turtle.jpg',
                      'video': 'http://www.vidsplay.com/vids/turtle.mp4',
                      'genre': 'Animals'}
                      ],
            'Cars': [{'name': 'Postal Truck',
                      'thumb': 'http://www.vidsplay.com/vids/us_postal.jpg',
                      'video': 'http://www.vidsplay.com/vids/us_postal.mp4',
                      'genre': 'Cars'},
                    {'name': 'Traffic',
                      'thumb': 'http://www.vidsplay.com/vids/traffic1.jpg',
                      'video': 'http://www.vidsplay.com/vids/traffic1.avi',
                      'genre': 'Cars'},
                    {'name': 'Traffic Arrows',
                      'thumb': 'http://www.vidsplay.com/vids/traffic_arrows.jpg',
                      'video': 'http://www.vidsplay.com/vids/traffic_arrows.mp4',
                      'genre': 'Cars'}
                    ],
            'Food': [{'name': 'Chicken',
                      'thumb': 'http://www.vidsplay.com/vids/chicken.jpg',
                      'video': 'http://www.vidsplay.com/vids/bbqchicken.mp4',
                      'genre': 'Food'},
                    {'name': 'Hamburger',
                      'thumb': 'http://www.vidsplay.com/vids/hamburger.jpg',
                      'video': 'http://www.vidsplay.com/vids/hamburger.mp4',
                      'genre': 'Food'},
                    {'name': 'Pizza',
                      'thumb': 'http://www.vidsplay.com/vids/pizza.jpg',
                      'video': 'http://www.vidsplay.com/vids/pizza.mp4',
                      'genre': 'Food'}
                    ]}
</syntaxhighlight>
And now we define something else...


<syntaxhighlight lang="python" enclose="div">
Try changing some of the links to another jpeg file or hosted online video. Also try to change the genre and see how that effects the view in Kodi.
def get_categories():
        """
        Get the list of video categories.
        Here you can insert some parsing code that retrieves
        the list of video categories (e.g. 'Movies', 'TV-shows', 'Documentaries' etc.)
        from some site or server.
        :return: list
        """
        return VIDEOS.keys()
</syntaxhighlight>
And now we define something else...


<syntaxhighlight lang="python" enclose="div">
Click save on your text editor and now try running the Add-On inside Kodi. You should see the new video links and navigation right away.
def get_videos(category):
    """
    Get the list of videofiles/streams.
    Here you can insert some parsing code that retrieves
    the list of videostreams in a given category from some site or server.
    :param category: str
    :return: list
    """
    return VIDEOS[category]
</syntaxhighlight>
And now we define the list of categories


<syntaxhighlight lang="python" enclose="div">
Congratulations! you've just played an online video from your very own Video Add-on
def list_categories():
    """
    Create the list of video categories in the Kodi interface.
    :return: None
    """
    # Get video categories
    categories = get_categories()
    # Create a list for our items.
    listing = []
    # Iterate through categories
    for category in categories:
        # Create a list item with a text label and a thumbnail image.
        list_item = xbmcgui.ListItem(label=category, thumbnailImage=VIDEOS[category][0]['thumb'])
        # Set a fanart image for the list item.
        # Here we use the same image as the thumbnail for simplicity's sake.
        list_item.setProperty('fanart_image', VIDEOS[category][0]['thumb'])
        # Set additional info for the list item.
        # Here we use a category name for both properties for for simplicity's sake.
        # setInfo allows to set various information for an item.
        # For available properties see the following link:
        # http://mirrors.xbmc.org/docs/python-docs/15.x-isengard/xbmcgui.html#ListItem-setInfo
        list_item.setInfo('video', {'title': category, 'genre': category})
        # Create a URL for the plugin recursive callback.
        # Example: plugin://plugin.video.example/?action=listing&category=Animals
        url = '{0}?action=listing&category={1}'.format(__url__, category)
        # is_folder = True means that this item opens a sub-list of lower level items.
        is_folder = True
        # Add our item to the listing as a 3-element tuple.
        listing.append((url, list_item, is_folder))
    # Add our listing to Kodi.
    # Large lists and/or slower systems benefit from adding all items at once via addDirectoryItems
    # instead of adding one by ove via addDirectoryItem.
    xbmcplugin.addDirectoryItems(__handle__, listing, len(listing))
    # Add a sort method for the virtual folder items (alphabetically, ignore articles)
    xbmcplugin.addSortMethod(__handle__, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
    # Finish creating a virtual folder.
    xbmcplugin.endOfDirectory(__handle__)
</syntaxhighlight>
 
And here we list the videos
 
<syntaxhighlight lang="python" enclose="div">
def list_videos(category):
    """
    Create the list of playable videos in the Kodi interface.
    :param category: str
    :return: None
    """
    # Get the list of videos in the category.
    videos = get_videos(category)
    # Create a list for our items.
    listing = []
    # Iterate through videos.
    for video in videos:
        # Create a list item with a text label and a thumbnail image.
        list_item = xbmcgui.ListItem(label=video['name'], thumbnailImage=video['thumb'])
        # Set a fanart image for the list item.
        # Here we use the same image as the thumbnail for simplicity's sake.
        list_item.setProperty('fanart_image', video['thumb'])
        # Set additional info for the list item.
        list_item.setInfo('video', {'title': video['name'], 'genre': video['genre']})
        # Set 'IsPlayable' property to 'true'.
        # This is mandatory for playable items!
        list_item.setProperty('IsPlayable', 'true')
        # Create a URL for the plugin recursive callback.
        # Example: plugin://plugin.video.example/?action=play&video=http://www.vidsplay.com/vids/crab.mp4
        url = '{0}?action=play&video={1}'.format(__url__, video['video'])
        # Add the list item to a virtual Kodi folder.
        # is_folder = False means that this item won't open any sub-list.
        is_folder = False
        # Add our item to the listing as a 3-element tuple.
        listing.append((url, list_item, is_folder))
    # Add our listing to Kodi.
    # Large lists and/or slower systems benefit from adding all items at once via addDirectoryItems
    # instead of adding one by ove via addDirectoryItem.
    xbmcplugin.addDirectoryItems(__handle__, listing, len(listing))
    # Add a sort method for the virtual folder items (alphabetically, ignore articles)
    xbmcplugin.addSortMethod(__handle__, xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE)
    # Finish creating a virtual folder.
    xbmcplugin.endOfDirectory(__handle__)
</syntaxhighlight>


Now we tell Kodi how to find the video path to play the videos
=Streaming Video=
In addition to this guide, here are some comments from an experienced developer who has worked with streaming video sites:


<syntaxhighlight lang="python" enclose="div">
The docs will help you a lot, way more than any wiki.
def play_video(path):
    """
    Play a video by the provided path.
    :param path: str
    :return: None
    """
    # Create a playable item with a path to play.
    play_item = xbmcgui.ListItem(path=path)
    # Pass the item to the Kodi player.
    xbmcplugin.setResolvedUrl(__handle__, True, listitem=play_item)
</syntaxhighlight>


This is the router function
https://xbmc.github.io/docs.kodi.tv/master/kodi-base/index.html


<syntaxhighlight lang="python" enclose="div">
Speaking of docs, the ListItem reference will be most useful, time and time again.
def router(paramstring):
    """
    Router function that calls other functions
    depending on the provided paramstring
    :param paramstring:
    :return:
    """
    # Parse a URL-encoded paramstring to the dictionary of
    # {<parameter>: <value>} elements
    params = dict(parse_qsl(paramstring[1:]))
    # Check the parameters passed to the plugin
    if params:
        if params['action'] == 'listing':
            # Display the list of videos in a provided category.
            list_videos(params['category'])
        elif params['action'] == 'play':
            # Play a video from a provided URL.
            play_video(params['video'])
    else:
        # If the plugin is called from Kodi UI without any parameters,
        # display the list of video categories
        list_categories()
</syntaxhighlight>


Call the router function
https://xbmc.github.io/docs.kodi.tv/master/kodi-base/d8/d29/group__python__xbmcgui__listitem.html


<syntaxhighlight lang="python" enclose="div">
Since you're relying on a streaming platform you won't need to do anything particular yourself, you can get away with fetching the data and posting an item with the URL of the video. InputStream.Adaptive configuration might be needed, especially if the videos need DRM.
if __name__ == '__main__':
    # Call the router function and pass the plugin call parameters to it.
    router(sys.argv[2])
</syntaxhighlight>


=Changing the code=
You can get a lot done with the requests module, depending on the data you're processing. It's fully supported in Kodi, cookie and sessions included.
In short, it's really simple, you:


Hopefully by now you have managed to run the Add-On, understand the structure and can see what the code can do. Now lets trying changing it a little!
- get the information you need off the internet (title/URL could suffice for a start);


Since we already have the Add-on installed we can go directly to the Kodi userdata folder and edit the python directly. You can also have Kodi open at this time ready to run the Add-on when required. Just switch between your text editor and Kodi any time.
- you generate items that Kodi will treat as video sources (see xbmcplugin.addDirectoryItem() and xbmcgui.ListItem());


Now open up the main.py file from your userdata folder and lets change what the text says.
You could also read the sources of plugins such as AsciiDisco's Netflix or Sandmann79's Amazon/AmazonVOD addons.


                'Cars': [{'name': 'Postal Truck',
You can read more in this thread
                      'thumb': 'http://www.vidsplay.com/vids/us_postal.jpg',
https://forum.kodi.tv/showthread.php?tid=348328
                      'video': 'http://www.vidsplay.com/vids/us_postal.mp4',
                      'genre': 'Cars'},
 
Try changing some of the links to another jpeg file or hosted online video. Also try to change the genre and see how that effects the view in Kodi.
 
Click save on your text editor and now try running the Add-On inside Kodi. You should see the new video links and navigation right away.
 
Congratulations! you've just played an online video from your very own Video Add-on


=Final Thoughts=
=Final Thoughts=

Latest revision as of 11:21, 21 June 2025

  ▶ Development ▶ Add-on development ▶ Python development ▶ HOW-TO:Video addon


Introduction

This tutorial will explain how to write your first Kodi/XBMC video plugin Add-on

Tools

Assuming you have already followed the Hello World Add-on you will have a text editor already setup. Since we are dealing with videos this time its probably a good idea to have a video player setup. We recommend another great open source project for this

- VLC http://www.videolan.org/vlc/


Installing

You can find the Add-on source code here:

https://github.com/romanvm/plugin.video.example

You need to download an installable zip from "Releases" section of the repo and install it from the Addons section of kodi GUI by clicking a "package" icon in the top left corner and selecting "Instal from ZIP".

Note that Kodi no longer supports "drop in" installing by copying addon files into addon sub-directory of the Kodi profile directory.

Testing

You can first give the add-on a test run by going to: System >> Add-Ons >> Enabled Add-Ons >> Video Add-Ons >> Example Kodi video Plugin. You should now be able to watch some test videos hosted from an internet web server.

Explanation

So whats happening in this add-on?

Basically the Add-on is checking a website for the hosted videos. In this example we are directly linking to the videos, but there are possibilities for dynamic content and scraping of just about any online source

Once the video link is sent to Kodi, our video player takes over and buffers, then plays the video just like any other media.

Structure

main.py <-- This is the actual python code for your Add-On

addon.xml <-- This is the Add-Ons metadata

icon.png <-- A PNG icon for the add-on. It can be 256x256 or 512x512 pixels big. Try to make it look nice!

Readme.md <-- The readme text file with a description of the Add-on and install instructions. This shows on the front of the GitHub page and helps users to understand your Add-on before downloading.

The Code

So now we come to the actual Add-On code, this is where most of your Add-on is written and is a simple text file containing python code.

Since this is a very simple Add-On, all its code are located in https://github.com/romanvm/plugin.video.example/blob/master/main.py file that is the Add-On entry point. Read the comments in the file that explain what each part of the code does.

More complex Add-Ons may include additional modules and packages. In this case a good practice is to put only minimal code in your Add-On entrypoint and keep the rest of the code in importable modueles.

Changing the code

Hopefully by now you have managed to run the Add-On, understand the structure and can see what the code can do. Now lets trying changing it a little!

Since we already have the Add-on installed we can go directly to the Kodi userdata folder and edit the python directly. You can also have Kodi open at this time ready to run the Add-on when required. Just switch between your text editor and Kodi any time.

Note that all the data for video strams are located in movies.json file. This allows to separate media information from the actual Python code.

Try changing some of the links to another jpeg file or hosted online video. Also try to change the genre and see how that effects the view in Kodi.

Click save on your text editor and now try running the Add-On inside Kodi. You should see the new video links and navigation right away.

Congratulations! you've just played an online video from your very own Video Add-on

Streaming Video

In addition to this guide, here are some comments from an experienced developer who has worked with streaming video sites:

The docs will help you a lot, way more than any wiki.

https://xbmc.github.io/docs.kodi.tv/master/kodi-base/index.html

Speaking of docs, the ListItem reference will be most useful, time and time again.

https://xbmc.github.io/docs.kodi.tv/master/kodi-base/d8/d29/group__python__xbmcgui__listitem.html

Since you're relying on a streaming platform you won't need to do anything particular yourself, you can get away with fetching the data and posting an item with the URL of the video. InputStream.Adaptive configuration might be needed, especially if the videos need DRM.

You can get a lot done with the requests module, depending on the data you're processing. It's fully supported in Kodi, cookie and sessions included. In short, it's really simple, you:

- get the information you need off the internet (title/URL could suffice for a start);

- you generate items that Kodi will treat as video sources (see xbmcplugin.addDirectoryItem() and xbmcgui.ListItem());

You could also read the sources of plugins such as AsciiDisco's Netflix or Sandmann79's Amazon/AmazonVOD addons.

You can read more in this thread https://forum.kodi.tv/showthread.php?tid=348328

Final Thoughts

Writing a Video Add-on is actually pretty simple once you get the basic structure correct. You can scrape most online sources with Regex, or host your own videos on the web. You can also play youtube clips or vevo videos using some additional easy to use modules.

If you have any questions about this tutorial, feel free to discuss it on our forums here: http://forum.kodi.tv/showthread.php?tid=248774

Extra info

Just a reminder... IMPORTANT!!!!!!! Do not mix tabs and spaces in python