Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # IMPORTANT NOTE: AS WITH ALL PYTHON CODING, PROPER INDENTATION IS NECESSARY TO PREVENT ERRORS.
- # PROGRAMS LIKE NOTEPAD++ DO NOT ALWAYS LINE UP PROPERLY OR CATCH THESE INDENTION ERRORS. TO
- # PREVENT THESE AND OTHER PYTHON ERRORS, BEFORE RUNNING THE PROGRAM IN PLEX OR AFTER MAKING CHANGES
- # TO THE FILE, I OPEN IT FIRST IN A LOCAL VERSION OF PYTHON I HAVE LOADED AND CHOOSE
- # RUN > CHECK MODULE TO FIND ANY POSSIBLE PROBLEMS.
- # These are python variables you set up for use later in this file
- # The naming and values are based on the where and how you choose to use them in your code
- # For the most part, you are defining variables you will use in the PlayVideo function
- # Often video files are stored in a video directory on the site, but the base file could just be htpp://www.anywebsite.com/
- BASE_URL = 'http://video.anywebsite.com/'
- # It is best practice to use regex when possible and avoid importing any Python modules, so below is a regex statement I use
- # later in my PlayVideo function to find the video info xml address within the page that allows me to easily pull the
- # web pages corresponding video file location
- RE_XML_URL = Regex("/xml/video(.+?)',")
- # The variable below is basic regex to pull a video from an html page. I show its use in a optional version of the PlayVideo function
- # RE_VIDEO_URL = Regex('videofile:"(?P<video_url>[^"]+)"')
- # IMPORTANT NOTE: THE VALUE OF 'URL' THAT IS PASSED TO THE DIFFERENT FUNCTIONS IN THIS PROGRAM IS DETERMINED EITHER
- # WITHIN THE PROGRAMMING OF THE INDIVIDUAL CHANNEL PLUGIN THAT USES THIS URL SERVICE OR BY THE END USER CHOOSING THE PLEXIT BUTTON
- ########################################################################################################
- # BELOW IS AN OPTIONAL CODE FOR CONVERTING HTML VIDEO PAGES TO THEIR CORRESPONDING VIDEO INFO XML PAGES.
- # IF YOU CAN FIND REFERENCE TO THESE XML VIDEO INFO FILES ON THE VIDEO WEBPAGES, THESE XML PAGES CAN BE
- # USED FOR EASY RETRIEVAL OF METADATA AND VIDEO FILES USING XML.ElementFromURL.
- # We use string.replace() to create a new url that adds /xml/video-folder/ to middle and changes the extension to .xml.
- ########################################################################################################
- XML_URL = url.replace('http://www.anywebsite.com/','http://www.anywebsite.com/xml/videos-page/').replace('.html','.xml')
- ####################################################################################################
- # This pulls the metadata that is used for Plexit, suggested videos (to friends), the pre-play screen on iOS, Roku, Android and Plex/Web,
- # as well as if you get the "info" or "details" within the OSX/Windows/Linux desktop client.
- # Afer you pull the data you should save it to preset variables. These basic variables are title, summary, and thumb.
- # but some also include duration, and originally_available_at, content_rating, show, tags and index
- def MetadataObjectForURL(url):
- # Here you are using the ElementFromURL() API to parse or pull up all the data from the webpage.
- # See the Framework documentation API reference for all the choices for parsing data
- page = HTML.ElementFromURL(url)
- # Extract the data available on the page using xpath commands.
- # Think about what will access the metadata from this URL service to determine what info you want to extract here
- # Below is a basic example that pulls the the title, description and thumb from the head of a html document that makes a request of this URL Service
- title = page.xpath("//head//meta[@property='og:title']")[0].get('content')
- description = page.xpath("//head//meta[@property='og:description']")[0].get('content')
- thumb = page.xpath("//head//meta[@property='og:image']")[0].get('url')
- # This command returns the metadata values you extracted as a video clip object.
- # See the Framework documentation API reference for all the choices of objects to return metadata
- return VideoClipObject(
- title = title,
- summary = description,
- thumb = thumb,
- )
- ####################################################################################################
- # Here you will define the different types of videos available on this website and the values for their quality
- # You will need to search the source of the web pages that play a video to determine the type and location of videos offered thru the site
- # You can see if the name and location is available through an embed link, but you may have to look into the subpages for a web page
- # like javascript or style sheets to find this information. You will also need this information later when
- # writing the code for the PlayVideo function that pulls these specific video files from the webpage
- def MediaObjectsForURL(url):
- return [
- # First you are calling a MediaObject() for each type of video the website offers using the MediaObject API command
- # Most separate these types of videos by the resolution, for example a site may offer a high and low quality option for each video on its site
- # or they may offer an .flv format and an .mp4 format version of the video file. You can choose to only offer one type of video file
- # or give the user the option of choosing the type of video file they want to use if there are several different types and qualities.
- MediaObject(
- # Then within each MediaObject you define the values for that particular type of video
- # The options most used are video_codec, audio_codec, parts, container, video_resolution, audio_channels, and bitrate
- # See the Framework documentation API reference for a lists all possible attributes for MediaObject()
- # Audio Codecs are AAC and .MP3; Video Codecs are .H264; Container File Types are .MP4, .MKV, .MOV, and .AVI¶
- # And for audio channels stereo equals 2
- # I have found the best way to determine these attributes is to use VLC player and open the network stream URL of a few of the
- # videos available on the site. And then use the tools to view the media information esp. codec info
- video_codec = VideoCodec.H264,
- audio_codec = AudioCodec.MP3,
- video_resolution = '720',
- audio_channels = 2,
- container = 'f4v',
- # This section of the code allows you to peice together videos that come in 2 or more parts it also uses a callback function
- # that calls the PlayVideo function below. This done to separate the playing of the video from the call for the media object
- # that way it will only play the video if the user selects that particular video.
- # The code below is the basic format that all URL Serivces use and then they define PlayVideo if the video only has one part, it only needs one PartObject
- # Note that we are also sending a fmt variable to tell the PlayVideo function whether this is a high or low quality video. This is only
- # necessary when you have more than one choice for the video files available.
- parts = [PartObject(key=Callback(PlayVideo, url = url, fmt='hi')]
- )
- # Below we are doing the same as above, and defining a second MediaObject that is a low quality version of the video file that is available.
- # The fmt variable is sent to the PlayVideo function to help you determine which of the available video types to send back to the Media Object.
- MediaObject(
- video_codec = VideoCodec.H264,
- audio_codec = AudioCodec.MP3,
- video_resolution = '420',
- audio_channels = 2,
- container = 'f4v',
- parts = [PartObject(key=Callback(PlayVideo, url = url, fmt='lo')]
- )
- ]
- ####################################################################################################
- # Here we are defining the PlayVideo function we called in the callback function above. This function defines the pattern for
- # the location and naming scheme of the video so we can play the video file directly. You use HTML request, regular expressions,
- # and predefined variables to create the path or http address of the video associated with the html or xml page that was sent
- # to this service through the "URL" value. The programming here will vary greatly based on the location of the
- # video file related to your video pages. This is where you will be doing the majority to the programming.
- # It is best to refer to other services already created for examples of how to pull the video file.
- # First we define the function taking the the variables for the url entered into the service and the
- # fmt variable we established above in MediaObjects
- def PlayVideo(url, fmt):
- # Below I have included a basic example of how to program the PlayVideo function for pulling the video location on the web page
- # whose URL was sent to the service and only has ONE video on the page. The code pulls the raw data from the web page
- # using the URL and then uses a simple page search that returns an f4v video file url that is located in each html video page.
- # It uses both of the variables we established at the top of the service.
- # EXAMPLE:
- # page = HTTP.Request(url).content
- # video = RE_VIDEO_URL.search(page).group('video_url') + ".f4v"
- # video = BASE_URL + video
- # The example I chose to use for this function uses the optional xml video information file to pull the high and low
- # quality version of a video from the url sent to this URL service.
- # It basically pulls the content from the URL, looks through the page to find a mention of the regex value I defined as a
- # global variable at the beginning of this document. Because the line of data I was using contained a parenthesis right before
- # the address, I had to get a little creative in pulling it and then replacing the ending single quote to properly pull
- # the xml address out of the page. The function then opens that xml video info page and uses xpath commands to extract the
- # video URL and returns those values in the form of a high and low quality video. Then it uses the fmt variable to determine
- # which of these videoss should be the value of video.
- content = HTTP.Request(url).content
- xmlurl = RE_XML_URL.search(content).group(0)
- xmlurl = xmlurl.replace("'", '')
- xmlurl = base_url + xmlurl
- xml = XML.ElementFromURL(xmlurl)
- if xml:
- # Here we are extracting the video file addresses from the xml video file metadata
- videoHi = xml.xpath('//video/videoHi//text()')[0]
- videoLo = xml.xpath('//video/videoLo')[0].text
- videoHi = videoHi.replace('.f4v', '.mp4')
- videoLo = videoLo.replace('.f4v', '.mp4')
- if fmt == 'hi':
- video = videoHi
- else:
- video = videoLo
- # We then return the address or value of the video. This video URL is then sent back to the MediObject above with return Redirect(video)
- # The Redirect() is a Plex Framework function that essentially tells the Client to look at this new URL for the actual media file.
- return Redirect(video)
- ####################################################################################################
- def TestURLs():
- # This is for testing the URL, so you are making sure the URL service is working.
- # YOU DO NOT NEED THIS IF YOU PUT A TEST URL IN YOUR SERVICEINFO.PLIST FILE. THIS IS AN ALTERNATIVE WAY IF YOU THINK THE VIDEO PAGES WILL CHANGE
- # ALOT AND YOU DO NOT THINK YOU CAN DETERMINE A SPECIFIC URL THAT WILL NOT CHANGE
- # This coding below is a basic example that allows you to make the test url more dynamic so the service will not fail just because the
- # test url no longer exists. Enter the main domain for urls that will be sent to this service in place of anydomain.com
- test_urls = []
- page = HTML.ElementFromURL('http://www.anydomain.com/')
- # here in this link command you need to edit this xpath to reflect the id or class is used to represent
- # a video player container on pages for this url service and enter the correct domain name
- for link in page.xpath("//a/span[@class='vid']/.."):
- if len(test_urls) < 3:
- url = link.get('href')
- url = "http://www.anydomain.com" + url
- if url not in test_urls:
- test_urls.append(url)
- else:
- break
- return test_urls
- ####################################################################
- # TESTING YOUR URL SERVICE #
- ####################################################################
- # To test your url service, the best way is to use 'http://localhost:32400/system/services/url/lookup?url=' followed by an html page that contains
- # a video. You must first use a URL encoder like 'http://meyerweb.com/eric/tools/dencoder/' to give the page name the proper format. Paste this
- # into the address bar of your browser. This will result in a page that shows you the metadata and a key with video info. If this info does not
- # come up, check the system log (come.plexapp.system.log) for errors.
- # To see the actual video file url and any errors with playing the video, you will then cut the key from the resulting metadata page you pulled
- # up above and add 'http://localhost:32400' to the beginning of it and paste it into the address bar of your browser. The resulting page will show you
- # the video file location and any errors in locating it.
Advertisement
Add Comment
Please, Sign In to add comment