Para todo esto vamos a utilizar la api que nos provee google: YouTube Data API (v3). Esta api nos permite incorporar funcionalidades de youtube en nuestra propia aplicación. Se puede utilizar la api para buscar videos, insertar, actualizar y borrar recursos tales como videos o listas de reproducciones de video.
Contenido:
- Registrar nuestra aplicación para obtener una clave publica de google.
- Definición del modelo para convertir la data json a objetos java.
- Servicio spring que contendrá la api necesaria para la búsqueda de videos.
- Definición del controlador que recibirá las peticiones realizadas por el usuario.
- Diseño de la vista para mostrar la lista de videos de manera paginada.
- Vista de la aplicación.
1. Registrar nuestra aplicación para obtener una clave publica de google.
2. Definición del modelo para convertir la data json a objetos java: Vamos a crear dos clases java, una para manejar la información relacionada a la lista de videos retornada por google y otra clase para manejar la información del video.
public class VideoYoutube { private String videoId; private Date publischedAt; private String channelId; private String title; private String description; private String thumbnail; private String channelTitle; private String duration; private Long viewCount; public VideoYoutube() { this.videoId = ""; this.publischedAt = null; this.channelId = ""; this.title = ""; this.description = ""; this.thumbnail = ""; this.channelTitle = ""; this.duration = ""; this.viewCount = null; } public VideoYoutube(String videoId, Date publischedAt, String channelId, String title, String description, String thumbnail, String channelTitle, String duration, Long viewCount) { super(); this.videoId = videoId; this.publischedAt = publischedAt; this.channelId = channelId; this.title = title; this.description = description; this.thumbnail = thumbnail; this.channelTitle = channelTitle; this.duration = duration; this.viewCount = viewCount; } public String getVideoId() { return videoId; } public void setVideoId(String videoId) { this.videoId = videoId; } public Date getPublischedAt() { return publischedAt; } public void setPublischedAt(Date publischedAt) { this.publischedAt = publischedAt; } public String getChannelId() { return channelId; } public void setChannelId(String channelId) { this.channelId = channelId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getThumbnail() { return thumbnail; } public void setThumbnail(String thumbnail) { this.thumbnail = thumbnail; } public String getChannelTitle() { return channelTitle; } public void setChannelTitle(String channelTitle) { this.channelTitle = channelTitle; } public String getDuration() { if (duration != null && !duration.equals("")) { StringBuilder strPeriod = new StringBuilder(); PeriodFormatter formatter = ISOPeriodFormat.standard(); Period period = formatter.parsePeriod(duration); if (period.getHours() > 0) { strPeriod.append(period.getHours()).append(":"); } if (period.getMinutes() < 10) { strPeriod.append("0").append(period.getMinutes()).append(":"); } else { strPeriod.append(period.getMinutes()).append(":"); } if (period.getSeconds() < 10) { strPeriod.append("0").append(period.getSeconds()); } else { strPeriod.append(period.getSeconds()); } return strPeriod.toString(); } return duration; } public void setDuration(String duration) { this.duration = duration; } public Long getViewCount() { return viewCount; } public void setViewCount(Long viewCount) { this.viewCount = viewCount; } } public class PageResultYoutube { private String nextPageToken; private String prevPageToken; private int totalResults; private int resultsPerPage; private MapvideosResults; public PageResultYoutube(String nextPageToken, String prevPageToken, int totalResults, int resultsPerPage, Map videosResults) { super(); this.nextPageToken = nextPageToken; this.prevPageToken = prevPageToken; this.totalResults = totalResults; this.resultsPerPage = resultsPerPage; this.videosResults = videosResults; } public PageResultYoutube(String dataJson) { JSONObject jo = new JSONObject(dataJson); if (jo.has("nextPageToken")) { nextPageToken = jo.getString("nextPageToken"); } if (jo.has("prevPageToken")) { prevPageToken = jo.getString("prevPageToken"); } if (jo.has("pageInfo")) { JSONObject pageInfo = jo.getJSONObject("pageInfo"); totalResults = pageInfo.getInt("totalResults"); resultsPerPage = pageInfo.getInt("resultsPerPage"); } videosResults = new HashMap (); if (jo.has("items")) { JSONArray items = jo.getJSONArray("items"); VideoYoutube video; for (int i = 0; i < items.length(); i++) { video = new VideoYoutube(); JSONObject item = items.getJSONObject(i); JSONObject id = item.getJSONObject("id"); JSONObject snippet = item.getJSONObject("snippet"); video.setVideoId(id.getString("videoId")); video.setChannelId(snippet.getString("channelId")); video.setChannelTitle(snippet.getString("channelTitle")); video.setDescription(snippet.getString("description")); video.setPublischedAt(new DateTime(snippet .getString("publishedAt")).toDate()); video.setThumbnail(snippet.getJSONObject("thumbnails") .getJSONObject("default").getString("url")); video.setTitle(snippet.getString("title")); videosResults.put(video.getVideoId(), video); } } } public String getVideoIdsSeparetedByComma() { StringBuilder str = new StringBuilder(); if (videosResults != null && videosResults.size() > 0) { for (Entry entry : videosResults.entrySet()) { str.append(entry.getKey()).append(","); } }// XXX fix validation String finalStr = str.toString(); finalStr = finalStr.substring(0, finalStr.toString().length() - 1); return finalStr; } public void addVideo(VideoYoutube video) { videosResults.put(video.getVideoId(), video); } public String getNextPageToken() { return nextPageToken; } public void setNextPageToken(String nextPageToken) { this.nextPageToken = nextPageToken; } public String getPrevPageToken() { return prevPageToken; } public void setPrevPageToken(String prevPageToken) { this.prevPageToken = prevPageToken; } public int getTotalResults() { return totalResults; } public void setTotalResults(int totalResults) { this.totalResults = totalResults; } public int getResultsPerPage() { return resultsPerPage; } public void setResultsPerPage(int resultsPerPage) { this.resultsPerPage = resultsPerPage; } public Map getVideosResults() { return videosResults; } public void setVideosResults(Map videosResults) { this.videosResults = videosResults; } public void setContentDetailsVideos(String contentDetailsJson) { JSONObject jo = new JSONObject(contentDetailsJson); if (jo.has("items")) { JSONArray items = jo.getJSONArray("items"); for (int i = 0; i < items.length(); i++) { JSONObject item = items.getJSONObject(i); VideoYoutube video = videosResults.get(item.get("id")); JSONObject cd = item.getJSONObject("contentDetails"); video.setDuration(cd.getString("duration")); JSONObject stats = item.getJSONObject("statistics"); video.setViewCount(stats.getLong("viewCount")); videosResults.put(video.getVideoId(), video); } } } }
3. Servicio spring que contendrá la api necesaria para la búsqueda de videos.
/** * * @author Williams Rivas Created 20/02/2014 12:59:49 * */ @Service public class YoutubeServiceImpl implements YoutubeService { public static final String PARAM_MAX_RESULTS = "maxResults"; private static int DEFAULT_VALUE_MAX_RESULTS = 16; private static String DEFAULT_VALUE_CHANNEL_ID = “XXXXXXXXXXXXXXXXXXXXXX"; public static final String PARAM_PART = "part"; public static final String DEFAULT_VALUE_PART = "snippet"; public static final String DEFAULT_VALUE_PARTS_VIDEOS = "contentDetails%2Cstatistics"; public static final String PARAM_PAGE_TOKEN = "pageToken"; public static final String PARAM_CHANNEL_ID = "channelId"; public static final String PARAM_VIDEO_IDS = "id"; public static final String PARAM_KEY = "key"; private static final String DEFAULT_VALUE_KEY = "API_KEY_GENERADA_EN_EL_PASO_UNO_DEL_CONTENIDO_DE_ESTE_POST"; public static final String URL_SEARCH_YOUTUBE = "https://www.googleapis.com/youtube/v3/search?type=video&"; public static final String URL_VIDEOS_LIST = "https://www.googleapis.com/youtube/v3/videos?"; public static final String PARAM_VALUE_SEPARATOR = "="; public static final String PARAM_VALUE_CONCAT = "&"; public static final String PARAM_VALUE_COMMA = "%2C"; @Autowired protected YoutubeCanalRepository youtubeCanalRepository; @Override public PageResultYoutube searchYoutubeVideos(String part, String channelId, int maxResults, String pageToken) throws SearchYoutubeException { setDefaultValues(); String query = buildQueryUrl(part, channelId, maxResults, pageToken, null); String dataJson = Util.httpGet(query); PageResultYoutube page = new PageResultYoutube(dataJson); String videoIds = page.getVideoIdsSeparetedByComma(); String contentDetailsJson = ""; try { contentDetailsJson = Util.httpGet(buildQueryUrl( DEFAULT_VALUE_PARTS_VIDEOS, null, DEFAULT_VALUE_MAX_RESULTS, null, videoIds)); } catch (HttpGetException e) { throw new SearchYoutubeException(e.getMessage()); } page.setContentDetailsVideos(contentDetailsJson); return page; } @Override public PageResultYoutube searchYoutubeVideos(String part, String channelId, int maxResults) throws SearchYoutubeException { return searchYoutubeVideos(part, channelId, maxResults, null); } @Override public PageResultYoutube searchYoutubeVideos() throws SearchYoutubeException { return searchYoutubeVideos(DEFAULT_VALUE_PART, DEFAULT_VALUE_CHANNEL_ID, DEFAULT_VALUE_MAX_RESULTS); } private String buildQueryUrl(String part, String channelId, int maxResults, String pageToken, String videoIds) { StringBuilder url; if (channelId != null && !channelId.equals("")) { url = new StringBuilder(URL_SEARCH_YOUTUBE); // parametro part url.append(PARAM_PART).append(PARAM_VALUE_SEPARATOR); if (part != null && !part.equals("")) { if (!part.equals(DEFAULT_VALUE_PART)) { url.append(DEFAULT_VALUE_PART); } else { url.append(part); } } else { url.append(DEFAULT_VALUE_PART); } // parametro channel id url.append(PARAM_VALUE_CONCAT).append(PARAM_CHANNEL_ID) .append(PARAM_VALUE_SEPARATOR); if (channelId != null && !channelId.equals("")) { url.append(channelId); } else { url.append(DEFAULT_VALUE_CHANNEL_ID); } // pagina if (pageToken != null && !pageToken.equals("")) { url.append(PARAM_VALUE_CONCAT).append(PARAM_PAGE_TOKEN) .append(PARAM_VALUE_SEPARATOR).append(pageToken); } } else { // busqueda no por canal sino por ids de videos // https://www.googleapis.com/youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics&id=uWKM4F2RAtI%2CJ2NIttHwZBA%2C6UliPT1LIc4%2CSaLWwDyHMvo&maxResults=3&key=AIzaSyBB8x12DXzrzXKhkum5f_Nv3Yl7-0GSwCg url = new StringBuilder(URL_VIDEOS_LIST); // parametro part url.append(PARAM_PART).append(PARAM_VALUE_SEPARATOR); if (part != null && !part.equals("")) { if (!part.equals(DEFAULT_VALUE_PARTS_VIDEOS)) { url.append(DEFAULT_VALUE_PARTS_VIDEOS); } else { url.append(part); } } else { url.append(DEFAULT_VALUE_PARTS_VIDEOS); } // videos ids separados por comma if (videoIds != null && !videoIds.equals("")) { url.append(PARAM_VALUE_CONCAT).append(PARAM_VIDEO_IDS) .append(PARAM_VALUE_SEPARATOR); url.append(videoIds); } } // max results url.append(PARAM_VALUE_CONCAT).append(PARAM_MAX_RESULTS) .append(PARAM_VALUE_SEPARATOR); if (maxResults <= 0) { url.append(DEFAULT_VALUE_MAX_RESULTS); } else { url.append(maxResults); } // key developer url.append(PARAM_VALUE_CONCAT).append(PARAM_KEY) .append(PARAM_VALUE_SEPARATOR).append(DEFAULT_VALUE_KEY); return url.toString(); } @Override public PageResultYoutube searchYoutubeVideos(String pageToken) throws SearchYoutubeException { return searchYoutubeVideos(DEFAULT_VALUE_PART, DEFAULT_VALUE_CHANNEL_ID, DEFAULT_VALUE_MAX_RESULTS, pageToken); } private void setDefaultValues() { Listcanals = youtubeCanalRepository.findAll(); if (canals != null && canals.size() > 0) { DEFAULT_VALUE_CHANNEL_ID = canals.get(0).getIdChannel(); DEFAULT_VALUE_MAX_RESULTS = canals.get(0).getMaxResults(); } } }
4. Definición del controlador que recibirá las peticiones realizadas por el usuario.
@RequestMapping("/youtube/**") @Controller public class YoutubeController extends GlobalModelAttributes { @Autowired private YoutubeService youtube; @RequestMapping(method = RequestMethod.POST, value = "{id}") public void post(@PathVariable Long id, ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) { } @RequestMapping public String index( @RequestParam(value = "page", required = false) String page, ModelMap uiModel) { PageResultYoutube result; if (page != null) { result = youtube.searchYoutubeVideos(page); } else { result = youtube.searchYoutubeVideos(); } uiModel.addAttribute("youtube", result); return "youtube/index"; } }
5. Diseño de la vista para mostrar la lista de videos de manera paginada.
6. Vista de la aplicación
No hay comentarios:
Publicar un comentario