Skip to content

Commit

Permalink
v1.2.0: hls support & patched submenus and navigation errors
Browse files Browse the repository at this point in the history
  • Loading branch information
idleloop-github committed Sep 20, 2017
1 parent 514b51e commit 303047e
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 117 deletions.
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
# plugin.video.earthcam plugin for Kodi / XBMC
# plugin.video.earthcam add-on for Kodi / XBMC

This plugin version will show you more webcams than any other version on internet!
This add-on version will show you more webcams than any other version on internet!

EarthCam.com is the premiere network of scenic webcams and offers a complete database of interesting places and views from around the world. EarthCam.com is the worlds favorite webcam network and the EarthCam Network cameras have been seen on top news shows, including CNN Headline News.

### Installation

* [download released zip](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.1.0/plugin.video.earthcam-1.1.0.zip)
* [download released zip](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.2.0/plugin.video.earthcam-1.2.0.zip)
* Kodi/XBMC: System / Add-ons / Install from zip file /
* or Kodi 17: Add-ons / Download / ".." / Install from zip file /
* select [earthcam's zip file](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.1.0/plugin.video.earthcam-1.1.0.zip)
* select [earthcam's zip file](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.2.0/plugin.video.earthcam-1.2.0.zip)
* Note that Kodi will complain about installing from "Unknown sources": in this case, activate this option, and repeat the installation steps.

From version 1.2.0 on, this add-on can play [HLS streams](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), and this mode is more stable than [RTMP](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol).
Please follow **Enable HLS playing** instructions to try it.

### Note for Kodi 17 (Krypton)

* Now, it is necessary to activate the "RTMP input stream": Add-ons / My Add-ons / VideoPlayer InputStream / RTMP Input / Enable

If after enabling the "RTMP input stream" no camera is shown (please, note that some links may not be active: try some USA cams first), the RTMP library may not be functioning - in this case you can **try** these **advanced steps**:
If after enabling the "RTMP input stream" no camera is shown (please, note that some links may not be active: try some USA cams first), the RTMP library may not be functioning - in this case you can try **Install inputstream.rtmp add-on** instructions,
**OR** try **Enable HLS playing** instructions.

Steps to install an **inputstream.rtmp** plugin from [this repo](https://github.com/kodinerds/binary-repo) in order to activate [rtmp videos](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol) for Kodi. That repo supports RPi2, Odroid-C2 (deprecated), Windows and Mac OS X.
##### Install **inputstream.rtmp** add-on
Steps to install an **inputstream.rtmp** add-on from [kodinerds repo](https://github.com/kodinerds/binary-repo) in order to activate [rtmp videos](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol) for Kodi. That repo supports RPi2 (compatible with RPi3), Odroid-C2 (deprecated), Windows and Mac OS X.

* Download the appropriate *repository.kodinerds_X.zip* zip file for your platform [from here](https://github.com/kodinerds/binary-repo).
* Install this repository on Kodi: Add-ons / Download / .. / Install from zip file / *and select kodiners' zip file*. Previously, "Unknown Sources" must have been activated on: Settings / System / Add-ons / Unknown sources
* Install *inputstream.rtmp* add-on: Add-ons / Download / .. / Install from repository / kodinerds / VideoPlayer InputStream / RTMP Input
* and then, install *plugin.video.earthcam*: Add-ons / Download / .. / Install from zip file / select [earthcam's zip file](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.1.0/plugin.video.earthcam-1.1.0.zip).
* and then, install *plugin.video.earthcam*: Add-ons / Download / .. / Install from zip file / select [earthcam's zip file](https://github.com/idleloop-github/xbmc-earthcam/releases/download/v1.2.0/plugin.video.earthcam-1.2.0.zip).

##### Enable HLS playing
From version 1.2.0 on, this add-on can play [HLS streams](https://en.wikipedia.org/wiki/HTTP_Live_Streaming).
In order to activate this functionality you have to both activate it in this add-on's configuration,
and also install (if necessary) and enable the add-on **InputStream Adaptative** (or another add-on capable of playing HLS - for example [awaiters1 releases](https://github.com/awaters1/inputstream.hls/releases)).

* Configure earthcam add-on: Add-ons / Video add-ons / Earthcam / right click / Settings / Enable HLS instead of RMP : activate
* activate "InputStream Adaptative": Add-ons / My Add-ons / VideoPlayer InputStream / InputStream Adaptative / Enable
* Also, configure it to be able to open HD streams: Add-ons / My Add-ons / VideoPlayer InputStream / InputStream Adaptative / Configure / Max. Resolution general decoder: Max [Ok]

* Now check that you can open some cams. If that is not the case, simply deactivate HLS again: Add-ons / Video add-ons / Earthcam / right click / Settings / Enable HLS instead of RMP : deactivate

### Changes

Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.earthcam"
name="EarthCam"
version="1.1.0"
version="1.2.0"
provider-name="idleloop, (forked from xbmchub.com)">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v1.2.0
(2017, Sept)
added HLS support: enable it in add-on's configuration if no cam is shown.
patched some errors getting submenus and navigating

v1.1.0
(2017, Sept)
patched for new earthcam web site
Expand Down
133 changes: 77 additions & 56 deletions channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
DEBUG = False
if (config.get_setting("debug") == 'true'):
DEBUG=True
HLS = True
if (config.get_setting("hls") == 'false'):
HLS=False
URL = 'https://www.earthcam.com/'
USA_PREFIX_PATCH = 'search/adv_search.php?restrict=1&country[]=United%20States'
WORLDWIDE_PREFIX_PATCH = 'search/adv_search.php?restrict=1&country[]='
Expand All @@ -41,11 +44,11 @@ def mainlist(item):
itemlist.append( Item(action="usa", title="USA" , url=URL + USA_PREFIX_PATCH + EARTHCAM_NAVIGATION_LINK_END ) )
return itemlist

def _get_tree(url, just_get = False):
def _get_tree(url, just_get_content = False):

html = scrapertools.cache_page(url)

if just_get == True: return html
if just_get_content == True: return html

try:
tree = BeautifulSoup(html, convertEntities='html')
Expand All @@ -58,13 +61,13 @@ def _get_tree(url, just_get = False):
def worldwide(item):
logger.info("[channel.py] worldwide")
itemlist = []
bStopNavigation = False
#bStopNavigation = False

if (DEBUG): logger.info("url=" + item.url)

tree = _get_tree( item.url )

divs = tree.findAll('div', {'class': re.compile(r'.*col-xs-.+result_column_[AB].*')})
divs = tree.findAll('div', {'class': re.compile(r'.*col\-xs\-.+result_column_[AB].*')})

(title, thumbnail, url, location, plot) = ('', '', '', '', '')

Expand All @@ -79,8 +82,9 @@ def worldwide(item):
url = div.find('a', {'class': 'camTitle'})['href']
# discard (almost all) the external links:
if not re.search( r'(//www.earthcam.com/|//(www.)?youtube.com/)', url ):
bStopNavigation = True
break
#bStopNavigation = True
#break
pass
title = div.find('a', {'class': 'camTitle'}).span.string.replace('EarthCam: ', '')
location = div.find('div', {'class': 'cam_location'}).string
plot = div.find('div', {'class': 'cam_description'}).string
Expand All @@ -96,16 +100,16 @@ def worldwide(item):
links = tree.find('div', {'id': 'pagination_bottom'}).findAll('a')
logger.info(str(links))
# next page
if bStopNavigation == False or (bStopNavigation == True and len(itemlist)>0):
link = links[-1]
if re.search(r'^Next', link.text):
url = link['href']
# Unfortunately, until BeautifulSoup 4.2.1 there're problems with double ampersands, so:
url = URL + USA_PREFIX_PATCH + url[1:]
logger.info(url)
item=Item(action="worldwide", title='Next >>' , url=url, thumbnail='',
fanart='', plot='' )
itemlist.append( item )
#if bStopNavigation == False or (bStopNavigation == True and len(itemlist)>0):
link = links[-1]
if re.search(r'^Next', link.text):
url = link['href']
# Unfortunately, until BeautifulSoup 4.2.1 there're problems with double ampersands, so:
url = URL + USA_PREFIX_PATCH + url[1:]
logger.info(url)
item=Item(action="worldwide", title='Next >>' , url=url, thumbnail='',
fanart='', plot='' )
itemlist.append( item )
except:
pass

Expand All @@ -114,7 +118,7 @@ def worldwide(item):
def usa(item):
logger.info("[channel.py] usa")
itemlist = []
bStopNavigation = False
#bStopNavigation = False

if (DEBUG): logger.info("url=" + item.url)

Expand All @@ -135,8 +139,9 @@ def usa(item):
url = div.find('a', {'class': 'camTitle'})['href']
# discard (almost all) the external links:
if not re.search( r'(//www.earthcam.com/|//(www.)?youtube.com/)', url ):
bStopNavigation = True
break
#bStopNavigation = True
#break
pass
title = div.find('a', {'class': 'camTitle'}).span.string.replace('EarthCam: ', '')
location = div.find('div', {'class': 'cam_location'}).string
plot = div.find('div', {'class': 'cam_description'}).string
Expand All @@ -152,16 +157,16 @@ def usa(item):
links = tree.find('div', {'id': 'pagination_bottom'}).findAll('a')
logger.info(str(links))
# next page
if bStopNavigation == False or (bStopNavigation == True and len(itemlist)>0):
link = links[-1]
if re.search(r'^Next', link.text):
url = link['href']
# Unfortunately, until BeautifulSoup 4.2.1 there're problems with double ampersands, so:
url = URL + USA_PREFIX_PATCH + url[1:]
logger.info(url)
item=Item(action="usa", title='Next >>' , url=url, thumbnail='',
fanart='', plot='' )
itemlist.append( item )
#if bStopNavigation == False or (bStopNavigation == True and len(itemlist)>0):
link = links[-1]
if re.search(r'^Next', link.text):
url = link['href']
# Unfortunately, until BeautifulSoup 4.2.1 there're problems with double ampersands, so:
url = URL + USA_PREFIX_PATCH + url[1:]
logger.info(url)
item=Item(action="usa", title='Next >>' , url=url, thumbnail='',
fanart='', plot='' )
itemlist.append( item )
except:
pass

Expand All @@ -175,7 +180,7 @@ def cams(item):

#tree = _get_tree( item.url )
# Ops... some earthcam's wrong html code here mangles BeautifulSoup tree :-(
html = _get_tree( item.url, just_get=True )
html = _get_tree( item.url, just_get_content=True )
html = html.replace(' ; id=', ' id=')
try:
tree = BeautifulSoup(html, convertEntities='html')
Expand Down Expand Up @@ -253,7 +258,7 @@ def previous_play(item, just_check=False):

#http://www.earthcam.com/usa/newyork/timessquare/?cam=tsstreet
#if "?cam=" in item.url:
video_url=""
#video_url=""
#try:
# # Extract cam_id
# cam_id = item.url.split("?")[1].split("=")[1]
Expand Down Expand Up @@ -283,44 +288,54 @@ def previous_play(item, just_check=False):
if (DEBUG): logger.info("liveon="+liveon)
if liveon!="disabled":
###video_url = cam_data[cam_id]["worldtour_path"]
video_url
video_url = ''
try:
if "worldtour_path" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4|\.jpg|\.png)$', cam_data[cam_id]["worldtour_path"] ):
video_url = cam_data[cam_id]["worldtour_path"]
elif "livestreamingpath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["livestreamingpath"] ):
video_url = cam_data[cam_id]["streamingdomain"] + cam_data[cam_id]["livestreamingpath"]
elif "timelapsepath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["timelapsepath"] ):
video_url = cam_data[cam_id]["timelapsedomain"] + cam_data[cam_id]["timelapsepath"]
elif "archivepath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["archivepath"] ):
video_url = cam_data[cam_id]["archivedomain"] + cam_data[cam_id]["archivepath"]
if (HLS):
if "html5_streamingdomain" in cam_data[cam_id]:
video_url = 'http:' + cam_data[cam_id]["html5_streamingdomain"]
if "html5_streampath" in cam_data[cam_id] and re.search( r'(\.m3u8)$', cam_data[cam_id]["html5_streampath"] ):
video_url = video_url + cam_data[cam_id]["html5_streampath"]
if (DEBUG): logger.info("html5_stream="+video_url)
else:
continue
else:
continue
if "worldtour_path" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4|\.jpg|\.png)$', cam_data[cam_id]["worldtour_path"] ):
video_url = cam_data[cam_id]["worldtour_path"]
elif "livestreamingpath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["livestreamingpath"] ):
video_url = cam_data[cam_id]["streamingdomain"] + cam_data[cam_id]["livestreamingpath"]
elif "timelapsepath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["timelapsepath"] ):
video_url = cam_data[cam_id]["timelapsedomain"] + cam_data[cam_id]["timelapsepath"]
elif "archivepath" in cam_data[cam_id] and re.search( r'(\.flv|\.mp4)$', cam_data[cam_id]["archivepath"] ):
video_url = cam_data[cam_id]["archivedomain"] + cam_data[cam_id]["archivepath"]
else:
continue
#video_url=re.sub(r'(?<!:)//','/',video_url)
url = calculate_url(video_url)
item=Item(action="play", url=url,
folder=False)
try:
item.title=cam_data[cam_id]["title"]
title=cam_data[cam_id]["title"]
except Exception, e:
item.title=str(cam_id)
title=str(cam_id)
try:
item.fanart=cam_data[cam_id]["offlineimage"]
fanart=cam_data[cam_id]["offlineimage"]
except Exception, e:
logger.info("[channel.py] [play] ERROR: no fanart")
fanart=''
if (DEBUG): logger.info("[channel.py] [play] ERROR: no fanart")
try:
item.thumbnail=cam_data[cam_id]["thumbimage"]
thumbnail=cam_data[cam_id]["thumbimage"]
except Exception, e:
logger.info("[channel.py] [play] ERROR: no thumbnail")
thumbnail=''
if (DEBUG): logger.info("[channel.py] [play] ERROR: no thumbnail")
try:
item.plot = re.sub(r'</?span[^>]*>', '',
plot = re.sub(r'</?span[^>]*>', '',
cam_data[cam_id]["description"].replace('+', ' '),
flags=re.IGNORECASE )
item.plot = re.sub(r'<[^>]+>', "\n", item.plot)
plot = re.sub(r'<[^>]+>', "\n", plot)
except Exception, e:
logger.info("[channel.py] [play] ERROR: no plot")
itemlist.append( item )
plot=''
if (DEBUG): logger.info("[channel.py] [play] ERROR: no plot")
itemlist.append( Item(action="play", url=url, thumbnail=thumbnail, title=title, fanart=fanart, plot=plot) )
except Exception, e:
logger.info("[channel.py] [play] ERROR:"+url)
if (DEBUG): logger.info("[channel.py] [play] ERROR:"+url)

return itemlist

Expand All @@ -329,7 +344,7 @@ def play(item):
if re.search( r'//(www.)?youtube.com/', item.url ):
video_id = re.sub('.+?=', '', item.url)
xbmc.executebuiltin('PlayMedia(plugin://plugin.video.youtube/play/?video_id=' + video_id + ')')
elif re.search( r'(\.flv|\.mp4|\.jpg|\.png)$', item.url ) or item.url.startswith("rtmp"):
elif re.search( r'(\.flv|\.mp4|\.jpg|\.png|\.m3u8)$', item.url ) or item.url.startswith("rtmp"):
itemlist.append( item )
else: # for backward compatitbility with v1.0.7 favorites
itemlist=previous_play( item )
Expand All @@ -344,6 +359,12 @@ def calculate_url(video_url):
# rtmp://video2.earthcam.com/ app=fecnetwork swfUrl=http://www.earthcam.com/swf/cam_player_v2/ecnPlayer.swf playpath=fridaysHD1.flv live=true timeout=180
if video_url.lower().endswith(".jpg") or video_url.lower().endswith(".png"):
url = video_url
elif video_url.lower().endswith(".m3u8"):
try:
m3u8_content = _get_tree(video_url, just_get_content = True)
url = video_url.replace( 'playlist', re.search(r'^([^#].+)\.m3u8$', m3u8_content, re.MULTILINE).group(1) )
except:
url=''
elif video_url.lower().startswith("http://") or video_url.lower().startswith("https://") or video_url.lower().endswith(".mp4"):
url = video_url
else:
Expand All @@ -353,7 +374,7 @@ def calculate_url(video_url):
playpath = scrapertools.get_match(video_url,"rtmp\://[^\/]+/[a-z]+/(.+\.flv)")
swfurl = "http://www.earthcam.com/swf/cam_player_v2/ecnPlayer.swf"
url=rtmp_url + " app=" + app + " swfUrl=" + swfurl + " playpath=" + playpath + " live=true timeout=180"
if (DEBUG): logger.info("url="+url)
if (DEBUG): logger.info("calculated_url="+url)
return url


Expand Down
Loading

0 comments on commit 303047e

Please sign in to comment.