From 3eb233db33b89edbd18040020bc277a9974c11ab Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Fri, 15 Dec 2023 14:59:42 -0800 Subject: code cleanup + add inital crossplatform implementation --- src/main/java/Main.java | 287 +++++++++++------------------------------------- 1 file changed, 66 insertions(+), 221 deletions(-) (limited to 'src/main/java/Main.java') diff --git a/src/main/java/Main.java b/src/main/java/Main.java index c82ccb8..a544001 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -2,10 +2,12 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; +import java.lang.reflect.Array; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Scanner; import com.formdev.flatlaf.FlatIntelliJLaf; @@ -16,17 +18,16 @@ import org.jaudiotagger.tag.Tag; import org.jaudiotagger.tag.datatype.Artwork; import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.DefaultCaret; public class Main extends JFrame { final static String BLACKLIST = "blacklist.txt"; - final static String DOWNLOADED_DIR = "downloaded"; - final static String COMPLETED_DIR = "completed"; + private static String COMPLETED_DIR = "completed"; String textPath = ""; - String formats[] = {"maxresdefault.jpg", "mqdefault.jpg", "hqdefault.jpg"}; static JTextArea outputArea = new JTextArea(""); JPanel panel = new JPanel(); @@ -35,14 +36,14 @@ public class Main extends JFrame { JButton editButton = new JButton("Edit Tags"); JButton startButton = new JButton("Set .txt File"); JButton configureDownloadButton = new JButton("Configure Download File Interactively"); + JButton setOutputDirButton = new JButton("Set MP3 Output Directory"); JCheckBox defaultFileBox = new JCheckBox("Use Default songs.txt file"); JCheckBox useBlacklistBox = new JCheckBox("Use Blacklist.txt"); JProgressBar progressBar = new JProgressBar(); - JLabel title = new JLabel("YouTube to MP3 Auto Tagging [1]"); + JLabel title = new JLabel("YouTube to MP3 Auto Tagging [CrossPlatform]"); Boolean useBlacklist = false; Boolean readyState = false; Boolean useDefault = false; - FileUtility fileUtil = new FileUtility(); public Main() { initializeComponents(); @@ -55,166 +56,57 @@ public class Main extends JFrame { new Main().setVisible(true); } - /** - * Download and tag all songs in the text file - */ - private void downloadAndTag() { - ArrayList songs = fileUtil.txtToArrayList(textPath); - String timeAppend = ""; - boolean partFlag; - for (int i = 0; i < songs.size(); i++) { - try { - fileUtil.deleteAllFilesDir(DOWNLOADED_DIR); - - //Check if user's URL wants to download a part or full audio based on commas - ArrayList splitStamp = new ArrayList<>(Arrays.asList(songs.get(i).split(","))); - switch(splitStamp.size()){ - case 1: - downloadContentFull(songs.get(i)); - partFlag = false; - break; - case 2: - timeAppend = downloadContentPartial(splitStamp.get(0), splitStamp.get(1)); - partFlag = true; - break; - - default: - showError("Invalid Input: " + songs.get(i)+ - "\nReason: Invalid formatting. Please use the format: URL,START_TIME:END_TIME"); - return; - } - - String info[] = fileUtil.parseInfoJSON(fileUtil.jsonToString(fileUtil.findJsonFile(DOWNLOADED_DIR))); //title,uploader - String uploader = info[1]; - String title = info[0]; - String urlID = info[2]; - String imageUrl = "https://img.youtube.com/vi/" + urlID + "/"; - - // Remove blacklisted words if asked to - if (useBlacklist) { - System.out.println("Using blacklist. Removing blacklisted words from title and uploader"); - uploader = fileUtil.removeBlacklist(uploader, BLACKLIST); - title = fileUtil.removeBlacklist(title, BLACKLIST); - } - // Method downloads as MP4, then converts to MP3. It's faster - File mp4File = fileUtil.findFileType(DOWNLOADED_DIR ,"mp4"); - mp4Tomp3(mp4File); - - boolean taggingSuccessful = tagMp3InDir(uploader, title, imageUrl); - if(!taggingSuccessful) - return; - - // If user wants to download a part of the video, append the time to the title. Else just move the file - File mp3Path = fileUtil.findFileType(DOWNLOADED_DIR, "mp3"); - String destinationPath = partFlag ? COMPLETED_DIR+"/" + fileUtil.removeNonAlphaNumeric(title) + "[" + urlID + "]" + timeAppend + ".mp3" : - COMPLETED_DIR+"/" + fileUtil.removeNonAlphaNumeric(info[0]) + "[" + urlID + "].mp3"; - System.out.println(destinationPath); - fileUtil.moveFile(mp3Path.getAbsolutePath(), destinationPath); - - outputArea.setText(outputArea.getText() + "\n" + "Moved file to Completed Folder"); - System.out.println("Current Progress " + calculatePercentage(i + 1, songs.size())); - progressBar.setValue(calculatePercentage(i + 1, songs.size())); - } catch (Exception e) { - showError("Error occured while downloading and tagging. Check the logs for more info"); - e.printStackTrace(); + public static ArrayList txtToList(String fileName) { + ArrayList lines = new ArrayList(); + try { + FileReader fr = new FileReader(fileName); + BufferedReader br = new BufferedReader(fr); + String line; + while ((line = br.readLine()) != null) { + lines.add(line); } + br.close(); + } catch (Exception e) { + e.printStackTrace(); } + return lines; } /** - * Tag mp3 with title, uploader, and image - * @param uploader Uploader of the video - * @param title Title of the video - * @param imageUrl URL of to the thumbnail image + * Calculate the percentage for progress bar + * @param current The current number of songs downloaded + * @param total The total number of songs to download + * @return The percentage of songs downloaded */ - public boolean tagMp3InDir(String uploader, String title, String imageUrl) {//Tag mp3 file in downloaded directory - try { - AudioFile f = AudioFileIO.read(fileUtil.findFileType(DOWNLOADED_DIR, "mp3")); - Tag tag = f.getTag(); - System.out.println("Uploader: " + uploader); - System.out.println("Title: " + title); - tag.setField(FieldKey.ARTIST, uploader); - tag.setField(FieldKey.TITLE, title); - fileUtil.downloadImage(imageUrl, "img.jpg", formats); - Artwork cover = Artwork.createArtworkFromFile(new File("img.jpg")); - tag.addField(cover); - f.commit(); - fileUtil.deleteFile("img.jpg"); - } - catch(Exception e){ - showError("Error occured while tagging mp3. Check your program version"); - return false; - } - return true; - + private int calculatePercentage(int current, int total) {//Calculate the percentage when give numerator and denominator + double currentD = current; + double totalD = total; + return (int) ((currentD / totalD) * 100); } - /** - * Download part of YouTube URL in MP3 format - * @param url Youtube URL - */ - public static void downloadContentFull(String url) {//Download mp3 of youtube video using yt-dlp.exe. Ran from cmd - try { - - ProcessBuilder builder = new ProcessBuilder( - "yt-dlp.exe", - "-vU", - "--extract-audio", - "--audio-format", "mp3", - "--audio-quality", "0", - "--output", DOWNLOADED_DIR+"/%(title)s_%(id)s.mp3", - "--ffmpeg-location", "ffmpeg.exe", - "--write-info-json", - url - ); - builder.redirectErrorStream(true); - Process p = builder.start(); - relayConsole(p); - } catch (Exception e) { - JOptionPane.showMessageDialog(null, "An Error occured while downloading using" + - " yt-dlp", "Error", JOptionPane.ERROR_MESSAGE); - e.printStackTrace(); + public void downloadAndTag(){ + ArrayList songs = txtToList(textPath); + int totalSongs = songs.size(); + int songsProcessed = 0; + for(String line: songs){ + System.out.println(line); + if(line.contains(",")){ + String[] parts = line.split(","); + String url = parts[0]; + String stamp = parts[1]; + Downloader downloader = new Downloader(COMPLETED_DIR, outputArea); + downloader.download(url, stamp); + } + else{ + Downloader downloader = new Downloader(COMPLETED_DIR, outputArea); + downloader.download(line); + } + songsProcessed++; + progressBar.setValue(calculatePercentage(songsProcessed, totalSongs)); } - } - /** - * Download part of YouTube URL in MP4 format - * @param url Youtube URL - * @param stamp Time stamp in format HH:MM:SS-HH:MM:SS - * @return String of time stamp to be used on filename startTimeInSeconds to endTimeInSeconds - */ - public static String downloadContentPartial(String url, String stamp) { //Download mp3 of youtube video using yt-dlp.exe. Ran from cmd - System.out.println(url + " " + stamp); - ArrayList times = new ArrayList<>(Arrays.asList(stamp.split("-"))); - String startTime = times.get(0); - String endTime = times.get(1); - - // Time to start in seconds and time to end in seconds - int startSec = timestampToSeconds(startTime); - int endSec = timestampToSeconds(endTime); - try { - ProcessBuilder builder = new ProcessBuilder( - "yt-dlp.exe", - "-vU", - "-f","\"(bestvideo+bestaudio/best)[protocol!*=dash]\"", - "--external-downloader", "ffmpeg.exe", - "--external-downloader-args", "\"ffmpeg_i:-ss " + startSec + " -to " + endSec + "\"", - "--output", "downloaded/%(title)s_%(id)s.mp4", - "--write-info-json", - url - ); - builder.redirectErrorStream(true); - Process p = builder.start(); - relayConsole(p); - } catch (Exception e) { - JOptionPane.showMessageDialog(null, "An Error occured while downloading using" + - " yt-dlp", "Error", JOptionPane.ERROR_MESSAGE); - e.printStackTrace(); - } - return startSec + "to" + endSec; - } /** * Initialize all GUI components @@ -222,6 +114,7 @@ public class Main extends JFrame { private void initializeComponents() {//Initiate GUI components this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLocationRelativeTo(null); + this.setIconImage(new ImageIcon("icon.png").getImage()); this.add(panel); panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); scrollPane = new JScrollPane(outputArea); @@ -248,21 +141,32 @@ public class Main extends JFrame { panel.add(Box.createVerticalStrut(10)); panel.add(startButton); panel.add(defaultFileBox); + panel.add(useBlacklistBox); panel.add(Box.createVerticalStrut(8)); panel.add(scrollPane); panel.add(Box.createVerticalStrut(5)); panel.add(editButton); panel.add(Box.createVerticalStrut(5)); - panel.add(useBlacklistBox); - panel.add(Box.createVerticalStrut(8)); outputArea.setEditable(false); - // make configureDownloadButton centered configureDownloadButton.setAlignmentX(Component.CENTER_ALIGNMENT); panel.add(configureDownloadButton); - this.setSize(550, 450); this.setTitle("YTMP3Tagger"); + } + + public static String showTextFileChooser() { + javax.swing.JFileChooser chooser = new javax.swing.JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter("Text File", "txt", "text"); + chooser.setFileFilter(filter); + chooser.setDialogTitle("Select a text file"); + chooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + if (chooser.showOpenDialog(null) == javax.swing.JFileChooser.APPROVE_OPTION) { + return chooser.getSelectedFile().getAbsolutePath(); + } else { + return null; + } } /** @@ -273,7 +177,7 @@ public class Main extends JFrame { @Override public void actionPerformed(ActionEvent e) { File f = new File("songs.txt"); - if (f.exists() & !f.isDirectory() && !useDefault) { + if (f.exists() && !f.isDirectory() && !useDefault) { System.out.println("songs found"); textPath = "songs.txt"; showWarning("Default File has been set.\nMake sure you add a new line for each URL"); @@ -290,7 +194,7 @@ public class Main extends JFrame { readyState = false; outputArea.setText(outputArea.getText() + "\n" + "Cancelled. Please set a .txt file"); System.out.println("Cancelled. Please set a .txt file"); - startButton.setText("Set .txt file"); + startButton.setText("Set Download File"); } } }); @@ -313,7 +217,9 @@ public class Main extends JFrame { if (readyState == false) { outputArea.setText(outputArea.getText() + "\n" + "txt path has not been set. Launching chooserPane"); System.out.println(".txt path has not been set. Launching chooserPane"); - textPath = fileUtil.showTextFileChooser(); + String path = showTextFileChooser(); + textPath = path; + COMPLETED_DIR = path.substring(0, path.lastIndexOf("/")); try { if (!textPath.equals("")) { showWarning("File has been set.\nMake sure you add a new line for each URL"); @@ -366,72 +272,11 @@ public class Main extends JFrame { } } - /** - * Convert mp4 to mp3 using ffmpeg - * @param mp4File The mp4 file to convert - */ - public static void mp4Tomp3(File mp4File){ - try { - String mp4FileName = mp4File.getName(); - String mp3FileName = mp4FileName.substring(0, mp4FileName.length() - 4) + ".mp3"; - ProcessBuilder builder = new ProcessBuilder( - "cmd.exe", "/c", "ffmpeg -i \"" + mp4File.getAbsolutePath() + "\" \""+DOWNLOADED_DIR+"/" + mp3FileName+"\"" - ); - builder.redirectErrorStream(true); - Process p = builder.start(); - relayConsole(p); - p.waitFor(); - System.out.println("Conversion of MP4 to MP3 complete"); - - } - catch (Exception e){ - e.printStackTrace(); - } - - } - - /** - * Relays the console output from the CMD to the outputArea - * @param p The process to relay to the outputArea from - */ - public static void relayConsole(Process p) { - BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); - String cmd_line; - while (true) { - try { - cmd_line = r.readLine(); - if (cmd_line == null) { - break; - } - outputArea.setText(outputArea.getText() + "\n" + cmd_line); - System.out.println(cmd_line); - } - catch (IOException e) { - System.out.println("Error while relaying from CMD"); - } - } - } - - /** - * Calculate the percentage for progress bar - * @param current The current number of songs downloaded - * @param total The total number of songs to download - * @return The percentage of songs downloaded - */ - private int calculatePercentage(int current, int total) {//Calculate the percentage when give numerator and denominator - double currentD = current; - double totalD = total; - return (int) ((currentD / totalD) * 100); - } /** * Create the directories for the downloaded and completed files */ public void createDirectories(){ - File f = new File(DOWNLOADED_DIR); - if (!f.exists()) { - f.mkdir(); - } File f2 = new File(COMPLETED_DIR); if (!f2.exists()) { f2.mkdir(); -- cgit v1.2.3