package moviescraper.doctord.controller; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import javax.swing.JOptionPane; import org.apache.commons.io.FilenameUtils; import moviescraper.doctord.controller.siteparsingprofile.SiteParsingProfile; import moviescraper.doctord.model.MovieFilenameFilter; import moviescraper.doctord.model.preferences.GuiSettings; import moviescraper.doctord.view.GUIMain; public class PlayMovieAction implements ActionListener { private final GUIMain guiMain; /** * @param guiMain */ public PlayMovieAction(GUIMain guiMain) { this.guiMain = guiMain; } /** * Play the selected movie (and any associated movies that are stacked in case the movie file is split into multiple pieces) * in the user's preferred external media player. If no external media player is known, the program * will prompt the user to set one before playing the file. */ @Override public void actionPerformed(ActionEvent arg0) { for(int movieNumberInList = 0; movieNumberInList < this.guiMain.getCurrentlySelectedMovieFileList().size(); movieNumberInList++) { if (this.guiMain.getCurrentlySelectedMovieFileList() != null) { File currentMovieFile = this.guiMain.getCurrentlySelectedMovieFileList().get(movieNumberInList); if(currentMovieFile.exists()) { //Get the movie file from within the directory if(currentMovieFile.isDirectory()) { File[] movieFilesInFolder = currentMovieFile.listFiles(new MovieFilenameFilter()); if(movieFilesInFolder.length > 0) { //Filter out the trailer files and then sort the list so we play any stacked movies in sequential order List<File> fileList = new LinkedList<>(Arrays.asList(movieFilesInFolder)); fileList = filterFiles(fileList); Collections.sort(fileList); playItems(fileList, arg0); } } //We are selecting an actual movie file. Get all stacked movie files and play them in alphabetical order. Remove trailer files as well from our playlist else{ List<File> stackedMovieFiles = new LinkedList<>(); File currentDirectory = this.guiMain.getCurrentlySelectedMovieFileList().get(movieNumberInList).getParentFile(); String currentlySelectedMovieFileWihoutStackSuffix = SiteParsingProfile.stripDiscNumber(FilenameUtils.removeExtension(this.guiMain.getCurrentlySelectedMovieFileList().get(movieNumberInList).getName())); if(currentDirectory != null) { for(File currentFile : currentDirectory.listFiles(new MovieFilenameFilter())) { String currentFileNameWithoutStackSuffix = SiteParsingProfile.stripDiscNumber(FilenameUtils.removeExtension(currentFile.getName())); if(currentFile.isFile() && currentFileNameWithoutStackSuffix.equals(currentlySelectedMovieFileWihoutStackSuffix)) { stackedMovieFiles.add(currentFile); } } } Collections.sort(stackedMovieFiles); stackedMovieFiles = filterFiles(stackedMovieFiles); playItems(stackedMovieFiles,arg0); } } } } } private void playItems(List<File> fileList, ActionEvent arg0) { String pathToExternalMediaPlayer = GuiSettings.getInstance().getPathToExternalMediaPlayer(); if(pathToExternalMediaPlayer != null) openMediaFilesInExternalProgram(fileList,pathToExternalMediaPlayer); //We don't know what program to play the movies in, so let's ask the user for a program else { Object[] options = {"Yes", "No" }; int optionPicked = JOptionPane.showOptionDialog(guiMain.getFrmMoviescraper(), "No external media player set. Would you like to set one now?", "Configure External Media Player", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if(optionPicked == 0) { ChooseExternalMediaPlayerAction chooseExternalMediaPlayerAction = new ChooseExternalMediaPlayerAction(guiMain); chooseExternalMediaPlayerAction.actionPerformed(arg0); pathToExternalMediaPlayer = GuiSettings.getInstance().getPathToExternalMediaPlayer(); //now that the user has successfully set a path to the media player, let's play it if(pathToExternalMediaPlayer != null) openMediaFilesInExternalProgram(fileList,pathToExternalMediaPlayer); } } } /** * Removes the trailer files from a fileList so that we don't enqueue them in our playlist **/ private List<File> filterFiles(List<File> fileList){ int listSize = fileList.size(); for(int i = listSize-1; i >= 0; i--) { String currentFileBaseName = FilenameUtils.getBaseName(fileList.get(i).toString()); if(currentFileBaseName.endsWith("-trailer")) fileList.remove(i); } return fileList; } /** * Opens the files passed in by fileList using the program specified at the path pathToPlayerProgram * @param fileList - list of files to play (multiple files may be passed in so that we can play multipart movie files) * @param pathToPlayerProgram - full system path of the program to use to open the movie files */ private void openMediaFilesInExternalProgram(List<File> fileList, String pathToPlayerProgram) { int i = 0; String args = " "; String[] cmdarray = new String[fileList.size()+1]; cmdarray[i++] = pathToPlayerProgram; for (File file : fileList) { args += "\"" + file.getAbsolutePath() + "\" "; cmdarray[i++] = file.getAbsolutePath(); } try { System.out.println("Running command to open External Media Player: \"" + pathToPlayerProgram + "\"" + args); Runtime.getRuntime().exec(cmdarray); } catch (Exception e1) { e1.printStackTrace(); System.err.println("Error while opening external media player: " + e1.getMessage()); JOptionPane.showMessageDialog(guiMain.getFrmMoviescraper(), e1.getMessage(), "Error opening external media player", JOptionPane.ERROR_MESSAGE); } } }