Sie sind auf Seite 1von 5

import org.serviio.library.metadata.

*
import org.serviio.library.online.*
/********************************************************************
* USTREAM plugin for Serviio
*
* Logic by forum member: piscui - http://piscui.webear.net/ustream.php
*
* @author X S Inattar
*
* Must be installed as a Video WebResource
* Sample URLs:
* http://www.ustream.tv/nasahdtv
* http://www.ustream.tv/opensea
* http://www.ustream.tv/discovery/live/sports?order=most-views-all
* http://www.ustream.tv/discovery/live/sports?order=most-views-all&page=2
* http://www.ustream.tv/discovery/live/entertainment
* http://www.ustream.tv/new#new/spotlight/underthesea
*
* Version:
* V1: July 28, 2012 - Initial Release
* V2: July 29, 2012 - Pages and Categories Support
* V3: August 06, 2012 - Fix for new# links for new USTREAM in IE
* V4: August 25, 2012 - USTREAM made some changes to the stream urls
* V5: August 27, 2012 - Added support for new categories. (provided by jhb50
)
*
********************************************************************/
class USTREAM extends WebResourceUrlExtractor {

final VALID_FEED_URL = '^(?:http://)?(?:www\\.)?ustream\\.tv/(.*?)(?:/)?$'
final BASE_URL = 'http://www.ustream.tv'
final CHANNEL_ID_EXTRACTOR = 'cid=(.*?)&'
final THUMBNAIL_EXTRACTOR_1 = '<img class="image" alt="(.*?)" width="66" hei
ght="66" src="(.*)" rel="(.*)" />'
final THUMBNAIL_EXTRACTOR_2 = '<img src="(.*)" alt="(.*?)" title="(.*?)" />'
final TITLE_EXTRACTOR = '<meta property="og:title" content="(.*)" />'
final PLAYPATH_EXTRACTOR_1 = "cdnStreamName\\W\\W\\W(.+?)\\x00"
final PLAYPATH_EXTRACTOR_2 = "streamName\\W\\W\\W(.+?)\\x00"
final TCURL_EXTRACTOR_1 = "cdnStreamUrl\\W\\W\\S(.*?)\\x00"
final TCURL_EXTRACTOR_2 = "cdnUrl\\W\\W\\S(.*?)\\x00"
final TCURL_EXTRACTOR_3 = "fmsUrl\\W\\W\\S(.*?)\\x00"
final SWF_URL = 'http://static-cdn1.ustream.tv/swf/live/viewer.rsl:96.swf'
final AMF_URL = 'http://cgw.ustream.tv/Viewer/getStream/1/<!--ChannelID-->.a
mf';
final CHANNEL_ITEMS_EXTRACTOR = '<a href="(.*?)" class="shadowbox">\n\t\t\t\
t\t<strong class="livebadgeLeft">LIVE</strong>\n\t\t\t\t\t\t\t<span class="img">
\n\t\t\t\t<img src=".*?" alt="(.*?)" width="192" height="108".*?/>'
String getExtractorName() {
return 'ustream.tv'
}

boolean extractorMatches(URL feedUrl) {
return feedUrl ==~ VALID_FEED_URL
}

WebResourceContainer extractItems(URL resourceUrl, int maxItemsToRetrieve) {

List<WebResourceItem> items = []

def ustreamURL = resourceUrl.toString()
ustreamURL = ustreamURL.replaceFirst("/new#\\./", "/")
ustreamURL = ustreamURL.replaceFirst("/new#", "/")
def channelCodeMatcher = ustreamURL =~ VALID_FEED_URL
if (channelCodeMatcher.count <= 0 ) {
return null
}

def channelText = new URL(ustreamURL).getText()
channelText = channelText.replaceAll('&amp;', '&')
def channelTitle = channelCodeMatcher
def channelTitleMatcher = channelText =~ TITLE_EXTRACTOR
if (channelTitleMatcher.count > 0) {
channelTitle = channelTitleMatcher[0][1]
}
println channelTitle

// NEW CODE FOR NEW CATEGORIES *********************************
*********
if (ustreamURL.contains('/new/')) {
def jsonMatcher = channelText =~ '(?s)<div class="active">.*
?<a href="/' + channelCodeMatcher[0][1] + '".*?data-listUrl="(.*?)".*?class="sta
te active">(.*?)<.*?</a>'
def catTitle = "UStream " + jsonMatcher[0][2].trim()
def jsonUrl = BASE_URL + jsonMatcher[0][1]
def jsonText = new URL(jsonUrl).getText()
jsonText = jsonText.replace("\\t", "")
jsonText = jsonText.replace("\\n", "")
jsonText = jsonText.replace("\\", "")
//# get ID#, thumbnail, title
def allLinks = jsonText =~ '(?s)<li.data-mediaType.*?dat
a-mediaId="(.*?)".*?<div class="img">.*?<img src="(.*?)".*?<span class="badge ba
dge.*?">(.*?)<.*?<div class="titleOwner">.*?<h3>(.*?)<.*?<a href="(.*?)".*?</li>
'
int itemsAdded = 0
for( int i = 0; i < allLinks.size() && (maxItemsToRetrie
ve == -1 || itemsAdded < maxItemsToRetrieve); i++ ) {
if (allLinks[i][3] == "Live"){
items << new WebResourceItem(title: allL
inks[i][4], additionalInfo: [channelURL: BASE_URL + allLinks[i][5]])
itemsAdded++
println "Live Item #" + itemsAdded + " "
+ allLinks[i][4] + " (" + BASE_URL + allLinks[i][5] + ")"
log ("Live Item #" + itemsAdded + " " +
allLinks[i][4] + " (" + BASE_URL + allLinks[i][5] + ")")
}
}
return new WebResourceContainer(title: catTitle, items:
items)
}
// END OF NEW CODE *****************************************************
*

else if (ustreamURL.contains('/discovery/live/')) {

def channel_items_matcher = channelText =~ CHANNEL_ITEMS_EXTRACTOR
if (channel_items_matcher.count <= 0) {
return null
}

def loopRun = (maxItemsToRetrieve != -1 && maxItemsToRetrieve <= cha
nnel_items_matcher.count) ? maxItemsToRetrieve : channel_items_matcher.count
int count = 0
for (i in 0..<loopRun) {
items << new WebResourceItem(title: channel_items_matcher[i][2],
additionalInfo: [channelURL: BASE_URL + channel_items_matcher[i][1]] )
// ADDED ITEM LOGGING **************************
count++
println "Live Item #" + count + " " + channel_it
ems_matcher[i][2] + " (" + BASE_URL + channel_items_matcher[i][1] + ")"
log ("Live Item #" + count + " " + channel_items
_matcher[i][2] + " (" + BASE_URL + channel_items_matcher[i][1] + ")")
//END ADD LOGGING ******************************
*
}
}
else {
items << new WebResourceItem(title: channelTitle, additionalInfo: [c
hannelURL: ustreamURL] )
}

return new WebResourceContainer(title: channelTitle, items: items)
}
ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality reques
tedQuality) {

println item.additionalInfo.channelURL
def channelText = new URL(item.additionalInfo.channelURL).getText()

def channelIdMatcher = channelText =~ CHANNEL_ID_EXTRACTOR
if (channelIdMatcher.count <= 0) {
return null
}
def channelId = channelIdMatcher[0][1]
println channelId

def channelThumb = null
def channelThumbMatcher_1 = channelText =~ THUMBNAIL_EXTRACTOR_1
if (channelThumbMatcher_1.count > 0) {
channelThumb = channelThumbMatcher_1[0][2]
}
else {
def channelThumbMatcher_2 = channelText =~ THUMBNAIL_EXTRACTOR_2
if (channelThumbMatcher_2.count > 0) {
channelThumb = channelThumbMatcher_2[0][1]
}
}
println channelThumb

def dataurl = AMF_URL
dataurl = dataurl.replaceAll("<!--.*?-->", channelId)
println dataurl
def data = new URL(dataurl).getText()

def cdnStreamUrlFound = 0
def playpath = ''
def playpath_matcher_1 = data =~ PLAYPATH_EXTRACTOR_1
if (playpath_matcher_1.count > 0) {
cdnStreamUrlFound = 1
playpath = playpath_matcher_1[0][1]
}
else {
def playpath_matcher_2 = data =~ PLAYPATH_EXTRACTOR_2
if (playpath_matcher_2.count <= 0) {
return null
}
playpath = playpath_matcher_2[0][1]
}

def rtmpurl = ''
if (cdnStreamUrlFound == 1)
{
def tcurl_matcher_1 = data =~ TCURL_EXTRACTOR_1
if (tcurl_matcher_1.count > 0) {
rtmpurl = tcurl_matcher_1[0][1]
}
else
{
return null
}
}
else
{
def tcurl_matcher_2 = data =~ TCURL_EXTRACTOR_2
if (tcurl_matcher_2.count > 0) {
rtmpurl = tcurl_matcher_2[0][1]
}
else {
def tcurl_matcher_3 = data =~ TCURL_EXTRACTOR_3
if (tcurl_matcher_3.count > 0) {
rtmpurl = tcurl_matcher_3[0][1]
rtmpurl = rtmpurl.replaceAll('/ustreamVideo', ':1935/ustream
Video')
rtmpurl = rtmpurl + '/'
}
else {
return null
}
}
}

def contentUrl = rtmpurl + ' playpath=' + playpath + ' swfUrl=' + SWF_UR
L + ' swfVfy=1 live=1'

def cacheKey = 'USTREAM_' + channelId

return new ContentURLContainer(contentUrl: contentUrl, thumbnailUrl: cha
nnelThumb, expiresImmediately: true, cacheKey : cacheKey, live: true)
}

static void main(args) {

USTREAM extractor = new USTREAM()

//WebResourceContainer container = extractor.extractItems( new URL("http
://www.ustream.tv/new#./creativelive"), 5)
WebResourceContainer container = extractor.extractItems( new URL("http:/
/www.ustream.tv/new#new/spotlight/underthesea"), 5)
//WebResourceContainer container = extractor.extractItems( new U
RL("http://www.ustream.tv/discovery/live/entertainment"), 5)
//WebResourceContainer container = extractor.extractItems( new URL("http
://www.ustream.tv/new#channel/live-iss-stream"), 5)
container.getItems().each {
ContentURLContainer result = extractor.extractUrl(it, PreferredQuali
ty.MEDIUM)
println result
}

/**
container = extractor.extractItems( new URL("http://www.ustream.tv/disco
very/live/entertainment"), 20)
container.getItems().each {
ContentURLContainer result = extractor.extractUrl(it, PreferredQuali
ty.MEDIUM)
println result
}
/**/
}
}

Das könnte Ihnen auch gefallen