diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,13 @@
 # Change log for cut-the-crap
 
+## Version 2.0.0 - 2020.10.09
+
+- Better install instructions
+- `defaut.nix` in project root now links to ffmpeg
+- return parse result from `runListenCut`
+- Make input file and output file positional
+- Add support for parsing uri and downloading automatically
+
 ## Version 1.4.2 - 2020.08.31
 - add c2hs to build tools so we don't need to modify nixpkgs
 
diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -30,10 +30,23 @@
 
 # Install
 
+## From source
+Install the [nix package](https://nixos.org/download.html) manager.
+
+```shell
+git clone https://github.com/jappeace/cut-the-crap
+cd cut-the-crap
+nix-build .
+result/bin/cut-the-crap
+```
+
 ## Nix/Nixos
-+ Apply [overlay](https://nixos.wiki/wiki/Overlays) found [here](https://github.com/jappeace/cut-the-crap/tree/master/overlay).
-+ Run `nix-env -iA cut-the-crap` or add to systemPackages.
+
++ Run `nix-env -iA nixos.haskellPackages.cut-the-crap` or add to systemPackages.
 + simply run `cut-the-crap` to display usage instructions.
+
+This only works for nixpkgs that have cut-the-crap >= 1.4.2 or =< 1.3
+There were some build issues with 1.4.0 and 1.4.1 (now fixed)
 
 ## Ubuntu
 Download the .deb file from the [release page](https://github.com/jappeace/cut-the-crap/releases).
diff --git a/cut-the-crap.cabal b/cut-the-crap.cabal
--- a/cut-the-crap.cabal
+++ b/cut-the-crap.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 1691afc2c7f5ffdaccba0cc99cb49f19c204ab772b4f3d5412758a6a5748fcb7
+-- hash: 0f25306419959045fb637431751e1f2ae5212ba5c47b5ccc91dca4436a8a7943
 
 name:           cut-the-crap
-version:        1.4.2
+version:        2.0.0
 synopsis:       Cuts out uninteresting parts of videos by detecting silences.
 description:    Cut the crap is an automatic video editing program for streamers. It can cut out uninteresting parts by detecting silences. This was inspired by [jumpcutter](https://github.com/carykh/jumpcutter), where this program can get better quality results by using an (optional) dedicated microphone track. This prevents cutting of [quieter consonants](https://youtu.be/DQ8orIurGxw?t=675) for example. Using ffmpeg more efficiently also produces faster results and is less error prone.
 category:       video
@@ -27,8 +27,8 @@
       Cut.Analyze
       Cut.Crap
       Cut.CutVideo
-      Cut.Ffmpeg
       Cut.Options
+      Cut.Shell
       Cut.SpeechRecognition
   other-modules:
       Paths_cut_the_crap
@@ -52,7 +52,9 @@
     , exceptions
     , generic-lens
     , lens
+    , network-uri
     , optparse-applicative
+    , random
     , regex-tdfa
     , shelly
     , system-filepath
@@ -87,7 +89,9 @@
     , exceptions
     , generic-lens
     , lens
+    , network-uri
     , optparse-applicative
+    , random
     , regex-tdfa
     , shelly
     , system-filepath
@@ -107,8 +111,8 @@
       Cut.Analyze
       Cut.Crap
       Cut.CutVideo
-      Cut.Ffmpeg
       Cut.Options
+      Cut.Shell
       Cut.SpeechRecognition
       Paths_cut_the_crap
   hs-source-dirs:
@@ -135,8 +139,10 @@
     , hspec
     , hspec-core
     , lens
+    , network-uri
     , optparse-applicative
     , quickcheck-classes
+    , random
     , regex-tdfa
     , shelly
     , system-filepath
diff --git a/src/Cut/Analyze.hs b/src/Cut/Analyze.hs
--- a/src/Cut/Analyze.hs
+++ b/src/Cut/Analyze.hs
@@ -15,7 +15,7 @@
 import           Control.Monad
 import           Control.Monad.Catch
 import           Control.Monad.IO.Unlift
-import           Cut.Ffmpeg
+import           Cut.Shell
 import           Cut.Options
 import           Cut.SpeechRecognition
 import           Data.Coerce
@@ -51,6 +51,7 @@
   liftIO $ putStrLn "-----------------actual lines-----------------"
   liftIO $ putStrLn "-----------------------------------------"
   liftIO $ Text.putStrLn $ Text.unlines lines'
+
   liftIO $ putStrLn "-----------------------------------------"
   liftIO $ putStrLn "-----------------filtered lines-----------------"
   liftIO $ putStrLn "-----------------------------------------"
diff --git a/src/Cut/Crap.hs b/src/Cut/Crap.hs
--- a/src/Cut/Crap.hs
+++ b/src/Cut/Crap.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DataKinds     #-}
 {-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 -- | This is where it all started
 module Cut.Crap
@@ -12,6 +13,7 @@
   )
 where
 
+import           Cut.Shell
 import           Control.Lens
 import           Control.Monad
 import           Control.Monad.Catch
@@ -19,7 +21,6 @@
 import           Control.Monad.IO.Unlift
 import           Cut.Analyze
 import           Cut.CutVideo
-import           Cut.Ffmpeg
 import           Cut.Options
 import           Cut.SpeechRecognition
 import           Data.Foldable                (fold, foldl', traverse_)
@@ -34,24 +35,68 @@
 import           Options.Applicative
 import           Shelly                       hiding (FilePath)
 import           System.IO.Temp
+import Network.URI(URI)
+import System.Random
+import Data.Word
 
+runYoutubeDL :: FileIO a -> URI -> IO FilePath
+runYoutubeDL opts x = do
+
+  inputNumbers :: Word32 <- randomIO
+  let inputChars :: String
+      -- youtube-dl doesn't do .mkv (not supported)
+      inputChars = (show inputNumbers) <> ".mp4"
+      filePath :: String
+      filePath = fromMaybe inputChars $ opts ^. work_dir
+  void $ shelly $ youtube_dl x filePath
+  pure filePath
+
+
+
+downloadIfNeccisary :: FileIO InputSource -> IO (FileIO FilePath)
+downloadIfNeccisary x = do
+  result <- sequence $ (runYoutube <|> alreadyLocal)
+  case result of
+    Nothing -> error $ "Couldn't find " <> show x
+    Just y -> pure $ x & in_file .~ y
+  where
+    runYoutube :: Maybe (IO FilePath)
+    runYoutube = x ^? in_file . input_src_remote . to (runYoutubeDL x)
+
+    alreadyLocal :: Maybe (IO FilePath)
+    alreadyLocal = preview (in_file . input_src_local_file . to pure) x
+
+downloadCutifNeccisary :: ListenCutOptionsT InputSource -> IO (ListenCutOptionsT FilePath)
+downloadCutifNeccisary cut = repackRes
+      where
+        downloadRes :: IO (FileIO FilePath)
+        downloadRes =  downloadIfNeccisary $ cut ^. lc_fileio
+        repackRes :: IO (ListenCutOptionsT (FilePath))
+        repackRes = downloadRes <&> \y -> lc_fileio .~ y $ cut
+
 -- | reads settings from terminal and runs whatever command was
 --   given in program options
-entryPoint :: (MonadMask m, MonadUnliftIO m) => m ()
+entryPoint :: MonadMask m => MonadUnliftIO m => m ()
 entryPoint = do
   result <- liftIO readSettings
+  betterResult <-  liftIO $ case  result of
+    ListenCut cut -> ListenCut <$> downloadCutifNeccisary cut
+    GenerateSubtitles x -> GenerateSubtitles <$> downloadIfNeccisary x
+
   -- I'm mr meeseeks look at me!
-  sequence_ $ result ^? listen_cut_prism . to runListenCut
-          <|> result ^? gnerate_sub_prism . to runGenSubs
+  sequence_ $ betterResult ^? listen_cut_prism . to (void . runListenCut)
+           <|> betterResult ^? gnerate_sub_prism . to runGenSubs
+  pure ()
 
-runGenSubs :: MonadIO m => FileIO -> m ()
+runGenSubs :: MonadIO m => FileIO FilePath -> m ()
 runGenSubs options = liftIO $ withTempDir options $ \tmp -> do
-    result <- shelly $ detectSpeech (set voice_track 1 simpleOptions) tmp $ options ^. in_file
+    betterOptions <- downloadCutifNeccisary simpleOptions
+    result <- shelly $ detectSpeech (set voice_track 1 betterOptions) tmp $ options ^. in_file
     print result
     traverse_ (T.writeFile (options ^. out_file) . makeSrt) result
 
 -- | Runs cut-the-crap with provided `ListenCutOptions`
-runListenCut :: (MonadMask m, MonadUnliftIO m) => ListenCutOptions -> m ()
+runListenCut :: MonadMask m => MonadUnliftIO m => ListenCutOptions -> m [Interval Sound]
 runListenCut options = do
   liftIO $ putStr "started with options: "
   liftIO $ print options
@@ -60,14 +105,14 @@
   parsed <- detectSoundInterval options
 
   -- then do stuff to it
-  case parsed of
+  parsed <$ case parsed of
     [] ->
       liftIO
         $ putStr
             "\n\nNo silence in input video detected. There is nothing to be cut so exiting.\n\n"
     _ -> liftIO $ withTempDir (options ^. lc_fileio) $ runEdit options parsed
 
-withTempDir :: FileIO -> (FilePath -> IO ()) -> IO ()
+withTempDir :: FileIO FilePath -> (FilePath -> IO ()) -> IO ()
 withTempDir filioOpts fun =
   maybe (withTempDirectory "/tmp" "streamedit" fun) fun $ filioOpts ^. work_dir
 
@@ -86,7 +131,7 @@
   writefile (fromText $ Text.pack $ tempDir <> "/input.txt") paths
   combine tempDir
 
-readSettings :: IO ProgramOptions
+readSettings :: IO (ProgramOptions InputSource)
 readSettings = customExecParser (prefs showHelpOnError) $ info
   (parseProgram <**> helper)
   (fullDesc <> header "Cut the crap" <> progDesc
diff --git a/src/Cut/CutVideo.hs b/src/Cut/CutVideo.hs
--- a/src/Cut/CutVideo.hs
+++ b/src/Cut/CutVideo.hs
@@ -15,7 +15,7 @@
 import           Control.Monad
 import           Control.Monad.Catch
 import           Cut.Analyze
-import           Cut.Ffmpeg
+import           Cut.Shell
 import           Cut.Options
 import           Data.Foldable
 import           Data.Text           (Text)
diff --git a/src/Cut/Ffmpeg.hs b/src/Cut/Ffmpeg.hs
deleted file mode 100644
--- a/src/Cut/Ffmpeg.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-module Cut.Ffmpeg
-  ( ffmpeg
-  , ffmpeg'
-  , floatToText
-  )
-where
-
-import           Data.Text (Text)
-import qualified Data.Text as Text
-import           Numeric
-import           Shelly
-
--- | Wrap ffmpeg for convenience and logging
---  technically supports multiple inputs but for convenice we threw that.
-ffmpeg :: Prelude.FilePath -> [Text] -> Sh [Text]
-ffmpeg file args = ffmpeg' ("-y" : "-i" : Text.pack file : args)
-
-ffmpeg' :: [Text] -> Sh [Text]
-ffmpeg' args = do
-  liftIO $ putStr "Running: "
-  liftIO $ print $ "ffmpeg " <> Text.unwords args
-  run_ "ffmpeg" args
-  Text.lines <$> lastStderr
-
--- | Format floats for cli
-floatToText :: Double -> Text
-floatToText = Text.pack . flip (showFFloat (Just 10)) ""
diff --git a/src/Cut/Options.hs b/src/Cut/Options.hs
--- a/src/Cut/Options.hs
+++ b/src/Cut/Options.hs
@@ -1,15 +1,27 @@
 {-# LANGUAGE DataKinds        #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeOperators    #-}
+{-# LANGUAGE DeriveAnyClass #-}
 
+-- | This module defines which options exists, and provides
+--   functions for parsing cli options.
 module Cut.Options
-  ( ProgramOptions
+  ( parseProgram
+  , specifyTracks
+  , getOutFileName
+  -- * Program options
+  , ProgramOptions(..)
+  , gnerate_sub_prism
+  , listen_cut_prism
+  -- * fileio, deal with input output files
   , FileIO
-  , ListenCutOptions
-  , parseProgram
   , lc_fileio
   , in_file
   , out_file
+  , work_dir
+  -- * listen cut, options for video editing by audio
+  , ListenCutOptionsT
+  , ListenCutOptions
   , seg_size
   , silent_treshold
   , detect_margin
@@ -17,39 +29,41 @@
   , music_track
   , silent_duration
   , cut_noise
-  , work_dir
-  , simpleOptions
   , voice_track_map
-  , specifyTracks
-  , getOutFileName
-  , gnerate_sub_prism
-  , listen_cut_prism
+  -- * input source prisms
+  , InputSource
+  , input_src_remote
+  , input_src_local_file
+  -- * defaults
+  , simpleOptions
   )
 where
 
-import           Control.Lens
+import           Control.Lens hiding (argument)
 import           Data.Generics.Product.Fields
 import           Data.Generics.Sum
 import qualified Data.Text                    as Text
 import           Data.Text.Lens
 import           GHC.Generics                 hiding (to)
 import           Options.Applicative
+import Network.URI
 
-simpleFileIO :: FileIO
-simpleFileIO = FileIO  { fi_inFile         = "in.mkv"                      , fi_outFile        = "out.mkv"
+simpleFileIO :: (FileIO InputSource)
+simpleFileIO = FileIO  { fi_inFile         = LocalFile "in.mkv"                      , fi_outFile        = "out.mkv"
                        , fi_workDir        = Nothing
                         }
 
-in_file :: Lens' FileIO FilePath
+-- type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
+in_file :: Lens (FileIO a) (FileIO b) a b
 in_file = field @"fi_inFile"
 
-out_file :: Lens' FileIO FilePath
+out_file :: Lens' (FileIO a) FilePath
 out_file = field @"fi_outFile"
 
-work_dir :: Lens' FileIO (Maybe FilePath)
+work_dir :: Lens' (FileIO a) (Maybe FilePath)
 work_dir = field @"fi_workDir"
 
-simpleOptions :: ListenCutOptions
+simpleOptions :: ListenCutOptionsT InputSource
 simpleOptions = ListenCutOptions
                         { lc_fileIO = simpleFileIO
                         , lc_segmentSize    = _Just # def_seg_size
@@ -61,20 +75,22 @@
                         , lc_cutNoise       = def_cut_noise
                         }
 
-getOutFileName :: ListenCutOptions -> FilePath
+getOutFileName :: ListenCutOptionsT a -> FilePath
 getOutFileName = reverse . takeWhile ('/' /=) . reverse . view (lc_fileio . out_file)
 
 -- | Deals with having an input file and a target output file
-data FileIO = FileIO
-              { fi_inFile  :: FilePath
+data FileIO a = FileIO
+              { fi_inFile  :: a
               , fi_outFile :: FilePath
               , fi_workDir :: Maybe FilePath -- ^ for consistency (or debugging) we may want to specify this.
               }
   deriving (Show, Generic)
 
+type ListenCutOptions = ListenCutOptionsT FilePath
+
 -- | Cut out by listening to sound options
-data ListenCutOptions = ListenCutOptions
-                { lc_fileIO         :: FileIO
+data ListenCutOptionsT a = ListenCutOptions
+                { lc_fileIO         :: FileIO a
                 , lc_segmentSize    :: Maybe Int
                 , lc_silentTreshold :: Maybe Double
                 , lc_silentDuration :: Maybe Double
@@ -85,14 +101,14 @@
                 }
   deriving (Show, Generic)
 
-data ProgramOptions = ListenCut ListenCutOptions
-                    | GenerateSubtitles FileIO
+data ProgramOptions a = ListenCut (ListenCutOptionsT a)
+                    | GenerateSubtitles (FileIO a)
   deriving (Show, Generic)
 
-listen_cut_prism :: Prism' ProgramOptions ListenCutOptions
+listen_cut_prism :: Prism' (ProgramOptions a) (ListenCutOptionsT a)
 listen_cut_prism = _Ctor @"ListenCut"
 
-gnerate_sub_prism :: Prism' ProgramOptions FileIO
+gnerate_sub_prism :: Prism' (ProgramOptions a) (FileIO a)
 gnerate_sub_prism = _Ctor @"GenerateSubtitles"
 
 def_seg_size :: Int
@@ -113,34 +129,34 @@
 def_voice :: Int
 def_voice = 1
 
-lc_fileio :: Lens' ListenCutOptions FileIO
+lc_fileio :: Lens (ListenCutOptionsT a) (ListenCutOptionsT b) (FileIO a) (FileIO b)
 lc_fileio = field @"lc_fileIO"
 
-seg_size :: Lens' ListenCutOptions Int
+seg_size :: Lens' (ListenCutOptionsT a) Int
 seg_size = field @"lc_segmentSize" . non def_seg_size
 
-detect_margin :: Lens' ListenCutOptions Double
+detect_margin :: Lens' (ListenCutOptionsT a) Double
 detect_margin = field @"lc_detectMargin" . non def_margin
 
-silent_treshold :: Lens' ListenCutOptions Double
+silent_treshold :: Lens' (ListenCutOptionsT a) Double
 silent_treshold = field @"lc_silentTreshold" . non def_silent
 
-silent_duration :: Lens' ListenCutOptions Double
+silent_duration :: Lens' (ListenCutOptionsT a) Double
 silent_duration = field @"lc_silentDuration" . non def_duration
 
-voice_track :: Lens' ListenCutOptions Int
+voice_track :: Lens' (ListenCutOptionsT a) Int
 voice_track = field @"lc_voiceTrack" . non def_voice
 
-music_track :: Lens' ListenCutOptions (Maybe Int)
+music_track :: Lens' (ListenCutOptionsT a) (Maybe Int)
 music_track = field @"lc_musicTrack"
 
-cut_noise :: Lens' ListenCutOptions Bool
+cut_noise :: Lens' (ListenCutOptionsT a) Bool
 cut_noise = field @"lc_cutNoise"
 
-voice_track_map :: ListenCutOptions -> Text.Text
+voice_track_map :: (ListenCutOptionsT a) -> Text.Text
 voice_track_map = mappend "0:" . view (voice_track . to show . packed)
 
-specifyTracks :: ListenCutOptions -> [Text.Text]
+specifyTracks :: (ListenCutOptionsT a) -> [Text.Text]
 specifyTracks options =
   [ "-map"
   , "0:0"
@@ -148,10 +164,26 @@
   , voice_track_map options
   ]
 
-parseFile :: Parser FileIO
+data InputSource = LocalFile FilePath
+                 | Remote URI
+                 deriving (Show, Generic)
+
+input_src_local_file :: Prism' InputSource FilePath
+input_src_local_file = _Ctor @"LocalFile"
+
+input_src_remote :: Prism' InputSource URI
+input_src_remote = _Ctor @"Remote"
+
+readFileSource :: ReadM InputSource
+readFileSource = eitherReader $
+  \x ->
+    maybe (Left "unlikely error") Right $
+    (Remote <$> parseURI x) <|> Just (LocalFile x)
+
+parseFile :: Parser (FileIO InputSource)
 parseFile = FileIO
-    <$> option str (long "inFile" <> help "The input video")
-    <*> option str (long "outFile" <> help "The output name without format")
+    <$> argument readFileSource (metavar "INPUT" <> help "The input video, either a file or a uri")
+    <*> argument str (metavar "OUTPUT_FILE" <> help "The output name without format")
     <*> optional
           (option
             str
@@ -161,14 +193,14 @@
             )
           )
 
-parseProgram :: Parser ProgramOptions
+parseProgram :: Parser (ProgramOptions InputSource)
 parseProgram =
   subparser $
     command "listen" (info (ListenCut <$> parseSound) $ progDesc "Cut out by listening to sound options. We listen for silences and cut out the parts that are silenced.")
     <>
     command "subtitles" (info (GenerateSubtitles <$> parseFile) $ progDesc "Generate subtiles for a video. This is an intermediate (but usefull) feature developed for recognizing human speech vs background noise.")
 
-parseSound :: Parser ListenCutOptions
+parseSound :: Parser (ListenCutOptionsT InputSource)
 parseSound = ListenCutOptions
     <$> parseFile
     <*> optional
diff --git a/src/Cut/Shell.hs b/src/Cut/Shell.hs
new file mode 100644
--- /dev/null
+++ b/src/Cut/Shell.hs
@@ -0,0 +1,40 @@
+
+-- | Run shell programs
+module Cut.Shell
+  ( ffmpeg
+  , ffmpeg'
+  , floatToText
+  , youtube_dl
+  )
+where
+
+import           Data.Text (Text)
+import qualified Data.Text as Text
+import           Numeric
+import           Shelly
+import Network.URI(URI)
+
+-- | Wrap ffmpeg for convenience and logging
+--  technically supports multiple inputs but for convenice we threw that.
+ffmpeg :: Prelude.FilePath -> [Text] -> Sh [Text]
+ffmpeg file args = ffmpeg' ("-y" : "-i" : Text.pack file : args)
+
+ffmpeg' :: [Text] -> Sh [Text]
+ffmpeg' args = do
+  liftIO $ putStr "Running: "
+  liftIO $ print $ "ffmpeg " <> Text.unwords args
+  run_ "ffmpeg" args
+  Text.lines <$> lastStderr
+
+-- | Format floats for cli
+floatToText :: Double -> Text
+floatToText = Text.pack . flip (showFFloat (Just 10)) ""
+
+youtube_dl :: URI -> FilePath -> Sh [Text]
+youtube_dl uri path' = do
+  liftIO $ print $ "running youtube-dl " <> Text.unwords args
+  run_ "youtube-dl" args
+  Text.lines <$> lastStderr
+  where
+    args = [Text.pack $ show uri,
+           "-o", Text.pack path']
