Downloader: Download to temporary directory, and read track info from
JSON before download.
This commit is contained in:
parent
03ffc9d994
commit
3437887551
|
@ -6,8 +6,12 @@
|
|||
package moe.nekojimi.chords;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
@ -20,6 +24,9 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonObject;
|
||||
import javax.json.JsonReader;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -33,6 +40,8 @@ public class Downloader implements Consumer<Song>
|
|||
private Consumer<Song> next;
|
||||
private BiConsumer<Song, Exception> messageHandler;
|
||||
|
||||
private File downloadDir = null;
|
||||
|
||||
public Downloader()
|
||||
{
|
||||
|
||||
|
@ -42,6 +51,7 @@ public class Downloader implements Consumer<Song>
|
|||
public void accept(Song song)
|
||||
{
|
||||
downloadQueue.add(song);
|
||||
getInfo(song);
|
||||
exec.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
|
@ -57,29 +67,49 @@ public class Downloader implements Consumer<Song>
|
|||
this.next = next;
|
||||
}
|
||||
|
||||
private void getInfo(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
String cmd = "/usr/bin/youtube-dl --skip-download --print-json " + song.getUrl().toString();
|
||||
Process exec = runCommand(cmd, 5);
|
||||
InputStream input = exec.getInputStream();
|
||||
JsonReader reader = Json.createReader(input);
|
||||
JsonObject object = reader.readObject();
|
||||
if (song.getTitle() == null)
|
||||
song.setTitle(object.getString("title", null));
|
||||
if (song.getArtist() == null)
|
||||
song.setArtist(object.getString("uploader", null));
|
||||
} catch (Exception ex)
|
||||
{
|
||||
Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private File getDownloadDir() throws IOException
|
||||
{
|
||||
if (downloadDir == null || !downloadDir.exists() || !downloadDir.canWrite())
|
||||
downloadDir = Files.createTempDirectory("chords").toFile();
|
||||
return downloadDir;
|
||||
}
|
||||
|
||||
private void download(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
messageHandler.accept(song, null);
|
||||
String cmd = "/usr/bin/youtube-dl -x -f=worstaudio/worst --audio-format=wav --no-playlist --write-info-json " + song.getUrl().toString();
|
||||
System.out.println("Running command: " + cmd);
|
||||
// Process exec = Runtime.getRuntime().exec().split(" "));
|
||||
Process exec = new ProcessBuilder(cmd.split(" ")).redirectOutput(ProcessBuilder.Redirect.PIPE).start();
|
||||
boolean done = exec.waitFor(300, TimeUnit.SECONDS);
|
||||
if (!done)
|
||||
{
|
||||
exec.destroyForcibly();
|
||||
throw new RuntimeException("Took too long to download, giving up.");
|
||||
}
|
||||
String cmd = "/usr/bin/youtube-dl -x -f=worstaudio/worst --audio-format=wav --no-playlist -o " + getDownloadDir().getAbsolutePath() + "/%(title)s.%(ext)s " + song.getUrl().toString();
|
||||
Process exec = runCommand(cmd, 300);
|
||||
InputStream in = exec.getInputStream();
|
||||
String output = new String(in.readAllBytes(), Charset.defaultCharset());
|
||||
String error = new String(exec.getErrorStream().readAllBytes(), Charset.defaultCharset());
|
||||
System.out.println(output);
|
||||
Matcher matcher = Pattern.compile("Destination: (.*\\.wav)").matcher(output);
|
||||
if (matcher.find())
|
||||
song.setLocation(new File(matcher.group(1)));
|
||||
else if (exec.exitValue() != 0)
|
||||
throw new RuntimeException("youtube-dl failed with error " + exec.exitValue());
|
||||
throw new RuntimeException("youtube-dl failed with error " + exec.exitValue() + ", output:\n" + error);
|
||||
// return true;
|
||||
|
||||
if (next != null)
|
||||
|
@ -95,6 +125,20 @@ public class Downloader implements Consumer<Song>
|
|||
}
|
||||
}
|
||||
|
||||
private Process runCommand(String cmd, int timeoutSecs) throws RuntimeException, IOException, InterruptedException
|
||||
{
|
||||
System.out.println("Running command: " + cmd);
|
||||
// Process exec = Runtime.getRuntime().exec().split(" "));
|
||||
Process exec = new ProcessBuilder(cmd.split(" ")).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start();
|
||||
boolean done = exec.waitFor(timeoutSecs, TimeUnit.SECONDS);
|
||||
if (!done)
|
||||
{
|
||||
exec.destroyForcibly();
|
||||
throw new RuntimeException("Took too long, giving up.");
|
||||
}
|
||||
return exec;
|
||||
}
|
||||
|
||||
public BiConsumer<Song, Exception> getMessageHandler()
|
||||
{
|
||||
return messageHandler;
|
||||
|
|
Loading…
Reference in New Issue