package youtube;
import activity.AWeb.Video;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javax.xml.parsers.FactoryConfigurationError;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
public class YouTubeUtility {
/**
* Retrieve the latest video in the specified playlist.
*
* @param pPlaylistId the id of the playlist for which to retrieve the latest video id
* @return the video id of the latest video, null if something goes wrong
* @throws java.io.IOException
* @throws org.apache.http.client.ClientProtocolException
* @throws javax.xml.parsers.FactoryConfigurationError
*/
public static String queryLatestPlaylistVideo(PlaylistId pPlaylistId)
throws IOException, ClientProtocolException,
FactoryConfigurationError {
String lVideoId = null;
HttpClient lClient = new DefaultHttpClient();
HttpGet lGetMethod = new HttpGet(YoutubeUrlIDs.YOUTUBE_PLAYLIST_ATOM_FEED_URL +
pPlaylistId.getId() + "?v=2&max-results=50&alt=json");
HttpResponse lResp = null;
lResp = lClient.execute(lGetMethod);
ByteArrayOutputStream lBOS = new ByteArrayOutputStream();
String lInfoStr = null;
JSONObject lYouTubeResponse = null;
try {
lResp.getEntity().writeTo(lBOS);
lInfoStr = lBOS.toString("UTF-8");
lYouTubeResponse = new JSONObject(lInfoStr);
JSONArray lEntryArr = lYouTubeResponse.getJSONObject("feed").getJSONArray("entry");
JSONArray lLinkArr = lEntryArr.getJSONObject(lEntryArr.length() - 1).getJSONArray("link");
for (int i = 0; i < lLinkArr.length(); i++) {
JSONObject lLinkObj = lLinkArr.getJSONObject(i);
;
String lRelVal = lLinkObj.optString("rel", null);
if (lRelVal != null && lRelVal.equals("alternate")) {
String lUriStr = lLinkObj.optString("href", null);
Uri lVideoUri = Uri.parse(lUriStr);
lVideoId = lVideoUri.getQueryParameter("v");
break;
}
}
} catch (IllegalStateException e) {
Log.i(YouTubeUtility.class.getSimpleName(), "Error retrieving content from YouTube", e);
} catch (IOException e) {
Log.i(YouTubeUtility.class.getSimpleName(), "Error retrieving content from YouTube", e);
} catch (JSONException e) {
Log.i(YouTubeUtility.class.getSimpleName(), "Error retrieving content from YouTube", e);
}
return lVideoId;
}
/**
* Get the string info for parse the video.
*/
public static String getInfoString(String id) throws IOException {
HttpClient lClient = new DefaultHttpClient();
HttpGet lGetMethod = new HttpGet(YoutubeUrlIDs.YOUTUBE_VIDEO_INFORMATION_URL + id + "&el=embedded&gl=US&hl=en&eurl=" + URLEncoder.encode("https://youtube.googleapis.com/v/" + id, "UTF-8") + "&asv=3&sts=1588");
HttpResponse lResp = null;
lResp = lClient.execute(lGetMethod);
ByteArrayOutputStream lBOS = new ByteArrayOutputStream();
String lInfoStr = null;
lResp.getEntity().writeTo(lBOS);
lInfoStr = new String(lBOS.toString("UTF-8"));
return lInfoStr;
}
/**
* Get the websource of a youtube video.
*/
public static String getUrlSource(String id) throws IOException {
URL yahoo = new URL(YoutubeUrlIDs.YOUTUBE_VIDEO_INFORMATION_URL + id);
URLConnection yc = yahoo.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream(), "UTF-8"));
String inputLine;
StringBuilder a = new StringBuilder();
while ((inputLine = in.readLine()) != null)
a.append(inputLine);
in.close();
return a.toString();
}
/**
* Parsing videos from youtube.
* Script#1.
*/
public static ArrayList<Video> func_get_video_script1(String web_source) throws Exception {
ArrayList<Video> video_list = new ArrayList<Video>();
String[] lArgs = web_source.split("&");
Map<String, String> lArgMap = new HashMap<String, String>();
for (int i = 0; i < lArgs.length; i++) {
String[] lArgValStrArr = lArgs[i].split("=");
if (lArgValStrArr != null) {
if (lArgValStrArr.length >= 2) {
lArgMap.put(lArgValStrArr[0], URLDecoder.decode(lArgValStrArr[1]));
}
}
}
//Find out the URI string from the parameters
//Populate the list of formats for the video
String lFmtList = URLDecoder.decode(lArgMap.get("fmt_list"));
ArrayList<Format> lFormats = new ArrayList<Format>();
if (null != lFmtList) {
String lFormatStrs[] = lFmtList.split(",");
for (String lFormatStr : lFormatStrs) {
Format lFormat = new Format(lFormatStr);
lFormats.add(lFormat);
}
}
//Populate the list of streams for the video
String lStreamList = lArgMap.get("url_encoded_fmt_stream_map");
if (null != lStreamList) {
String lStreamStrs[] = lStreamList.split(",");
ArrayList<VideoStream> lStreams = new ArrayList<VideoStream>();
for (String lStreamStr : lStreamStrs) {
VideoStream lStream = new VideoStream(lStreamStr);
lStreams.add(lStream);
}
//-----------------------------------------------------
//----
HashMap<Integer, String> typeMap = new HashMap<Integer, String>();
typeMap.put(13, "Low : 176x144 | 3GP");
typeMap.put(17, "Low : 176x144 | 3GP");
typeMap.put(36, "Medium : 320x240 | 3GP");
typeMap.put(5, "Medium : 640x360 | FLV");
typeMap.put(6, "Medium : 640x360 | FLV");
typeMap.put(34, "Medium : 640x360 | FLV");
typeMap.put(35, "High : 854x480 | FLV");
typeMap.put(43, "Medium : 640x360 | WEBM");
typeMap.put(44, "High : 854x480 | WEBM");
typeMap.put(45, "HD : 1280x720 | WEBM");
typeMap.put(46, "Full HD 3D : 1920x1020 | WEBM");
typeMap.put(18, "Medium : 480x360 | MP4");
typeMap.put(22, "HD : 1280x720 | MP4");
typeMap.put(37, "Full HD : 1920x1080 | MP4");
typeMap.put(38, "Full HD 3D : 3072x1080 | MP4");
typeMap.put(33, "4K : 4096x230 | MP4");
for (Format lformat : lFormats) {
Video lvid = new Video();
int lIndex = lFormats.indexOf(lformat);
int id = lformat.getId();
//get video quality type string..
String ltype = typeMap.get(id);
if (lIndex >= 0) {
VideoStream lSearchStream = lStreams.get(lIndex);
String lUriString = Uri.decode(Uri.parse(lSearchStream.getUrl()).toString());
lvid.type = ltype;
lvid.url = lUriString;
if (lvid.type != null && lvid.url != null) {
video_list.add(lvid);
}
}
}
}
return video_list;
}
/**
* Parsing videos from youtube.
* This is : Script#2
*/
public static ArrayList<Video> func_get_video_script2(String pYouTubeVideoId) throws IOException,
ClientProtocolException, UnsupportedEncodingException {
ArrayList<Video> lVideoList = new ArrayList<Video>();
HttpClient lClient = new DefaultHttpClient();
HttpGet lGetMethod = new HttpGet(YoutubeUrlIDs.YOUTUBE_VIDEO_INFORMATION_URL + pYouTubeVideoId + "&el=embedded&gl=US&hl=en&eurl=" + URLEncoder.encode("https://youtube.googleapis.com/v/" + pYouTubeVideoId, "UTF-8") + "&asv=3&sts=1588");
HttpResponse lResp = null;
lResp = lClient.execute(lGetMethod);
ByteArrayOutputStream lBOS = new ByteArrayOutputStream();
String lInfoStr = null;
lResp.getEntity().writeTo(lBOS);
lInfoStr = new String(lBOS.toString("UTF-8"));
String[] lArgs = lInfoStr.split("&");
Map<String, String> lArgMap = new HashMap<String, String>();
for (int i = 0; i < lArgs.length; i++) {
String[] lArgValStrArr = lArgs[i].split("=");
if (lArgValStrArr != null) {
if (lArgValStrArr.length >= 2) {
lArgMap.put(lArgValStrArr[0], URLDecoder.decode(lArgValStrArr[1]));
}
}
}
//Find out the URI string from the parameters
//Populate the list of formats for the video
String lFmtList = URLDecoder.decode(lArgMap.get("fmt_list"));
ArrayList<Format> lFormats = new ArrayList<Format>();
if (null != lFmtList) {
String lFormatStrs[] = lFmtList.split(",");
for (String lFormatStr : lFormatStrs) {
Format lFormat = new Format(lFormatStr);
lFormats.add(lFormat);
}
}
//Populate the list of streams for the video
String lStreamList = lArgMap.get("url_encoded_fmt_stream_map");
if (null != lStreamList) {
String lStreamStrs[] = lStreamList.split(",");
ArrayList<VideoStream> lStreams = new ArrayList<VideoStream>();
for (String lStreamStr : lStreamStrs) {
VideoStream lStream = new VideoStream(lStreamStr);
lStreams.add(lStream);
}
//-----------------------------------------------------
//----
HashMap<Integer, String> typeMap = new HashMap<Integer, String>();
typeMap.put(13, "Low : 176x144 | 3GP");
typeMap.put(17, "Low : 176x144 | 3GP");
typeMap.put(36, "Medium : 320x240 | 3GP");
typeMap.put(5, "Medium : 640x360 | FLV");
typeMap.put(6, "Medium : 640x360 | FLV");
typeMap.put(34, "Medium : 640x360 | FLV");
typeMap.put(35, "High : 854x480 | FLV");
typeMap.put(43, "Medium : 640x360 | WEBM");
typeMap.put(44, "High : 854x480 | WEBM");
typeMap.put(45, "HD : 1280x720 | WEBM");
typeMap.put(46, "Full HD 3D : 1920x1020 | WEBM");
typeMap.put(18, "Medium : 480x360 | MP4");
typeMap.put(22, "HD : 1280x720 | MP4");
typeMap.put(37, "Full HD : 1920x1080 | MP4");
typeMap.put(38, "Full HD 3D : 3072x1080 | MP4");
typeMap.put(33, "4K : 4096x230 | MP4");
for (Format lformat : lFormats) {
Video lvid = new Video();
int lIndex = lFormats.indexOf(lformat);
int id = lformat.getId();
//get video quality type string..
String ltype = typeMap.get(id);
if (lIndex >= 0) {
VideoStream lSearchStream = lStreams.get(lIndex);
String lUriString = Uri.decode(Uri.parse(lSearchStream.getUrl()).toString());
lvid.type = ltype;
lvid.url = lUriString;
if (lvid.type != null && lvid.url != null) {
lVideoList.add(lvid);
}
}
}
}
return lVideoList;
}
public static String calculateYouTubeUrl(String pYouTubeFmtQuality, boolean pFallback, String pYouTubeVideoId) throws IOException,
ClientProtocolException, UnsupportedEncodingException {
String lUriStr = null;
HttpClient lClient = new DefaultHttpClient();
HttpGet lGetMethod = new HttpGet(YoutubeUrlIDs.YOUTUBE_VIDEO_INFORMATION_URL +
pYouTubeVideoId);
HttpResponse lResp = null;
lResp = lClient.execute(lGetMethod);
ByteArrayOutputStream lBOS = new ByteArrayOutputStream();
String lInfoStr = null;
lResp.getEntity().writeTo(lBOS);
lInfoStr = new String(lBOS.toString("UTF-8"));
String[] lArgs = lInfoStr.split("&");
Map<String, String> lArgMap = new HashMap<String, String>();
for (int i = 0; i < lArgs.length; i++) {
String[] lArgValStrArr = lArgs[i].split("=");
if (lArgValStrArr != null) {
if (lArgValStrArr.length >= 2) {
lArgMap.put(lArgValStrArr[0], URLDecoder.decode(lArgValStrArr[1]));
}
}
}
//Find out the URI string from the parameters
//Populate the list of formats for the video
String lFmtList = URLDecoder.decode(lArgMap.get("fmt_list"));
ArrayList<Format> lFormats = new ArrayList<Format>();
if (null != lFmtList) {
String lFormatStrs[] = lFmtList.split(",");
for (String lFormatStr : lFormatStrs) {
Format lFormat = new Format(lFormatStr);
lFormats.add(lFormat);
}
}
//Populate the list of streams for the video
String lStreamList = lArgMap.get("url_encoded_fmt_stream_map");
if (null != lStreamList) {
String lStreamStrs[] = lStreamList.split(",");
ArrayList<VideoStream> lStreams = new ArrayList<VideoStream>();
for (String lStreamStr : lStreamStrs) {
VideoStream lStream = new VideoStream(lStreamStr);
lStreams.add(lStream);
}
//Search for the given format in the list of video formats
// if it is there, select the corresponding stream
// otherwise if fallback is requested, check for next lower format
int lFormatId = Integer.parseInt(pYouTubeFmtQuality);
Format lSearchFormat = new Format(lFormatId);
while (!lFormats.contains(lSearchFormat) && pFallback) {
int lOldId = lSearchFormat.getId();
int lNewId = getSupportedFallbackId(lOldId);
if (lOldId == lNewId) {
break;
}
lSearchFormat = new Format(lNewId);
}
int lIndex = lFormats.indexOf(lSearchFormat);
if (lIndex >= 0) {
VideoStream lSearchStream = lStreams.get(lIndex);
lUriStr = lSearchStream.getUrl();
}
}
//Return the URI string. It may be null if the format (or a fallback format if enabled)
// is not found in the list of formats for the video
return lUriStr;
}
public static boolean hasVideoBeenViewed(Context pCtxt, String pVideoId) {
SharedPreferences lPrefs = PreferenceManager.getDefaultSharedPreferences(pCtxt);
String lViewedVideoIds = lPrefs.getString("com.keyes.screebl.lastViewedVideoIds", null);
if (lViewedVideoIds == null) {
return false;
}
String[] lSplitIds = lViewedVideoIds.split(";");
if (lSplitIds == null || lSplitIds.length == 0) {
return false;
}
for (int i = 0; i < lSplitIds.length; i++) {
if (lSplitIds[i] != null && lSplitIds[i].equals(pVideoId)) {
return true;
}
}
return false;
}
public static void markVideoAsViewed(Context pCtxt, String pVideoId) {
SharedPreferences lPrefs = PreferenceManager.getDefaultSharedPreferences(pCtxt);
if (pVideoId == null) {
return;
}
String lViewedVideoIds = lPrefs.getString("com.keyes.screebl.lastViewedVideoIds", null);
if (lViewedVideoIds == null) {
lViewedVideoIds = "";
}
String[] lSplitIds = lViewedVideoIds.split(";");
if (lSplitIds == null) {
lSplitIds = new String[]{};
}
// make a hash table of the ids to deal with duplicates
Map<String, String> lMap = new HashMap<String, String>();
for (int i = 0; i < lSplitIds.length; i++) {
lMap.put(lSplitIds[i], lSplitIds[i]);
}
// recreate the viewed list
String lNewIdList = "";
Set<String> lKeys = lMap.keySet();
Iterator<String> lIter = lKeys.iterator();
while (lIter.hasNext()) {
String lId = lIter.next();
if (!lId.trim().equals("")) {
lNewIdList += lId + ";";
}
}
// add the new video id
lNewIdList += pVideoId + ";";
Editor lPrefEdit = lPrefs.edit();
lPrefEdit.putString("com.keyes.screebl.lastViewedVideoIds", lNewIdList);
lPrefEdit.commit();
}
public static int getSupportedFallbackId(int pOldId) {
final int lSupportedFormatIds[] = {13, //3GPP (MPEG-4 encoded) Low quality
17, //3GPP (MPEG-4 encoded) Medium quality
18, //MP4 (H.264 encoded) Normal quality
22, //MP4 (H.264 encoded) High quality
37 //MP4 (H.264 encoded) High quality
};
int lFallbackId = pOldId;
for (int i = lSupportedFormatIds.length - 1; i >= 0; i--) {
if (pOldId == lSupportedFormatIds[i] && i > 0) {
lFallbackId = lSupportedFormatIds[i - 1];
}
}
return lFallbackId;
}
}