com.edgehometheater.IndexMoviesContext.java Source code

Java tutorial

Introduction

Here is the source code for com.edgehometheater.IndexMoviesContext.java

Source

/***********************************************
 This file is part of the Edge Home Theater project (https://github.com/parlock/Edge-Home-Theater).
    
Edge Home Theater is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
Edge Home Theater 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 General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Edge Home Theater.  If not, see <http://www.gnu.org/licenses/>.
    
***********************************************/

package com.edgehometheater;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Set;

import org.json.*;

import com.edgehometheater.util.*;
import com.edgehometheater.mediainfo.*;
import com.github.savvasdalkitsis.jtmdb.*;

import net.freeutils.httpserver.HTTPServer.*;

@SuppressWarnings("deprecation")
public class IndexMoviesContext implements ContextHandler {
    protected String moviesPath = "";
    protected static boolean indexing = false;

    public IndexMoviesContext(String path) {
        moviesPath = path;
    }

    public boolean Status() {
        return indexing;
    }

    @Context("/indexmovies")
    public int serve(Request req, Response resp) throws IOException {

        // Check if we are already indexing
        if (!indexing) {
            indexing = true;

            // Create thread for scanning media in background
            Thread t = new Thread() {
                public void run() {

                    int count = IndexMovies(moviesPath);

                    indexing = false;
                }
            };

            // Start thread to index movies in background
            t.start();
        }

        // Let client know indexing is inprogress
        try {
            JSONObject listJson = new JSONObject();
            listJson.put("status", "inprogress");

            String baseJson = listJson.toString();
            resp.send(200, baseJson);
        } catch (Exception ex) {
        }

        return 0;
    }

    public int IndexMovies(String directory) {
        int count = 0;

        File movieDir = new File(directory);
        String[] movieFiles = movieDir.list(new MovieFilter());

        for (String movieFile : movieFiles) {

            File file = new File(movieDir.toString() + "/" + movieFile);

            // Sub-directory
            if (file.isDirectory()) {
                int subCount = IndexMovies(directory + "/" + file.getName());

                count = count + subCount;
                continue;
            }

            // check if we already indexed this file in the Sqlite3 DB
            String relativeMovieFile = file.getAbsolutePath().replace(moviesPath + "\\", "")
                    .replace(moviesPath + "/", "").replace("\\", "/");
            if (MovieDB.MovieExists(relativeMovieFile).length() > 0) {
                // skip this movie
                continue;
            }

            // count of movies processed
            count++;

            MetaData metaData = new MetaData();
            metaData.setMovieID(GeneralUtils.getUniqueId());

            metaData.setMovieFile(relativeMovieFile);

            try {
                // Lookup media stream info, bitrate, width x height, framerate, duration, format, etc..
                MediaInfo info = new MediaInfo();
                info.open(file);

                int i = 0;

                //String format     = info.get(MediaInfo.StreamKind.Video, i, "Format", 
                //                        MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
                String bitRate = info.get(MediaInfo.StreamKind.Video, i, "BitRate", MediaInfo.InfoKind.Text,
                        MediaInfo.InfoKind.Name);
                String frameRate = info.get(MediaInfo.StreamKind.Video, i, "FrameRate", MediaInfo.InfoKind.Text,
                        MediaInfo.InfoKind.Name);
                String width = info.get(MediaInfo.StreamKind.Video, i, "Width", MediaInfo.InfoKind.Text,
                        MediaInfo.InfoKind.Name);
                String height = info.get(MediaInfo.StreamKind.Video, i, "Height", MediaInfo.InfoKind.Text,
                        MediaInfo.InfoKind.Name);
                String duration = info.get(MediaInfo.StreamKind.Video, i, "Duration", MediaInfo.InfoKind.Text,
                        MediaInfo.InfoKind.Name);

                info.close();
                info.dispose();

                // Convert values, BitRate to Kbps, Duration to seconds
                Float bitRateFloat = new Float(bitRate) / 1000;
                int bitRateKbps = Math.round(bitRateFloat);
                int durationSecs = Integer.parseInt(duration) / 1000;

                //metaData.setFormat(format);
                metaData.setFrameRate(frameRate);
                metaData.setBitRate(bitRateKbps);
                metaData.setWidth(Integer.parseInt(width));
                metaData.setHeight(Integer.parseInt(height));
                metaData.setDuration(durationSecs);

            } catch (Exception ex) {
                //System.out.println("Failed: " + ex.getMessage());
                continue;
            }

            // Get filename minus extension and then extension minus filename
            String nameMovie = file.getName().substring(0, file.getName().lastIndexOf(".")).replaceAll("_", " ");
            String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1);

            // Hack for now
            metaData.setFormat(extension);

            // set initial title value based on filename. in case we can't lookup title from TMDb
            metaData.setTitle(nameMovie);

            // Lookup movie info from TMDb
            try {
                GeneralSettings.setApiKey("24498a4aee4e3f8205f29c0197261ce1");
                List<Movie> movies = Movie.search(nameMovie);
                if (movies != null && movies.size() > 0) {
                    Movie movie = movies.get(0);
                    Movie movieFull = Movie.getInfo(movie.getID());

                    // Get movie info
                    metaData.setTitle(movie.getName());
                    metaData.setDescription(movie.getOverview());
                    metaData.setRating(movie.getCertification());

                    int year = movieFull.getReleasedDate().getYear();
                    year = year + 1900;

                    metaData.setReleaseDate(year);

                    // Get movie genres
                    Set<Genre> genres = movieFull.getGenres();
                    for (Genre genre : genres) {
                        metaData.getGenres().add(genre.getName());
                    }

                    // Get cast of movie, actors, directors, etc.
                    for (CastInfo cast : movieFull.getCast()) {
                        // job is 'Actor' or 'Director'
                        String job = cast.getJob();
                        if (job.toLowerCase().equals("actor")) {
                            metaData.getActors().add(cast.getName());
                        }
                        if (job.toLowerCase().equals("director")) {
                            metaData.getDirectors().add(cast.getName());
                        }
                    }

                    // Get first poster image for cover and save it to the disk
                    MovieImages images = movie.getImages();
                    if (images.posters.size() > 0) {
                        MoviePoster poster = (MoviePoster) images.posters.toArray()[0];
                        URL imageUrl = poster.getImage(MoviePoster.Size.COVER);

                        // Get image filename
                        String imageFile = imageUrl.getFile().substring(imageUrl.getFile().lastIndexOf("/") + 1);

                        // Create images folder if doesn't exist
                        File imageDir = new File("images");
                        imageDir.mkdirs();

                        // Save image file
                        GeneralUtils.saveImage(imageUrl, "images/" + imageFile);

                        metaData.setPosterImage("images/" + imageFile);
                    }
                } else {
                    //System.out.println("Failed to get TMDb data: " + metaData.getTitle());
                }
            } catch (Exception ex) {
                //System.out.println("Failed: " + ex.getMessage());
            }

            // If we make it this far, then we have data to store for this movie in the Sqlite3 DB
            MovieDB.MovieInsert(metaData);
        }

        return count;
    }

}

class MovieFilter implements FilenameFilter {

    /**
    * Select only *.mp4, *.m4v files.
    *
    * @param dir the directory in which the file was found.
    *
    * @param name the name of the file
    *
    * @return true if and only if the name should be
    * included in the file list; false otherwise.
    */
    public boolean accept(File dir, String name) {
        if (new File(dir, name).isDirectory()) {
            return true;
        }
        name = name.toLowerCase();
        return name.endsWith(".mp4") || name.endsWith(".m4v");
    }
}