diff --git a/src/main/java/moe/nekojimi/chords/Downloader.java b/src/main/java/moe/nekojimi/chords/Downloader.java
index 9f5c0a5..f030efd 100644
--- a/src/main/java/moe/nekojimi/chords/Downloader.java
+++ b/src/main/java/moe/nekojimi/chords/Downloader.java
@@ -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;