From 776d40ffdc9d859d74503b19d3666a1249efbb8c Mon Sep 17 00:00:00 2001 From: randompooper <53050756+randompooper@users.noreply.github.com> Date: Tue, 16 Jul 2019 10:04:39 +0000 Subject: [PATCH 1/3] Fix invalid timestamps (caused ffmpeg to fail sometimes) Example of invalid timestamp produced: 00:02:60.354 Here can't be more than 60 seconds --- src/zone/arctic/ytpplus/TimeStamp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zone/arctic/ytpplus/TimeStamp.java b/src/zone/arctic/ytpplus/TimeStamp.java index f10e8d8..39cd534 100644 --- a/src/zone/arctic/ytpplus/TimeStamp.java +++ b/src/zone/arctic/ytpplus/TimeStamp.java @@ -37,7 +37,7 @@ public TimeStamp(double l) { this.HOURS = (int)hours; this.MINUTES = (int)minutes; - this.SECONDS = seconds + (millis/1000); + this.SECONDS = (int)seconds + (millis/1000); } From 2590101d77aec364c846791d347afb70bafaf595 Mon Sep 17 00:00:00 2001 From: randompooper <53050756+randompooper@users.noreply.github.com> Date: Tue, 16 Jul 2019 10:48:32 +0000 Subject: [PATCH 2/3] Refactoring, fixes and performance improvements - Use fast (inexact) seek to process videos faster - Parallelize clip creation for a faster pooping process - Possibly fix issues with ffmpeg failing (file name issues, unquoting, quoting where necessary, etc) - Fix incompatibility with Linux systems (removed quotes where unnecessary) - Allow all media formats supported by ffmpeg (it is still converted to mp4 though) - Halved chance of squidward effect being applied - Mostly minor refactoring around the code (add pseudorandom prefixes to temporary files, reduce concatenation frequency, etc) --- src/zone/arctic/ytpplus/EffectsFactory.java | 322 +++++++++----------- src/zone/arctic/ytpplus/TimeStamp.java | 16 +- src/zone/arctic/ytpplus/Utilities.java | 86 +++--- src/zone/arctic/ytpplus/YTPGenerator.java | 68 ++--- 4 files changed, 233 insertions(+), 259 deletions(-) diff --git a/src/zone/arctic/ytpplus/EffectsFactory.java b/src/zone/arctic/ytpplus/EffectsFactory.java index cba599e..a1f52e7 100644 --- a/src/zone/arctic/ytpplus/EffectsFactory.java +++ b/src/zone/arctic/ytpplus/EffectsFactory.java @@ -13,84 +13,54 @@ import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; - + public class EffectsFactory { - + public Utilities toolBox; - + public EffectsFactory(Utilities utilities) { this.toolBox = utilities; } - + public String pickSound() { - FilenameFilter fileFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - String lowercase = name.toLowerCase(); - if (lowercase.endsWith(".mp3")) - return true; - else - return false; - } - }; - File[] files = new File(toolBox.SOUNDS).listFiles(fileFilter); + File[] files = new File(toolBox.SOUNDS).listFiles(); Random rand = new Random(); File file = files[rand.nextInt(files.length)]; - return file.getName(); + return file.getPath(); } public String pickSource() { - FilenameFilter fileFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - String lowercase = name.toLowerCase(); - if (lowercase.endsWith(".mp4")) - return true; - else - return false; - } - }; - File[] files = new File(toolBox.SOURCES).listFiles(fileFilter); + File[] files = new File(toolBox.SOURCES).listFiles(); Random rand = new Random(); File file = files[rand.nextInt(files.length)]; - return file.getName(); + return file.getPath(); } - + public String pickMusic() { - FilenameFilter fileFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - String lowercase = name.toLowerCase(); - if (lowercase.endsWith(".mp3")) - return true; - else - return false; - } - }; - File[] files = new File(toolBox.MUSIC).listFiles(fileFilter); + File[] files = new File(toolBox.MUSIC).listFiles(); Random rand = new Random(); File file = files[rand.nextInt(files.length)]; - return file.getName(); + return file.getPath(); } - + /* EFFECTS */ public void effect_RandomSound(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String randomSound = pickSound(); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" - + " -i "+ toolBox.SOUNDS + randomSound - + " -filter_complex \"[1:a]volume=1,apad[A];[0:a][A]amerge[out]\"" + + " -i " + temp.getPath() + + " -i \"" + randomSound + "\"" + + " -filter_complex [1:a]volume=1,apad[A];[0:a][A]amerge[out]" + " -ac 2" //+ " -c:v copy" - + + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + + " -map 0:v" + " -map [out]" + " -y " + video; @@ -99,42 +69,44 @@ public void effect_RandomSound(String video){ int exitValue = executor.execute(cmdLine); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } + } public void effect_RandomSoundMute(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { String randomSound = pickSound(); - String soundLength = toolBox.getLength(toolBox.SOUNDS+randomSound); + String soundLength = toolBox.getLength(randomSound); System.out.println("Doing a mute now. " + randomSound + " length: " + soundLength + "."); //Scanner userInput = new Scanner(System.in); //String input = userInput.nextLine(); - + //if (!input.isEmpty()) { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); - File temp2 = new File(toolBox.TEMP + "temp2.mp4"); + File temp = new File(toolBox.getTempVideoName()); + File temp2 = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); if (temp2.exists()) temp2.delete(); String command1 = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af \"volume=0\" -y " + toolBox.TEMP + "temp2.mp4"; + + " -af volume=0 -y " + temp2.getPath(); String command2 = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp2.mp4" - + " -i \"" + toolBox.SOUNDS +""+randomSound+"\"" - + " -to "+soundLength + + " -i " + temp2.getPath() + + " -i \"" + randomSound + "\"" + + " -to " + soundLength + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter_complex \"[1:a]volume=1,apad[A]; [0:a][A]amerge[out]\" -ac 2 -map 0:v -map [out] -y " + video; + + " -filter_complex [1:a]volume=1,apad[A];[0:a][A]amerge[out] -ac 2 -map 0:v -map [out] -y " + video; //String command1 = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; CommandLine cmdLine = CommandLine.parse(command1); + System.out.println("Command: " + cmdLine); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); cmdLine = CommandLine.parse(command2); + System.out.println("Command: " + cmdLine); executor = new DefaultExecutor(); exitValue = executor.execute(cmdLine); @@ -144,24 +116,24 @@ public void effect_RandomSoundMute(String video){ //System.out.println("Did a mute sfx. Type anything to verify."); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } + } public void effect_Reverse(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); - File temp2 = new File(toolBox.TEMP + "temp2.mp4"); + File temp = new File(toolBox.getTempVideoName()); + File temp2 = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); if (temp2.exists()) temp2.delete(); String command1 = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4 -map 0" + + " -i " + temp.getPath() + " -map 0" + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af \"areverse\" -y " + toolBox.TEMP + "temp2.mp4"; + + " -af areverse -y " + temp2.getPath(); String command2 = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp2.mp4" + + " -i " + temp2.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -vf reverse -y " + video; @@ -169,26 +141,26 @@ public void effect_Reverse(String video){ CommandLine cmdLine = CommandLine.parse(command1); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); - + cmdLine = CommandLine.parse(command2); executor = new DefaultExecutor(); exitValue = executor.execute(cmdLine); - + temp.delete(); temp2.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } - - + } + + public void effect_SpeedUp(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -filter:v setpts=0.5*PTS -filter:a atempo=2.0 -y " + video; @@ -197,17 +169,17 @@ public void effect_SpeedUp(String video){ int exitValue = executor.execute(cmdLine); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } - + } + public void effect_SlowDown(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -filter:v setpts=2*PTS -filter:a atempo=0.5 -y " + video; @@ -218,17 +190,17 @@ public void effect_SlowDown(String video){ } catch (Exception ex) { System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex); } - } - + } + public void effect_Chorus(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -af chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3 -y " + video; @@ -237,17 +209,17 @@ public void effect_Chorus(String video){ int exitValue = executor.execute(cmdLine); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } + } public void effect_Vibrato(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -af vibrato=f=7.0:d=0.5 -y " + video; @@ -256,17 +228,17 @@ public void effect_Vibrato(String video){ int exitValue = executor.execute(cmdLine); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } - + } + public void effect_LowPitch(String video) { System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -filter:v setpts=2*PTS -af asetrate=44100*0.5,aresample=44100 -y " + video; @@ -281,11 +253,11 @@ public void effect_HighPitch(String video) { System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - File temp = new File(toolBox.TEMP + "temp.mp4"); + File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); String command = toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4" + + " -i " + temp.getPath() + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -filter:v setpts=0.5*PTS -af asetrate=44100*2,aresample=44100 -y " + video; @@ -295,22 +267,21 @@ public void effect_HighPitch(String video) { temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } - + public void effect_Dance(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - - File temp = new File(toolBox.TEMP + "temp.mp4"); //og file - File temp2 = new File(toolBox.TEMP + "temp2.mp4"); //1st cut - File temp3 = new File(toolBox.TEMP + "temp3.mp4"); //backwards (silent - File temp4 = new File(toolBox.TEMP + "temp4.mp4"); //forwards (silent - File temp5 = new File(toolBox.TEMP + "temp5.mp4"); //backwards & forwards concatenated - File temp6 = new File(toolBox.TEMP + "temp6.mp4"); //backwards & forwards concatenated - File temp7 = new File(toolBox.TEMP + "temp7.mp4"); //backwards & forwards concatenated - + + File temp = new File(toolBox.getTempVideoName()); //og file + File temp2 = new File(toolBox.getTempVideoName()); //1st cut + File temp3 = new File(toolBox.getTempVideoName()); //backwards (silent + File temp4 = new File(toolBox.getTempVideoName()); //forwards (silent + File temp5 = new File(toolBox.getTempVideoName()); //backwards & forwards concatenated + File temp6 = new File(toolBox.getTempVideoName()); //backwards & forwards concatenated + // final result is backwards & forwards concatenated with music - + if (in.exists()) in.renameTo(temp); if (temp2.exists()) @@ -323,11 +294,9 @@ public void effect_Dance(String video){ temp5.delete(); if (temp6.exists()) temp6.delete(); - if (temp7.exists()) - temp7.delete(); - + String randomSound = pickMusic(); - + /* lib/ffmpeg -i stu.mp4 -map 0 -ar 44100 -to 00:00:00.5 -vf "scale=640x480,setsar=1:1" -an -y " + toolBox.TEMP + "temp2.mp4 lib/ffmpeg -i " + toolBox.TEMP + "temp2.mp4 -map 0 -ar 44100 -vf "reverse,scale=640x480,setsar=1:1" -y " + toolBox.TEMP + "temp3.mp4 @@ -337,158 +306,161 @@ public void effect_Dance(String video){ lib/ffmpeg -i " + toolBox.TEMP + "temp6.mp4 -i music/dancemusic.mp3 -c:v libx264 -map 0:v:0 -map 1:a:0 -vf "scale=640x480,setsar=1:1,fps=fps=30" -shortest -y " + toolBox.TEMP + "temp7.mp4 */ ArrayList commands = new ArrayList(); - int randomTime = randomInt(3,9); - int randomTime2 = randomInt(0,1); + int randomTime = toolBox.randomInt(3,9); + int randomTime2 = toolBox.randomInt(0,1); commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4 -map 0"// -c:v copy" + + " -i " + temp.getPath() + " -map 0"// -c:v copy" + " -ar 44100" + " -to 00:00:0"+randomTime2+"." + randomTime + " -vf scale=640x480,setsar=1:1" + " -an" - + " -y " + toolBox.TEMP + "temp2.mp4"); - + + " -y " + temp2.getPath()); + commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp2.mp4 -map 0"// -c:v copy" + + " -i " + temp2.getPath() + " -map 0"// -c:v copy" + " -ar 44100" + " -vf reverse,scale=640x480,setsar=1:1" - + " -y " + toolBox.TEMP + "temp3.mp4"); - + + " -y " + temp3.getPath()); + commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp3.mp4" + + " -i " + temp3.getPath() + " -ar 44100" + " -vf reverse,scale=640x480,setsar=1:1" - + " -y " + toolBox.TEMP + "temp4.mp4"); - + + " -y " + temp4.getPath()); + commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp3.mp4" - + " -i " + toolBox.TEMP + "temp4.mp4" - + " -filter_complex \"[0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0]concat=n=8:v=1[outv]\"" - + " -map \"[outv]\"" + + " -i " + temp3.getPath() + + " -i " + temp4.getPath() + + " -filter_complex [0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0]concat=n=8:v=1[outv]" + + " -map [outv]" + " -c:v libx264 -shortest" - + " -y " + toolBox.TEMP + "temp5.mp4"); - + + " -y " + temp5.getPath()); + commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp5.mp4" + + " -i " + temp5.getPath() + " -map 0" + " -ar 44100" - + " -vf \"setpts=0.5*PTS,scale=640x480,setsar=1:1\"" - + " -af \"atempo=2.0\"" + + " -vf setpts=0.5*PTS,scale=640x480,setsar=1:1" + + " -af atempo=2.0" + " -shortest" - + " -y " + toolBox.TEMP + "temp6.mp4"); - + + " -y " + temp6.getPath()); + commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp6.mp4" - + " -i " + toolBox.MUSIC + randomSound + + " -i " + temp6.getPath() + + " -i \"" + randomSound + "\"" + " -c:v libx264" + " -map 0:v:0 -map 1:a:0" - + " -vf \"scale=640x480,setsar=1:1,fps=fps=30\"" + + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -shortest" + " -y " + video); - + //String command = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; for (String command : commands) { CommandLine cmdLine = CommandLine.parse(command); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); } - + temp.delete(); temp2.delete(); temp3.delete(); temp4.delete(); temp5.delete(); temp6.delete(); - temp7.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } - + } + public void effect_Squidward(String video){ System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); - - File temp = new File(toolBox.TEMP + "temp.mp4"); //og file - + File temp = new File(toolBox.getTempVideoName()); //og file + int pictureNum = toolBox.randomInt(); + String picturePrefix = toolBox.TEMP + pictureNum + "-"; + // final result is backwards & forwards concatenated with music - + if (in.exists()) in.renameTo(temp); - + ArrayList commands = new ArrayList(); commands.add(toolBox.FFMPEG - + " -i " + toolBox.TEMP + "temp.mp4"// -c:v copy" - + " -vf \"select=gte(n\\,1)\"" + + " -i " + temp.getPath() // -c:v copy" + + " -vf select=gte(n\\,1)" + " -vframes 1" - + " -y " + toolBox.TEMP + "squidward0.png"); - - for (int i=1; i<6; i++) { + + " -y " + picturePrefix + "squidward0.png"); + + for (int i=1; i<6; i++) { String effect = ""; - int random = randomInt(0,6); + int random = toolBox.randomInt(0,6); switch (random) { - case 0: + case 0: effect = " -flop"; break; case 1: effect = " -flip"; break; case 2: - effect = " -implode -" + randomInt(1,3); + effect = " -implode -" + toolBox.randomInt(1,3); break; case 3: - effect = " -implode " + randomInt(1,3); + effect = " -implode " + toolBox.randomInt(1,3); break; case 4: - effect = " -swirl " + randomInt(1,180); + effect = " -swirl " + toolBox.randomInt(1,180); break; case 5: - effect = " -swirl -" + randomInt(1,180); + effect = " -swirl -" + toolBox.randomInt(1,180); break; case 6: effect = " -channel RGB -negate"; break; //case 7: - // effect = " -virtual-pixel Black +distort Cylinder2Plane " + randomInt(1,90); + // effect = " -virtual-pixel Black +distort Cylinder2Plane " + toolBox.randomInt(1,90); // break; } commands.add(toolBox.MAGICK - + " convert " + toolBox.TEMP + "squidward0.png" + + " convert " + picturePrefix + "squidward0.png" + effect - + " " + toolBox.TEMP + "squidward" + i + ".png" + + " " + picturePrefix + "squidward" + i + ".png" ); } commands.add(toolBox.MAGICK - + " convert -size 640x480 canvas:black " + toolBox.TEMP + "black.png"); - - if (new File(toolBox.TEMP + "concatsquidward.txt").exists()) - new File(toolBox.TEMP + "concatsquidward.txt").delete(); - PrintWriter writer = new PrintWriter(toolBox.TEMP + "concatsquidward.txt", "UTF-8"); + + " convert -size 640x480 canvas:black " + picturePrefix + "black.png"); + + File squidwardScript = new File(picturePrefix + "concatsquidward.txt"); + if (squidwardScript.exists()) + squidwardScript.delete(); + PrintWriter writer = new PrintWriter(squidwardScript, "UTF-8"); writer.write - ("file 'squidward0.png'\n" + + ("file " + pictureNum + "-squidward0.png\n" + "duration 0.467\n" + - "file 'squidward1.png'\n" + + "file " + pictureNum + "-squidward1.png\n" + "duration 0.434\n" + - "file 'squidward2.png'\n" + + "file " + pictureNum + "-squidward2.png\n" + "duration 0.4\n" + - "file 'black.png'\n" + + "file " + pictureNum + "-black.png'\n" + "duration 0.834\n" + - "file 'squidward3.png'\n" + + "file " + pictureNum + "-squidward3.png\n" + "duration 0.467\n" + - "file 'squidward4.png'\n" + + "file " + pictureNum + "-squidward4.png\n" + "duration 0.4\n" + - "file 'squidward5.png'\n" + + "file " + pictureNum + "-squidward5.png\n" + "duration 0.467"); writer.close(); - + /* Using "\\" slashes breaks concat (and thus squidward) on + * Windows + */ commands.add(toolBox.FFMPEG + " -f concat" - + " -i " + toolBox.TEMP + "concatsquidward.txt" + + " -i " + picturePrefix + "concatsquidward.txt" + " -i " + toolBox.RESOURCES + "squidward/music.wav" + " -map 0:v:0 -map 1:a:0" - + " -vf \"scale=640x480,setsar=1:1\"" + + " -vf scale=640x480,setsar=1:1" + " -pix_fmt yuv420p" + " -y " + video); - + //String command = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; for (String command : commands) { System.out.println("Executing: " + command); @@ -496,17 +468,13 @@ public void effect_Squidward(String video){ DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); } - + temp.delete(); for (int i=0; i<6; i++) { - new File(toolBox.TEMP + "squidward"+i+".png").delete(); + new File(picturePrefix + "squidward"+i+".png").delete(); } - new File(toolBox.TEMP + "black.png").delete(); - new File(toolBox.TEMP + "concatsquidward.txt").delete(); + new File(picturePrefix + "black.png").delete(); + squidwardScript.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} - } - - public static int randomInt(int min, int max) { - return new Random().nextInt((max - min) + 1) + min; } } diff --git a/src/zone/arctic/ytpplus/TimeStamp.java b/src/zone/arctic/ytpplus/TimeStamp.java index 39cd534..10427cc 100644 --- a/src/zone/arctic/ytpplus/TimeStamp.java +++ b/src/zone/arctic/ytpplus/TimeStamp.java @@ -16,14 +16,14 @@ public class TimeStamp { private int HOURS; private int MINUTES; private double SECONDS; - + public TimeStamp(String time) { String[] parts = time.split(":"); this.HOURS = Integer.parseInt(parts[0]); this.MINUTES = Integer.parseInt(parts[1]); this.SECONDS = Double.parseDouble(parts[2]); } - + public TimeStamp(double l) { double ms = l*1000; @@ -34,17 +34,17 @@ public TimeStamp(double l) { double minutes = x % 60; x /= 60; double hours = x % 24; - + this.HOURS = (int)hours; this.MINUTES = (int)minutes; this.SECONDS = (int)seconds + (millis/1000); - + } - + public double getLengthSec() { return SECONDS + (MINUTES*60) + (HOURS*60*60); } - + public int getHours() { return HOURS; } @@ -54,13 +54,13 @@ public int getMinutes() { public double getSeconds() { return SECONDS; } - + public void getDeets() { System.out.println("HOURS: " + this.HOURS); System.out.println("MIN: " + this.MINUTES); System.out.println("SEC: " + this.SECONDS); } - + public String getTimeStamp() { return this.HOURS + ":" + this.MINUTES + ":" + this.SECONDS; } diff --git a/src/zone/arctic/ytpplus/Utilities.java b/src/zone/arctic/ytpplus/Utilities.java index d9b5872..5287cf8 100644 --- a/src/zone/arctic/ytpplus/Utilities.java +++ b/src/zone/arctic/ytpplus/Utilities.java @@ -3,6 +3,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; +import java.util.Random; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; @@ -12,16 +13,17 @@ * @author benb */ public class Utilities { - + public String FFPROBE; public String FFMPEG; public String MAGICK; - + public String TEMP = ""; public String SOURCES = ""; public String SOUNDS = ""; public String MUSIC = ""; public String RESOURCES = ""; + private Random random = new Random(); /** * Return the length of a video (in seconds) @@ -32,42 +34,40 @@ public class Utilities { public String getVideoLength(String video){ try { Runtime rt = Runtime.getRuntime(); - Process proc = rt.exec(FFPROBE + Process proc = rt.exec(FFPROBE + " -v error" + " -sexagesimal" + " -show_entries format=duration" + " -of default=noprint_wrappers=1:nokey=1" + " \"" + video + "\""); - BufferedReader stdInput = new BufferedReader(new - InputStreamReader(proc.getInputStream())); + BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; - Thread.sleep(100); + proc.waitFor(); while ((s = stdInput.readLine()) != null) { return s; } } catch (Exception ex) {ex.printStackTrace(); return "";} return ""; } - + public String getLength(String file) { try { Runtime rt = Runtime.getRuntime(); - Process proc = rt.exec(FFPROBE - + " -i " + file + Process proc = rt.exec(FFPROBE + + " -i \"" + file + "\"" + " -show_entries format=duration" - + " -v quiet" - + " -of csv=\"p=0\""); - BufferedReader stdInput = new BufferedReader(new - InputStreamReader(proc.getInputStream())); + + " -v error" + + " -of csv=p=0"); + BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; - Thread.sleep(100); + proc.waitFor(); while ((s = stdInput.readLine()) != null) { return s; } } catch (Exception ex) {System.out.println(ex); return "";} return ""; } - + /** * Snip a video file between the start and end time, and save it to an output file. * @@ -78,15 +78,16 @@ public String getLength(String file) { */ public void snipVideo(String video, TimeStamp startTime, TimeStamp endTime, String output){ try { - String command1 = FFMPEG - + " -i " + video + String command1 = FFMPEG + " -ss " + startTime.getTimeStamp() + + " -i \"" + video + "\"" + " -to " + endTime.getTimeStamp() + + " -copyts" + " -ac 1" + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -y" - + " " + output + ".mp4"; + + " " + output; CommandLine cmdLine = CommandLine.parse(command1); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); @@ -95,8 +96,8 @@ public void snipVideo(String video, TimeStamp startTime, TimeStamp endTime, Stri System.exit(0); } } catch (Exception ex) {System.out.println(ex);} - } - + } + /** * Copies a video and encodes it in the proper format without changes. * @@ -105,14 +106,13 @@ public void snipVideo(String video, TimeStamp startTime, TimeStamp endTime, Stri */ public void copyVideo(String video, String output){ try { - String command1 = FFMPEG - + " -i " + video - + " -ar 44100" + String command1 = FFMPEG + + " -i \"" + video + "\"" + " -ac 1" - //+ " -filter:v fps=fps=30,setsar=1:1" + + " -ar 44100" + " -vf scale=640x480,setsar=1:1,fps=fps=30" + " -y" - + " " + output + ".mp4"; + + " " + output; CommandLine cmdLine = CommandLine.parse(command1); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); @@ -121,8 +121,8 @@ public void copyVideo(String video, String output){ System.exit(0); } } catch (Exception ex) {System.out.println(ex);} - } - + } + /** * Concatenate videos by count * @@ -132,19 +132,19 @@ public void copyVideo(String video, String output){ public void concatenateVideo(int count, String out ) { try { File export = new File(out); - + if (export.exists()) export.delete(); - + String command1 = FFMPEG; - + for (int i=0; i sourceList = new ArrayList(); public volatile boolean done = false; public volatile double doneCount = 0; - + public YTPGenerator(String output) { this.OUTPUT_FILE = output; //configurate(); } - + public YTPGenerator(String output, double min, double max) { this.OUTPUT_FILE = output; this.MIN_STREAM_DURATION = min; @@ -84,7 +84,7 @@ public YTPGenerator(String output, double min, double max, int maxclips) { this.MAX_CLIPS = maxclips; //configurate(); } - + public void setMaxClips(int clips) { this.MAX_CLIPS = clips; } @@ -94,7 +94,7 @@ public void setMinDuration(double min) { public void setMaxDuration(double max) { this.MAX_STREAM_DURATION = max; } - + public void addSource(String sourceName) { sourceList.add(sourceName); } @@ -114,7 +114,7 @@ public void run() { System.out.println("No sources added..."); return; } - + System.out.println("poop_1"); File out = new File(OUTPUT_FILE); if (out.exists()) { @@ -124,9 +124,8 @@ public void run() { try { PrintWriter writer = new PrintWriter(toolBox.TEMP+"concat.txt", "UTF-8"); - for (int i = 0; i < MAX_CLIPS; i++) { - doneCount = (double) i/MAX_CLIPS; - String sourceToPick = sourceList.get(randomInt(0, sourceList.size() - 1)); + IntStream.range(0, MAX_CLIPS).parallel().forEach(i -> { + String sourceToPick = sourceList.get(toolBox.randomInt(0, sourceList.size() - 1)); System.out.println(sourceToPick); System.out.println(toolBox.getLength(sourceToPick)); TimeStamp boy = new TimeStamp(Double.parseDouble(toolBox.getLength(sourceToPick))); @@ -137,16 +136,16 @@ public void run() { TimeStamp endOfClip = new TimeStamp(startOfClip.getLengthSec() + randomDouble(MIN_STREAM_DURATION, MAX_STREAM_DURATION)); System.out.println("Beginning of clip " + i + ": " + startOfClip.getTimeStamp()); System.out.println("Ending of clip " + i + ": " + endOfClip.getTimeStamp() + ", in seconds: "); - if (randomInt(0, 15) == 15 && insertTransitionClips==true) { + String clipToWorkWith = toolBox.TEMP+"video" + i + ".mp4"; + if (toolBox.randomInt(0, 15) == 15 && insertTransitionClips==true) { System.out.println("Tryina use a diff source"); - toolBox.copyVideo(toolBox.SOURCES + effectsFactory.pickSource(), toolBox.TEMP+"video" + i); + toolBox.copyVideo(effectsFactory.pickSource(), clipToWorkWith); } else { - toolBox.snipVideo(sourceToPick, startOfClip, endOfClip, toolBox.TEMP+"video" + i); + toolBox.snipVideo(sourceToPick, startOfClip, endOfClip, clipToWorkWith); } //Add a random effect to the video - int effect = randomInt(0, 16); + int effect = toolBox.randomInt(0, 16); System.out.println("STARTING EFFECT ON CLIP " + i + " EFFECT" + effect); - String clipToWorkWith = toolBox.TEMP+"video" + i + ".mp4"; switch (effect) { case 1: //random sound @@ -191,14 +190,15 @@ public void run() { effectsFactory.effect_Dance(clipToWorkWith); break; case 11: - if (effect11==true) + if (effect11==true && toolBox.randomInt(0, 99) < 50) effectsFactory.effect_Squidward(clipToWorkWith); break; default: + //toolBox.convertVideo(clipToWorkWith); break; } - - } + doneCount += 1.0 / MAX_CLIPS; + }); for (int i = 0; i < MAX_CLIPS; i++) { if (new File(toolBox.TEMP+"video" + i + ".mp4").exists()) { writer.write("file 'video" + i + ".mp4'\n"); //writing to same folder @@ -211,35 +211,29 @@ public void run() { } catch (Exception ex) { ex.printStackTrace(); } - //for (int i=0; i<100; i++) { cleanUp(); rmDir(new File(toolBox.TEMP)); done = true; } }; vidThread.start(); - + } - - + + public boolean isDone() { return done; } - + public static double randomDouble(double min, double max) { double finalVal = -1; while (finalVal<0) { double x = (Math.random() * ((max - min) + 0)) + min; - finalVal=Math.round(x * 100.0) / 100.0; + finalVal=Math.round(x * 100.0) / 100.0; } return finalVal; } - - public static int randomInt(int min, int max) { - return new Random().nextInt((max - min) + 1) + min; - } - - + public void cleanUp() { //Create concatenation text file File text = new File(toolBox.TEMP+"concat.txt"); @@ -247,7 +241,7 @@ public void cleanUp() { text.delete(); File mp4 = new File(toolBox.TEMP + "temp.mp4"); if (mp4.exists()) - mp4.delete(); + mp4.delete(); for (int i=0; i Date: Thu, 18 Jul 2019 02:47:11 +0000 Subject: [PATCH 3/3] So long quotes! - construct command lines using arrays instead of string concatenation to support file names with white spaces and quotes - move ffmpeg and magick execution to Utilities - remove unused getVideoLength function --- src/zone/arctic/ytpplus/EffectsFactory.java | 358 +++++++------------- src/zone/arctic/ytpplus/Utilities.java | 139 ++++---- src/zone/arctic/ytpplus/YTPGenerator.java | 4 +- 3 files changed, 185 insertions(+), 316 deletions(-) diff --git a/src/zone/arctic/ytpplus/EffectsFactory.java b/src/zone/arctic/ytpplus/EffectsFactory.java index a1f52e7..95543d8 100644 --- a/src/zone/arctic/ytpplus/EffectsFactory.java +++ b/src/zone/arctic/ytpplus/EffectsFactory.java @@ -50,23 +50,16 @@ public void effect_RandomSound(String video){ File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String randomSound = pickSound(); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -i \"" + randomSound + "\"" - + " -filter_complex [1:a]volume=1,apad[A];[0:a][A]amerge[out]" - + " -ac 2" - //+ " -c:v copy" - - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - - + " -map 0:v" - + " -map [out]" - + " -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-i", pickSound(), + "-filter_complex", "[1:a]volume=1,apad[A];[0:a][A]amerge[out]", + "-ac", "2", + "-ar", "44100", + "-vf", "scale=640x480,setsar=1:1,fps=fps=30", + "-map", "0:v", + "-map", "[out]", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -76,45 +69,28 @@ public void effect_RandomSoundMute(String video){ String randomSound = pickSound(); String soundLength = toolBox.getLength(randomSound); System.out.println("Doing a mute now. " + randomSound + " length: " + soundLength + "."); - //Scanner userInput = new Scanner(System.in); - //String input = userInput.nextLine(); - - //if (!input.isEmpty()) { - File in = new File(video); - File temp = new File(toolBox.getTempVideoName()); - File temp2 = new File(toolBox.getTempVideoName()); - if (in.exists()) - in.renameTo(temp); - if (temp2.exists()) - temp2.delete(); - String command1 = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af volume=0 -y " + temp2.getPath(); - String command2 = toolBox.FFMPEG - + " -i " + temp2.getPath() - + " -i \"" + randomSound + "\"" - + " -to " + soundLength - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter_complex [1:a]volume=1,apad[A];[0:a][A]amerge[out] -ac 2 -map 0:v -map [out] -y " + video; - //String command1 = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; - CommandLine cmdLine = CommandLine.parse(command1); - System.out.println("Command: " + cmdLine); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); - - cmdLine = CommandLine.parse(command2); - System.out.println("Command: " + cmdLine); - executor = new DefaultExecutor(); - exitValue = executor.execute(cmdLine); - - temp.delete(); + File in = new File(video); + File temp = new File(toolBox.getTempVideoName()); + File temp2 = new File(toolBox.getTempVideoName()); + if (in.exists()) + in.renameTo(temp); + if (temp2.exists()) temp2.delete(); - //} - //System.out.println("Did a mute sfx. Type anything to verify."); + toolBox.execFFmpeg("-i", temp.getPath(), + "-af", "volume=0", + "-y", temp2.getPath()); + toolBox.execFFmpeg("-i", temp2.getPath(), + "-i", randomSound, + "-to", soundLength, + "-ar", "44100", + "-filter_complex", "[1:a]volume=1,apad[A];[0:a][A]amerge[out]", + "-ac", "2", + "-map", "0:v", + "-map", "[out]", + "-y", video); + temp.delete(); + temp2.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } public void effect_Reverse(String video){ @@ -127,25 +103,14 @@ public void effect_Reverse(String video){ in.renameTo(temp); if (temp2.exists()) temp2.delete(); - String command1 = toolBox.FFMPEG - + " -i " + temp.getPath() + " -map 0" - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af areverse -y " + temp2.getPath(); - String command2 = toolBox.FFMPEG - + " -i " + temp2.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -vf reverse -y " + video; - - CommandLine cmdLine = CommandLine.parse(command1); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); - - cmdLine = CommandLine.parse(command2); - executor = new DefaultExecutor(); - exitValue = executor.execute(cmdLine); + toolBox.execFFmpeg("-i", temp.getPath(), + "-map", "0", + "-af", "areverse", + "-y", temp2.getPath()); + toolBox.execFFmpeg("-i", temp2.getPath(), + "-vf", "reverse", + "-y", video); temp.delete(); temp2.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} @@ -159,14 +124,11 @@ public void effect_SpeedUp(String video){ File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter:v setpts=0.5*PTS -filter:a atempo=2.0 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-filter:v", "setpts=0.5*PTS", + "-filter:a", "atempo=2.0", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -178,14 +140,11 @@ public void effect_SlowDown(String video){ File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter:v setpts=2*PTS -filter:a atempo=0.5 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-filter:v", "setpts=2*PTS", + "-filter:a", "atempo=0.5", + "-y", video); temp.delete(); } catch (Exception ex) { System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex); @@ -199,14 +158,10 @@ public void effect_Chorus(String video){ File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-af", "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -218,14 +173,10 @@ public void effect_Vibrato(String video){ File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -af vibrato=f=7.0:d=0.5 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-af", "vibrato=f=7.0:d=0.5", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -237,14 +188,11 @@ public void effect_LowPitch(String video) { File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter:v setpts=2*PTS -af asetrate=44100*0.5,aresample=44100 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-filter:v", "setpts=2*PTS", + "-af", "asetrate=44100*0.5,aresample=44100", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -256,14 +204,11 @@ public void effect_HighPitch(String video) { File temp = new File(toolBox.getTempVideoName()); if (in.exists()) in.renameTo(temp); - String command = toolBox.FFMPEG - + " -i " + temp.getPath() - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -filter:v setpts=0.5*PTS -af asetrate=44100*2,aresample=44100 -y " + video; - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + + toolBox.execFFmpeg("-i", temp.getPath(), + "-filter:v", "setpts=0.5*PTS", + "-af", "asetrate=44100*2,aresample=44100", + "-y", video); temp.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } @@ -296,70 +241,37 @@ public void effect_Dance(String video){ temp6.delete(); String randomSound = pickMusic(); - - /* - lib/ffmpeg -i stu.mp4 -map 0 -ar 44100 -to 00:00:00.5 -vf "scale=640x480,setsar=1:1" -an -y " + toolBox.TEMP + "temp2.mp4 - lib/ffmpeg -i " + toolBox.TEMP + "temp2.mp4 -map 0 -ar 44100 -vf "reverse,scale=640x480,setsar=1:1" -y " + toolBox.TEMP + "temp3.mp4 - lib/ffmpeg -i " + toolBox.TEMP + "temp3.mp4 -map 0 -ar 44100 -vf "reverse,scale=640x480,setsar=1:1" -y " + toolBox.TEMP + "temp4.mp4 - lib/ffmpeg -i " + toolBox.TEMP + "temp3.mp4 -i " + toolBox.TEMP + "temp4.mp4 -filter_complex "[0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0]concat=n=8:v=1[outv]" -map "[outv]" -c:v libx264 -shortest -y " + toolBox.TEMP + "temp5.mp4 - lib/ffmpeg -i " + toolBox.TEMP + "temp5.mp4 -map 0 -ar 44100 -vf "setpts=0.5*PTS,scale=640x480,setsar=1:1" -af "atempo=2.0" -shortest -y " + toolBox.TEMP + "temp6.mp4 - lib/ffmpeg -i " + toolBox.TEMP + "temp6.mp4 -i music/dancemusic.mp3 -c:v libx264 -map 0:v:0 -map 1:a:0 -vf "scale=640x480,setsar=1:1,fps=fps=30" -shortest -y " + toolBox.TEMP + "temp7.mp4 - */ - ArrayList commands = new ArrayList(); int randomTime = toolBox.randomInt(3,9); int randomTime2 = toolBox.randomInt(0,1); - commands.add(toolBox.FFMPEG - + " -i " + temp.getPath() + " -map 0"// -c:v copy" - + " -ar 44100" - + " -to 00:00:0"+randomTime2+"." + randomTime - + " -vf scale=640x480,setsar=1:1" - + " -an" - + " -y " + temp2.getPath()); - - commands.add(toolBox.FFMPEG - + " -i " + temp2.getPath() + " -map 0"// -c:v copy" - + " -ar 44100" - + " -vf reverse,scale=640x480,setsar=1:1" - + " -y " + temp3.getPath()); - - commands.add(toolBox.FFMPEG - + " -i " + temp3.getPath() - + " -ar 44100" - + " -vf reverse,scale=640x480,setsar=1:1" - + " -y " + temp4.getPath()); - - commands.add(toolBox.FFMPEG - + " -i " + temp3.getPath() - + " -i " + temp4.getPath() - + " -filter_complex [0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0]concat=n=8:v=1[outv]" - + " -map [outv]" - + " -c:v libx264 -shortest" - + " -y " + temp5.getPath()); - - commands.add(toolBox.FFMPEG - + " -i " + temp5.getPath() - + " -map 0" - + " -ar 44100" - + " -vf setpts=0.5*PTS,scale=640x480,setsar=1:1" - + " -af atempo=2.0" - + " -shortest" - + " -y " + temp6.getPath()); - - commands.add(toolBox.FFMPEG - + " -i " + temp6.getPath() - + " -i \"" + randomSound + "\"" - + " -c:v libx264" - + " -map 0:v:0 -map 1:a:0" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -shortest" - + " -y " + video); - - //String command = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; - for (String command : commands) { - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); - } + + toolBox.execFFmpeg("-i", temp.getPath(), + "-map", "0", // "-c:v", "copy", + "-to", "00:00:0"+randomTime2+"." + randomTime, + "-an", "-y", temp2.getPath()); + toolBox.execFFmpeg("-i", temp2.getPath(), + "-map", "0", // "-c:v", "copy", + "-vf", "reverse", + "-y", temp3.getPath()); + toolBox.execFFmpeg("-i", temp3.getPath(), + "-vf", "reverse", + "-y", temp4.getPath()); + toolBox.execFFmpeg("-i", temp3.getPath(), + "-i", temp4.getPath(), + "-filter_complex", "[0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0][0:v:0][1:v:0]concat=n=8:v=1[outv]", + "-map", "[outv]", + "-c:v", "libx264", + "-shortest", "-y", temp5.getPath()); + toolBox.execFFmpeg("-i", temp5.getPath(), + "-map", "0", + "-vf", "setpts=0.5*PTS", + "-af", "atempo=2.0", + "-shortest", "-y", temp6.getPath()); + toolBox.execFFmpeg("-i", temp6.getPath(), + "-i", randomSound, + "-c:v", "libx264", + "-map", "0:v:0", + "-map", "1:a:0", + "-shortest", "-y", video); temp.delete(); temp2.delete(); @@ -370,7 +282,7 @@ public void effect_Dance(String video){ } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} } - public void effect_Squidward(String video){ + public void effect_Squidward(String video) { System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + " initiated"); try { File in = new File(video); @@ -383,51 +295,44 @@ public void effect_Squidward(String video){ if (in.exists()) in.renameTo(temp); - ArrayList commands = new ArrayList(); + toolBox.execFFmpeg("-i", temp.getPath(), + "-vf", "select=gte(n\\,1)", + "-vframes", "1", + "-y", picturePrefix + "squidward0.png"); - commands.add(toolBox.FFMPEG - + " -i " + temp.getPath() // -c:v copy" - + " -vf select=gte(n\\,1)" - + " -vframes 1" - + " -y " + picturePrefix + "squidward0.png"); - - for (int i=1; i<6; i++) { - String effect = ""; - int random = toolBox.randomInt(0,6); - switch (random) { + for (int i = 1; i < 6; i++) { + ArrayList cmdLine = new ArrayList(); + cmdLine.add("convert"); + cmdLine.add(picturePrefix + "squidward0.png"); + switch (toolBox.randomInt(0, 4)) { case 0: - effect = " -flop"; + cmdLine.add("-flop"); break; case 1: - effect = " -flip"; + cmdLine.add("-flip"); break; case 2: - effect = " -implode -" + toolBox.randomInt(1,3); + cmdLine.add("-implode"); + cmdLine.add((toolBox.randomInt(0, 1) == 0 ? "-" : "") + toolBox.randomInt(1, 3)); break; case 3: - effect = " -implode " + toolBox.randomInt(1,3); + cmdLine.add("-swirl"); + cmdLine.add((toolBox.randomInt(0, 1) == 0 ? "-" : "") + toolBox.randomInt(1, 180)); break; case 4: - effect = " -swirl " + toolBox.randomInt(1,180); - break; - case 5: - effect = " -swirl -" + toolBox.randomInt(1,180); - break; - case 6: - effect = " -channel RGB -negate"; + cmdLine.add("-channel"); + cmdLine.add("RGB"); + cmdLine.add("-negate"); break; //case 7: // effect = " -virtual-pixel Black +distort Cylinder2Plane " + toolBox.randomInt(1,90); // break; } - commands.add(toolBox.MAGICK - + " convert " + picturePrefix + "squidward0.png" - + effect - + " " + picturePrefix + "squidward" + i + ".png" - ); + cmdLine.add(picturePrefix + "squidward" + i + ".png"); + toolBox.execMagick(cmdLine.toArray(new String[cmdLine.size()])); } - commands.add(toolBox.MAGICK - + " convert -size 640x480 canvas:black " + picturePrefix + "black.png"); + toolBox.execMagick("convert", "-size", "640x480", "canvas:black", + picturePrefix + "black.png"); File squidwardScript = new File(picturePrefix + "concatsquidward.txt"); if (squidwardScript.exists()) @@ -450,29 +355,18 @@ public void effect_Squidward(String video){ "duration 0.467"); writer.close(); /* Using "\\" slashes breaks concat (and thus squidward) on - * Windows + * Windows breaks */ - commands.add(toolBox.FFMPEG - + " -f concat" - + " -i " + picturePrefix + "concatsquidward.txt" - + " -i " + toolBox.RESOURCES + "squidward/music.wav" - + " -map 0:v:0 -map 1:a:0" - + " -vf scale=640x480,setsar=1:1" - + " -pix_fmt yuv420p" - + " -y " + video); - - //String command = "lib/ffmpeg -i " + toolBox.TEMP + "temp.mp4 -i sounds/"+randomSound+" -c:v copy -map 0:v:0 -map 1:a:0 -shortest "+ video; - for (String command : commands) { - System.out.println("Executing: " + command); - CommandLine cmdLine = CommandLine.parse(command); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); - } + toolBox.execFFmpeg("-f", "concat", + "-i", picturePrefix + "concatsquidward.txt", + "-i", toolBox.RESOURCES + "squidward/music.wav", + "-map", "0:v:0", "-map", "1:a:0", "-pix_fmt", "yuv420p", + "-y", video); temp.delete(); - for (int i=0; i<6; i++) { - new File(picturePrefix + "squidward"+i+".png").delete(); - } + for (int i = 0; i < 6; i++) + new File(picturePrefix + "squidward" + i + ".png").delete(); + new File(picturePrefix + "black.png").delete(); squidwardScript.delete(); } catch (Exception ex) {System.out.println(new Object() {}.getClass().getEnclosingMethod().getName() + "\n" +ex);} diff --git a/src/zone/arctic/ytpplus/Utilities.java b/src/zone/arctic/ytpplus/Utilities.java index 5287cf8..83e3100 100644 --- a/src/zone/arctic/ytpplus/Utilities.java +++ b/src/zone/arctic/ytpplus/Utilities.java @@ -25,39 +25,16 @@ public class Utilities { public String RESOURCES = ""; private Random random = new Random(); - /** - * Return the length of a video (in seconds) - * - * @param video input video filename to work with - * @return Video length as a string (output from ffprobe) - */ - public String getVideoLength(String video){ - try { - Runtime rt = Runtime.getRuntime(); - Process proc = rt.exec(FFPROBE - + " -v error" - + " -sexagesimal" - + " -show_entries format=duration" - + " -of default=noprint_wrappers=1:nokey=1" - + " \"" + video + "\""); - BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); - String s; - proc.waitFor(); - while ((s = stdInput.readLine()) != null) { - return s; - } - } catch (Exception ex) {ex.printStackTrace(); return "";} - return ""; - } - public String getLength(String file) { try { Runtime rt = Runtime.getRuntime(); - Process proc = rt.exec(FFPROBE - + " -i \"" + file + "\"" - + " -show_entries format=duration" - + " -v error" - + " -of csv=p=0"); + Process proc = rt.exec(new String[] { + FFPROBE, + "-i", file, + "-show_entries", "format=duration", + "-v", "error", + "-of", "csv=p=0" + }); BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); String s; proc.waitFor(); @@ -78,19 +55,16 @@ public String getLength(String file) { */ public void snipVideo(String video, TimeStamp startTime, TimeStamp endTime, String output){ try { - String command1 = FFMPEG - + " -ss " + startTime.getTimeStamp() - + " -i \"" + video + "\"" - + " -to " + endTime.getTimeStamp() - + " -copyts" - + " -ac 1" - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -y" - + " " + output; - CommandLine cmdLine = CommandLine.parse(command1); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + int exitValue = execFFmpeg( + "-ss", startTime.getTimeStamp(), + "-i", video, + "-to", endTime.getTimeStamp(), + "-copyts", + "-ac", "1", + "-ar", "44100", + "-vf", "scale=640x480,setsar=1:1,fps=fps=30", + "-y", output + ); if (exitValue==1) { System.out.println("ERROR"); System.exit(0); @@ -106,16 +80,13 @@ public void snipVideo(String video, TimeStamp startTime, TimeStamp endTime, Stri */ public void copyVideo(String video, String output){ try { - String command1 = FFMPEG - + " -i \"" + video + "\"" - + " -ac 1" - + " -ar 44100" - + " -vf scale=640x480,setsar=1:1,fps=fps=30" - + " -y" - + " " + output; - CommandLine cmdLine = CommandLine.parse(command1); - DefaultExecutor executor = new DefaultExecutor(); - int exitValue = executor.execute(cmdLine); + int exitValue = execFFmpeg( + "-i", video, + "-ac", "1", + "-ar", "44100", + "-vf", "scale=640x480,setsar=1:1,fps=fps=30", + "-y", output + ); if (exitValue==1) { System.out.println("ERROR"); System.exit(0); @@ -129,47 +100,51 @@ public void copyVideo(String video, String output){ * @param count number of input videos to concatenate * @param out output video filename */ - public void concatenateVideo(int count, String out ) { + public void concatenateVideo(int count, String out) { try { File export = new File(out); if (export.exists()) export.delete(); - String command1 = FFMPEG; - - for (int i=0; i