jobs.YoutubeJob.java Source code

Java tutorial

Introduction

Here is the source code for jobs.YoutubeJob.java

Source

/*
 * Copyright (c) 2011 - 2016 by  Edward J. Becker
 *
 * This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jobs;

import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.*;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import controllers.Catalog;
import controllers.Users;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import models.LibraryItem;
import models.Track;
import models.User;
import models.YouTubeVideo;
import org.joda.time.Period;
import play.Logger;
import play.Play;
import play.jobs.Job;
import play.libs.F.Promise;
import play.libs.WS;
import play.libs.WS.HttpResponse;
import play.libs.WS.WSRequest;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.services.youtube.YouTube;
import utils.Auth;
//import com.google.api.services.samples.youtube.cmdline.Auth;
import java.util.Iterator;

/**
 *
 * @author Eltmon
 */
public class YoutubeJob extends Job<List<LibraryItem>> {

    public static String key = Play.configuration.getProperty("youtubekey");
    public static String endpoint = "https://gdata.youtube.com/feeds/api/videos";

    private Track track;

    private static final long NUMBER_OF_VIDEOS_RETURNED = 2;

    /**
     * Define a global instance of a YoutubeJob object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY,
            new HttpRequestInitializer() {
                public void initialize(HttpRequest request) throws IOException {
                    Logger.info("youtubeinitiailize");
                }
            }).setApplicationName("youtube-cmdline-search-sample").build();
    //public static YouTubeService service = null; //new YouTubeService("Auricle", key);

    public YoutubeJob(Track track) {

        this.track = track;

    }

    public List<LibraryItem> doJobWithResult() throws Exception {
        // return searchYoutube();
        return null;
    }

    public void loadYoutubes(Track track) {
        Logger.info("Loading you tube videos for " + track.title + "/" + track.artist);

        List searchResultList = searchYoutube(track);
        Iterator iter = searchResultList.iterator();
        SearchResult bestResult = null;

        int difference = 0;

        Logger.info("Found " + searchResultList.size() + " youtube videos on response");
        if (searchResultList != null && iter.hasNext()) {
            while (iter.hasNext()) {
                SearchResult singleVideo = (SearchResult) iter.next();
                YouTubeVideo ytv = new YouTubeVideo(track);
                ytv.thumbnailURL = singleVideo.getSnippet().getThumbnails().getDefault().getUrl();
                ytv.title = singleVideo.getSnippet().getTitle();
                ResourceId rId = singleVideo.getId();

                // Confirm that the result represents a video. Otherwise, the
                // item will not contain a video ID.
                if (rId.getKind().equals("youtube#video")) {
                    Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();
                    //ytv.videoID = singleVideo.getId().getVideoId();
                    ytv.linkID = singleVideo.getId().getVideoId();
                    ytv.videoID = singleVideo.getId().toString();
                    getDetails(ytv, ytv.linkID);
                    if (ytv.duration == 0) {
                        Logger.info("Received 0 duration video, skipping");
                        ytv = null;
                        continue;
                    }
                    Logger.info(" Title:" + singleVideo.getSnippet().getTitle());
                    System.out.println(" Kind:" + rId.getKind());
                    System.out.println(" LinkID:" + singleVideo.getId().getVideoId());
                    System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
                    System.out.println(" Thumbnail: " + thumbnail.getUrl());
                    System.out.println(" ETag: " + singleVideo.getEtag());
                    Logger.info("Found video match for track" + track.title);
                    ytv.save();
                    track.youTubeVideos.add(ytv);

                } else {
                    try {
                        Logger.info("Not a true video for id " + rId.toPrettyString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
        track.save();

    }

    private static List<SearchResult> searchYoutube(Track track) {

        Logger.info("searchyoutube:" + track.title);
        try {

            // Prompt the user to enter a query term.

            // Define the API request for retrieving search results.
            YouTube.Search.List search = youtube.search().list("id,snippet");

            // Set your developer key from the Google Developers Console for
            // non-authenticated requests. See:
            // https://console.developers.google.com/

            Logger.info(track.title + " " + track.artist);

            search.setKey(key);
            search.setQ(track.title + " " + track.artist + " video");

            // Restrict the search results to only include videos. See:
            // https://developers.google.com/youtube/v3/docs/search/list#type
            search.setType("video");
            search.setVideoEmbeddable("true");
            search.setVideoLicense("youtube");
            search.setOrder("relevance");
            // To increase efficiency, only retrieve the fields that the
            // application uses.
            //search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url/etag)");
            search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);

            // Call the API and print results.
            Logger.info("youtubejob:preexecute");
            SearchListResponse searchResponse = search.execute();
            Logger.info("youtubejob:postexecute");
            List<SearchResult> searchResultList = searchResponse.getItems();

            // Find best match

            //Logger.info("=--=-=-=---=-=");

            return searchResultList;

        } catch (GoogleJsonResponseException e) {
            System.err.println(
                    "There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return null;

        //        String searchText = trackName;
        //        //User user = Users.getCurrentUser();
        //        List<Track> tracks;
        //        List<LibraryItem> litems = new ArrayList();

        //
        //        try {
        //            tracks = searchTrack();
        //            Logger.info("Found " + tracks.size() + " tracks on youtube.");
        //            /*
        //             * Now we have to go through user's library, and determine if the
        //             * library items exist If they do not, we have to create one.
        //             */
        //
        //            // Library library = user.library;
        //            // List<LibraryItem> libraryItems = library.libraryItems;
        //
        //            /*
        //             * Go through tracks, make sure each one exists in users library
        //             * items. Won't get saved unless they rate!
        //             */
        //            for (Track track : tracks) {
        //                //Logger.info("Looking for umm " + track.id.toString() + " : " + track.title.toString());
        //                litems.add(Catalog.findMatchingLibraryItem(user, track));
        //            }
        //
        //        } catch (Exception ex) {
        //            Logger.info("Exception in searchYoutube");
        //            ex.printStackTrace();
        //        }
        //        return litems;

    }

    public static YouTubeVideo getDetails(YouTubeVideo youVideo, String videoID) {
        //String videoEntryUrl = "http://gdata.youtube.com/feeds/api/videos/"+videoID;

        // Logger.info("Getting duration for " + videoID);

        try {
            YouTube.Videos.List listVideosRequest = youtube.videos().list("contentDetails").setId(videoID);

            listVideosRequest.setKey(key);
            VideoListResponse listResponse = listVideosRequest.execute();

            List<Video> videoList = listResponse.getItems();
            if (videoList.isEmpty()) {
                System.out.println("Can't find a video with ID: " + videoID);
                return null;
            }

            // Extract the snippet from the video resource.
            Video video = videoList.get(0);
            // Logger.info(video.toString());
            // VideoFileDetails details = video.getFileDetails();
            //Logger.info("Details" + details);
            // Logger.info("CD" + video.getContentDetails());
            // Logger.info("String duration" + video.getContentDetails().getDuration());

            int boo = Period.parse(video.getContentDetails().getDuration()).toStandardSeconds().getSeconds(); // Milliseconds

            //Logger.info("Long duration" + boo);
            // int duration = 3000; //details.getDurationMs().intValue();
            //youVideo.bitrateBps = video.getFileDetails().getBitrateBps().longValue();

            youVideo.duration = boo;
            youVideo.save();

            return youVideo;

        } catch (Exception e) {
            Logger.info("Exception: " + e.getMessage());
            e.printStackTrace();
        }
        return youVideo;
    }

    //    public static ArrayList<Track> searchTrack() {
    //        searchYoutube();
    //
    //
    //        return null; //trackResults;
    //    }

    private static void parseNewTrack(Track track, JsonObject scTrack) {
        track.soundcloud_id = scTrack.get("id").getAsInt();
        track.title = scTrack.get("title").getAsString(); // Name of track

        JsonObject obj = scTrack.get("user").getAsJsonObject();
        track.artist = obj.get("username").getAsString();
        track.album_name = track.title; // Soundcloud items will just use the item name as album name
        track.canStream = scTrack.get("streamable").getAsBoolean();
        track.duration = scTrack.get("duration").getAsLong() / 1000;
        if (!scTrack.get("artwork_url").isJsonNull()) {
            track.coverArt = scTrack.get("artwork_url").getAsString();
            track.bigIcon = track.coverArt;
        }

    }

    //    public static void printVideoEntry(VideoEntry videoEntry, boolean detailed) {
    //        Logger.info("Title: " + videoEntry.getTitle().getPlainText());
    //
    //        if (videoEntry.isDraft()) {
    //            Logger.info("Video is not live");
    //            YtPublicationState pubState = videoEntry.getPublicationState();
    //            if (pubState.getState() == YtPublicationState.State.PROCESSING) {
    //                Logger.info("Video is still being processed.");
    //            } else if (pubState.getState() == YtPublicationState.State.REJECTED) {
    //                System.out.print("Video has been rejected because: ");
    //                Logger.info(pubState.getDescription());
    //                System.out.print("For help visit: ");
    //                Logger.info(pubState.getHelpUrl());
    //            } else if (pubState.getState() == YtPublicationState.State.FAILED) {
    //                System.out.print("Video failed uploading because: ");
    //                Logger.info(pubState.getDescription());
    //                System.out.print("For help visit: ");
    //                Logger.info(pubState.getHelpUrl());
    //            }
    //        }
    //
    //        if (videoEntry.getEditLink() != null) {
    //            Logger.info("Video is editable by current user.");
    //        }
    //
    //        if (detailed) {
    //
    //            YouTubeMediaGroup mediaGroup = videoEntry.getMediaGroup();
    //
    //            Logger.info("Uploaded by: " + mediaGroup.getUploader());
    //
    //            Logger.info("Video ID: " + mediaGroup.getVideoId());
    //            Logger.info("Description: "
    //                    + mediaGroup.getDescription().getPlainTextContent());
    //
    //            MediaPlayer mediaPlayer = mediaGroup.getPlayer();
    //            Logger.info("Web Player URL: " + mediaPlayer.getUrl());
    //            MediaKeywords keywords = mediaGroup.getKeywords();
    //            System.out.print("Keywords: ");
    //            for (String keyword : keywords.getKeywords()) {
    //                System.out.print(keyword + ",");
    //            }
    //
    //            GeoRssWhere location = videoEntry.getGeoCoordinates();
    //            if (location != null) {
    //                Logger.info("Latitude: " + location.getLatitude());
    //                Logger.info("Longitude: " + location.getLongitude());
    //            }
    //
    //            Rating rating = videoEntry.getRating();
    //            if (rating != null) {
    //                Logger.info("Average rating: " + rating.getAverage());
    //            }
    //
    //            YtStatistics stats = videoEntry.getStatistics();
    //            if (stats != null) {
    //                Logger.info("View count: " + stats.getViewCount());
    //            }
    //            //Logger.info();
    //
    //            Logger.info("\tThumbnails:");
    //            for (MediaThumbnail mediaThumbnail : mediaGroup.getThumbnails()) {
    //                Logger.info("\t\tThumbnail URL: " + mediaThumbnail.getUrl());
    //                Logger.info("\t\tThumbnail Time Index: "
    //                        + mediaThumbnail.getTime());
    //                //Logger.info();
    //            }
    //
    //            Logger.info("\tMedia:");
    //            for (YouTubeMediaContent mediaContent : mediaGroup.getYouTubeContents()) {
    //                Logger.info("\t\tMedia Location: " + mediaContent.getUrl());
    //                Logger.info("\t\tMedia Type: " + mediaContent.getType());
    //                Logger.info("\t\tDuration: " + mediaContent.getDuration());
    //                //Logger.info();
    //            }
    //
    //            for (YouTubeMediaRating mediaRating : mediaGroup.getYouTubeRatings()) {
    //                Logger.info("Video restricted in the following countries: "
    //                        + mediaRating.getCountries().toString());
    //            }
    //        }
    //    }
    //
    //    public static void printVideoFeed(VideoFeed videoFeed, boolean detailed) {
    //        for (VideoEntry videoEntry : videoFeed.getEntries()) {
    //            printVideoEntry(videoEntry, detailed);
    //        }
    //    }
}