diff --git a/app/app.iml b/app/app.iml index d853a04..fb36e3b 100755 --- a/app/app.iml +++ b/app/app.iml @@ -79,6 +79,7 @@ + diff --git a/app/src/main/java/com/ericsson/uecontrol/core/behaviour/UeBehaviourVideoStreaming.java b/app/src/main/java/com/ericsson/uecontrol/core/behaviour/UeBehaviourVideoStreaming.java index 57009aa..f4fe4c2 100755 --- a/app/src/main/java/com/ericsson/uecontrol/core/behaviour/UeBehaviourVideoStreaming.java +++ b/app/src/main/java/com/ericsson/uecontrol/core/behaviour/UeBehaviourVideoStreaming.java @@ -11,8 +11,11 @@ import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.SAXReader; -import java.net.MalformedURLException; -import java.net.URL; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.*; +import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -22,9 +25,10 @@ import java.util.regex.Pattern; */ public class UeBehaviourVideoStreaming extends UeBehaviour implements MediaPlayer.OnErrorListener{ private static final Logger log = Logger.getLogger(UeBehaviourVideoStreaming.class); - private static final Pattern YOUTUBE_VIDEOURL_PATTERN = Pattern.compile(".*youtube.*[&\\?]v=([\\w_-]*)[&#]?"); - private static final Pattern YOUTUBE_VIDEOID_PATTERN = Pattern.compile("^[\\w_-]*$"); + protected static final Pattern YOUTUBE_VIDEOURL_PATTERN = Pattern.compile(".*youtube.*[&\\?]v=([\\w_-]*)[&#]?"); + protected static final Pattern YOUTUBE_VIDEOID_PATTERN = Pattern.compile("^[\\w_-]*$"); protected static final String YOUTUBE_FEED_URL = "http://gdata.youtube.com/feeds/api/videos/"; + protected static final String YOUTUBE_VIDEO_URL = "https://www.youtube.com/watch?v="; @Configurable("Streaming URL") private String url = "I9L79_xEQ-U"; @@ -40,8 +44,14 @@ public class UeBehaviourVideoStreaming extends UeBehaviour implements MediaPlaye try { String videoUrl = url.trim(); if (isYouTubeUrl(videoUrl)) { - videoUrl = getYoutubeRtsUrl(getYoutubeVideoId(videoUrl)); log.debug("Detected youtube video url: " + videoUrl); + + String videoId = getYoutubeVideoId(videoUrl); + videoUrl = getYoutubeFileUrl(videoId); + if(videoUrl == null) { + log.warn("Unable to parse Youtube URL, using fallback rts url"); + videoUrl = getYoutubeRtsUrl(videoId); + } } else { log.debug("Video url: " + videoUrl); @@ -49,7 +59,6 @@ public class UeBehaviourVideoStreaming extends UeBehaviour implements MediaPlaye mp.setDataSource(videoUrl); mp.prepare(); mp.start(); - //log.debug("Video size: "+mp.getVideoWidth()+"x"+mp.getVideoHeight()); Thread.sleep(UeBehaviourSleep.SLEEP_PERIOD); while (mp.isPlaying() && playbackException == null) { @@ -83,7 +92,58 @@ public class UeBehaviourVideoStreaming extends UeBehaviour implements MediaPlaye return match.group(1); return null; } - protected String getYoutubeRtsUrl(String videoId) throws DocumentException, MalformedURLException { + public static String getYoutubeFileUrl(String videoId) throws IOException{ + URL url = new URL(YOUTUBE_VIDEO_URL + videoId); + URLConnection conn = url.openConnection(); + conn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1;) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"); + conn.connect(); + + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line; + while((line = in.readLine()) != null){ + if(line.contains("ytplayer.config")){ + //log.debug("html: " + line); + + Matcher matchUrlMap = Pattern.compile("\"url_encoded_fmt_stream_map\": \"(.*?)\"").matcher(line); + if(matchUrlMap.find()) { + String url_map = matchUrlMap.group(1); + log.debug("url_map: " + url_map); + + Matcher matchStream = Pattern.compile("[^,]+").matcher(url_map); + while (matchStream.find()){ + String stream = URLDecoder.decode(matchStream.group(), "UTF-8"); + log.debug("stream: " + stream); + + HashMap values = new HashMap(); + for(String tag : stream.split("\\\\u0026")){ + String[] key = tag.split("=", 2); + if(key.length > 1) { + log.debug(" tag: " +key[0]+ "=" +key[1]); + values.put(key[0], key[1]); + } + } + + if(values.containsKey("sig") || values.containsKey("s")) { + log.warn("Scrambled Youtube URL not supported"); + return null; + } + else if(values.get("type").contains("video/mp4")){ + return values.get("url"); + } + } + } + } + } + in.close(); + } finally{ + if(in != null) + try{ in.close(); }catch (IOException e){} + } + return null; + } + public static String getYoutubeRtsUrl(String videoId) throws DocumentException, MalformedURLException { URL feedUrl = new URL(YOUTUBE_FEED_URL + videoId); Document document = new SAXReader().read(feedUrl); Attribute attr = (Attribute)document.selectSingleNode( "//media:content[@yt:format='6']/@url" );