import groovy.json.JsonSlurper import org.serviio.library.metadata.* import org.serviio.library.online.* import org.serviio.util.* /** * WebResource extractor plugin for tunein.com. * * @author Petr Nejedly * */ class TuneIn extends WebResourceUrlExtractor { final VALID_FEED_URL = '^(?:https?://)?(?:www\\.)?tunein\\.com/(radio/|search/\\?query=).+' String getExtractorName() { return 'Tune In' } boolean extractorMatches(URL feedUrl) { return feedUrl ==~ VALID_FEED_URL } int getVersion() { 4 } WebResourceContainer extractItems(URL resourceUrl, int maxItems) { String html = resourceUrl.getText() def titleMatcher = html =~ '(?s)(.+?)<' String pageTitle = titleMatcher[0][1].trim() List items = [] def stationMatcher = html =~ '(?s)
  • \\s* it['Type'] == 'Live' && ['MP3','Windows','AAC'].contains(it['MediaType']) && it['Url'].indexOf('adType') == -1 } if( streams.size() > 0 ) { // ignore quality, audio bitrate is too low to make any difference, deliver the best available streams = streams.sort { it -> it['Bandwidth'].toInteger() } Map selectedStream = streams.last() String streamUrl = selectedStream['Url'] boolean hasPlaylist = Boolean.valueOf (selectedStream['HasPlaylist']) if(hasPlaylist) { return getUrlFromPlaylist(new URL(streamUrl)) } else { return streamUrl } } else { return null } } /** * Supports m3u playlists ATM */ protected getUrlFromPlaylist(URL playlistUrl) { assert playlistUrl != null String playlist = playlistUrl.getText() if(playlist.toLowerCase().startsWith(" -1 || url.indexOf('.pls') > -1) { return getUrlFromPlaylist(new URL(url)) } return url } } static void main(args) { // this is just to test TuneIn extractor = new TuneIn() assert extractor.extractorMatches( new URL("http://tunein.com/radio/London-United-Kingdom-r100780/?qlc=1") ) assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") ) //WebResourceContainer container = extractor.extractItems( new URL("http://tunein.com/radio/London-United-Kingdom-r100780/?qlc=1"), -1) // with embedded streams //WebResourceContainer container = extractor.extractItems( new URL("http://tunein.com/radio/search/05301/"), -1) // with external streams WebResourceContainer container = extractor.extractItems( new URL("http://tunein.com/radio/Trance-g403/"), -1) println container ContentURLContainer result = extractor.extractUrl(container.getItems()[2], PreferredQuality.MEDIUM) print result //println extractor.getUrlFromPlaylist (new URL("http://stream.radiotime.com/listen.stream?streamId=1045956&rti=dihyG20zJlYQXB09HBdHXE8gQV4QHBwvSwUAV11OJg0ZThZ7ZFBYDFEDJn8QRlU0CwdPUFNDRG5FEFF0Ek5dEFYSXXRqGAVEBUUEUlhRYQ0%3d%7e%7e%7e")) } }