{-# LANGUAGE DataKinds        #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators    #-}

module Cut.Options
  ( ProgramOptions
  , FileIO
  , ListenCutOptions
  , parseProgram
  , lc_fileio
  , in_file
  , out_file
  , seg_size
  , silent_treshold
  , detect_margin
  , voice_track
  , music_track
  , silent_duration
  , cut_noise
  , work_dir
  , simpleOptions
  , voice_track_map
  , specifyTracks
  , getOutFileName
  , gnerate_sub_prism
  , listen_cut_prism
  )
where

import           Control.Lens
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

simpleFileIO :: FileIO
simpleFileIO :: FileIO
simpleFileIO = FileIO :: FilePath -> FilePath -> Maybe FilePath -> FileIO
FileIO  { fi_inFile :: FilePath
fi_inFile         = "in.mkv"                      , fi_outFile :: FilePath
fi_outFile        = "out.mkv"
                       , fi_workDir :: Maybe FilePath
fi_workDir        = Maybe FilePath
forall a. Maybe a
Nothing
                        }

in_file :: Lens' FileIO FilePath
in_file :: (FilePath -> f FilePath) -> FileIO -> f FileIO
in_file = forall s t a b. HasField "fi_inFile" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"fi_inFile"

out_file :: Lens' FileIO FilePath
out_file :: (FilePath -> f FilePath) -> FileIO -> f FileIO
out_file = forall s t a b. HasField "fi_outFile" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"fi_outFile"

work_dir :: Lens' FileIO (Maybe FilePath)
work_dir :: (Maybe FilePath -> f (Maybe FilePath)) -> FileIO -> f FileIO
work_dir = forall s t a b. HasField "fi_workDir" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"fi_workDir"

simpleOptions :: ListenCutOptions
simpleOptions :: ListenCutOptions
simpleOptions = ListenCutOptions :: FileIO
-> Maybe Int
-> Maybe Double
-> Maybe Double
-> Maybe Double
-> Maybe Int
-> Maybe Int
-> Bool
-> ListenCutOptions
ListenCutOptions
                        { lc_fileIO :: FileIO
lc_fileIO = FileIO
simpleFileIO
                        , lc_segmentSize :: Maybe Int
lc_segmentSize    = Tagged Int (Identity Int)
-> Tagged (Maybe Int) (Identity (Maybe Int))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just (Tagged Int (Identity Int)
 -> Tagged (Maybe Int) (Identity (Maybe Int)))
-> Int -> Maybe Int
forall t b. AReview t b -> b -> t
# Int
def_seg_size
                        , lc_silentTreshold :: Maybe Double
lc_silentTreshold = Tagged Double (Identity Double)
-> Tagged (Maybe Double) (Identity (Maybe Double))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just (Tagged Double (Identity Double)
 -> Tagged (Maybe Double) (Identity (Maybe Double)))
-> Double -> Maybe Double
forall t b. AReview t b -> b -> t
# Double
def_silent
                        , lc_detectMargin :: Maybe Double
lc_detectMargin   = Tagged Double (Identity Double)
-> Tagged (Maybe Double) (Identity (Maybe Double))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just (Tagged Double (Identity Double)
 -> Tagged (Maybe Double) (Identity (Maybe Double)))
-> Double -> Maybe Double
forall t b. AReview t b -> b -> t
# Double
def_margin
                        , lc_voiceTrack :: Maybe Int
lc_voiceTrack     = Tagged Int (Identity Int)
-> Tagged (Maybe Int) (Identity (Maybe Int))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just (Tagged Int (Identity Int)
 -> Tagged (Maybe Int) (Identity (Maybe Int)))
-> Int -> Maybe Int
forall t b. AReview t b -> b -> t
# 2
                        , lc_musicTrack :: Maybe Int
lc_musicTrack     = Maybe Int
forall a. Maybe a
Nothing
                        , lc_silentDuration :: Maybe Double
lc_silentDuration = Tagged Double (Identity Double)
-> Tagged (Maybe Double) (Identity (Maybe Double))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just (Tagged Double (Identity Double)
 -> Tagged (Maybe Double) (Identity (Maybe Double)))
-> Double -> Maybe Double
forall t b. AReview t b -> b -> t
# Double
def_duration
                        , lc_cutNoise :: Bool
lc_cutNoise       = Bool
def_cut_noise
                        }

getOutFileName :: ListenCutOptions -> FilePath
getOutFileName :: ListenCutOptions -> FilePath
getOutFileName = FilePath -> FilePath
forall a. [a] -> [a]
reverse (FilePath -> FilePath)
-> (ListenCutOptions -> FilePath) -> ListenCutOptions -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> FilePath -> FilePath
forall a. (a -> Bool) -> [a] -> [a]
takeWhile ('/' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=) (FilePath -> FilePath)
-> (ListenCutOptions -> FilePath) -> ListenCutOptions -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
forall a. [a] -> [a]
reverse (FilePath -> FilePath)
-> (ListenCutOptions -> FilePath) -> ListenCutOptions -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting FilePath ListenCutOptions FilePath
-> ListenCutOptions -> FilePath
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((FileIO -> Const FilePath FileIO)
-> ListenCutOptions -> Const FilePath ListenCutOptions
Lens' ListenCutOptions FileIO
lc_fileio ((FileIO -> Const FilePath FileIO)
 -> ListenCutOptions -> Const FilePath ListenCutOptions)
-> ((FilePath -> Const FilePath FilePath)
    -> FileIO -> Const FilePath FileIO)
-> Getting FilePath ListenCutOptions FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> Const FilePath FilePath)
-> FileIO -> Const FilePath FileIO
Lens' FileIO FilePath
out_file)

-- | Deals with having an input file and a target output file
data FileIO = FileIO
              { FileIO -> FilePath
fi_inFile  :: FilePath
              , FileIO -> FilePath
fi_outFile :: FilePath
              , FileIO -> Maybe FilePath
fi_workDir :: Maybe FilePath -- ^ for consistency (or debugging) we may want to specify this.
              }
  deriving (Int -> FileIO -> FilePath -> FilePath
[FileIO] -> FilePath -> FilePath
FileIO -> FilePath
(Int -> FileIO -> FilePath -> FilePath)
-> (FileIO -> FilePath)
-> ([FileIO] -> FilePath -> FilePath)
-> Show FileIO
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [FileIO] -> FilePath -> FilePath
$cshowList :: [FileIO] -> FilePath -> FilePath
show :: FileIO -> FilePath
$cshow :: FileIO -> FilePath
showsPrec :: Int -> FileIO -> FilePath -> FilePath
$cshowsPrec :: Int -> FileIO -> FilePath -> FilePath
Show, (forall x. FileIO -> Rep FileIO x)
-> (forall x. Rep FileIO x -> FileIO) -> Generic FileIO
forall x. Rep FileIO x -> FileIO
forall x. FileIO -> Rep FileIO x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FileIO x -> FileIO
$cfrom :: forall x. FileIO -> Rep FileIO x
Generic)

-- | Cut out by listening to sound options
data ListenCutOptions = ListenCutOptions
                { ListenCutOptions -> FileIO
lc_fileIO         :: FileIO
                , ListenCutOptions -> Maybe Int
lc_segmentSize    :: Maybe Int
                , ListenCutOptions -> Maybe Double
lc_silentTreshold :: Maybe Double
                , ListenCutOptions -> Maybe Double
lc_silentDuration :: Maybe Double
                , ListenCutOptions -> Maybe Double
lc_detectMargin   :: Maybe Double
                , ListenCutOptions -> Maybe Int
lc_voiceTrack     :: Maybe Int
                , ListenCutOptions -> Maybe Int
lc_musicTrack     :: Maybe Int
                , ListenCutOptions -> Bool
lc_cutNoise       :: Bool
                }
  deriving (Int -> ListenCutOptions -> FilePath -> FilePath
[ListenCutOptions] -> FilePath -> FilePath
ListenCutOptions -> FilePath
(Int -> ListenCutOptions -> FilePath -> FilePath)
-> (ListenCutOptions -> FilePath)
-> ([ListenCutOptions] -> FilePath -> FilePath)
-> Show ListenCutOptions
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [ListenCutOptions] -> FilePath -> FilePath
$cshowList :: [ListenCutOptions] -> FilePath -> FilePath
show :: ListenCutOptions -> FilePath
$cshow :: ListenCutOptions -> FilePath
showsPrec :: Int -> ListenCutOptions -> FilePath -> FilePath
$cshowsPrec :: Int -> ListenCutOptions -> FilePath -> FilePath
Show, (forall x. ListenCutOptions -> Rep ListenCutOptions x)
-> (forall x. Rep ListenCutOptions x -> ListenCutOptions)
-> Generic ListenCutOptions
forall x. Rep ListenCutOptions x -> ListenCutOptions
forall x. ListenCutOptions -> Rep ListenCutOptions x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ListenCutOptions x -> ListenCutOptions
$cfrom :: forall x. ListenCutOptions -> Rep ListenCutOptions x
Generic)

data ProgramOptions = ListenCut ListenCutOptions
                    | GenerateSubtitles FileIO
  deriving (Int -> ProgramOptions -> FilePath -> FilePath
[ProgramOptions] -> FilePath -> FilePath
ProgramOptions -> FilePath
(Int -> ProgramOptions -> FilePath -> FilePath)
-> (ProgramOptions -> FilePath)
-> ([ProgramOptions] -> FilePath -> FilePath)
-> Show ProgramOptions
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [ProgramOptions] -> FilePath -> FilePath
$cshowList :: [ProgramOptions] -> FilePath -> FilePath
show :: ProgramOptions -> FilePath
$cshow :: ProgramOptions -> FilePath
showsPrec :: Int -> ProgramOptions -> FilePath -> FilePath
$cshowsPrec :: Int -> ProgramOptions -> FilePath -> FilePath
Show, (forall x. ProgramOptions -> Rep ProgramOptions x)
-> (forall x. Rep ProgramOptions x -> ProgramOptions)
-> Generic ProgramOptions
forall x. Rep ProgramOptions x -> ProgramOptions
forall x. ProgramOptions -> Rep ProgramOptions x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ProgramOptions x -> ProgramOptions
$cfrom :: forall x. ProgramOptions -> Rep ProgramOptions x
Generic)

listen_cut_prism :: Prism' ProgramOptions ListenCutOptions
listen_cut_prism :: p ListenCutOptions (f ListenCutOptions)
-> p ProgramOptions (f ProgramOptions)
listen_cut_prism = forall s t a b. AsConstructor "ListenCut" s t a b => Prism s t a b
forall (ctor :: Symbol) s t a b.
AsConstructor ctor s t a b =>
Prism s t a b
_Ctor @"ListenCut"

gnerate_sub_prism :: Prism' ProgramOptions FileIO
gnerate_sub_prism :: p FileIO (f FileIO) -> p ProgramOptions (f ProgramOptions)
gnerate_sub_prism = forall s t a b.
AsConstructor "GenerateSubtitles" s t a b =>
Prism s t a b
forall (ctor :: Symbol) s t a b.
AsConstructor ctor s t a b =>
Prism s t a b
_Ctor @"GenerateSubtitles"

def_seg_size :: Int
def_seg_size :: Int
def_seg_size = 20

def_margin :: Double
def_margin :: Double
def_margin = 0.05

def_cut_noise :: Bool
def_cut_noise :: Bool
def_cut_noise = Bool
False

def_silent :: Double
def_silent :: Double
def_silent = 0.0001

def_duration :: Double
def_duration :: Double
def_duration = 0.25

def_voice :: Int
def_voice :: Int
def_voice = 1

lc_fileio :: Lens' ListenCutOptions FileIO
lc_fileio :: (FileIO -> f FileIO) -> ListenCutOptions -> f ListenCutOptions
lc_fileio = forall s t a b. HasField "lc_fileIO" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_fileIO"

seg_size :: Lens' ListenCutOptions Int
seg_size :: (Int -> f Int) -> ListenCutOptions -> f ListenCutOptions
seg_size = forall s t a b. HasField "lc_segmentSize" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_segmentSize" ((Maybe Int -> f (Maybe Int))
 -> ListenCutOptions -> f ListenCutOptions)
-> ((Int -> f Int) -> Maybe Int -> f (Maybe Int))
-> (Int -> f Int)
-> ListenCutOptions
-> f ListenCutOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Iso' (Maybe Int) Int
forall a. Eq a => a -> Iso' (Maybe a) a
non Int
def_seg_size

detect_margin :: Lens' ListenCutOptions Double
detect_margin :: (Double -> f Double) -> ListenCutOptions -> f ListenCutOptions
detect_margin = forall s t a b. HasField "lc_detectMargin" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_detectMargin" ((Maybe Double -> f (Maybe Double))
 -> ListenCutOptions -> f ListenCutOptions)
-> ((Double -> f Double) -> Maybe Double -> f (Maybe Double))
-> (Double -> f Double)
-> ListenCutOptions
-> f ListenCutOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Iso' (Maybe Double) Double
forall a. Eq a => a -> Iso' (Maybe a) a
non Double
def_margin

silent_treshold :: Lens' ListenCutOptions Double
silent_treshold :: (Double -> f Double) -> ListenCutOptions -> f ListenCutOptions
silent_treshold = forall s t a b.
HasField "lc_silentTreshold" s t a b =>
Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_silentTreshold" ((Maybe Double -> f (Maybe Double))
 -> ListenCutOptions -> f ListenCutOptions)
-> ((Double -> f Double) -> Maybe Double -> f (Maybe Double))
-> (Double -> f Double)
-> ListenCutOptions
-> f ListenCutOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Iso' (Maybe Double) Double
forall a. Eq a => a -> Iso' (Maybe a) a
non Double
def_silent

silent_duration :: Lens' ListenCutOptions Double
silent_duration :: (Double -> f Double) -> ListenCutOptions -> f ListenCutOptions
silent_duration = forall s t a b.
HasField "lc_silentDuration" s t a b =>
Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_silentDuration" ((Maybe Double -> f (Maybe Double))
 -> ListenCutOptions -> f ListenCutOptions)
-> ((Double -> f Double) -> Maybe Double -> f (Maybe Double))
-> (Double -> f Double)
-> ListenCutOptions
-> f ListenCutOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Iso' (Maybe Double) Double
forall a. Eq a => a -> Iso' (Maybe a) a
non Double
def_duration

voice_track :: Lens' ListenCutOptions Int
voice_track :: (Int -> f Int) -> ListenCutOptions -> f ListenCutOptions
voice_track = forall s t a b. HasField "lc_voiceTrack" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_voiceTrack" ((Maybe Int -> f (Maybe Int))
 -> ListenCutOptions -> f ListenCutOptions)
-> ((Int -> f Int) -> Maybe Int -> f (Maybe Int))
-> (Int -> f Int)
-> ListenCutOptions
-> f ListenCutOptions
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Iso' (Maybe Int) Int
forall a. Eq a => a -> Iso' (Maybe a) a
non Int
def_voice

music_track :: Lens' ListenCutOptions (Maybe Int)
music_track :: (Maybe Int -> f (Maybe Int))
-> ListenCutOptions -> f ListenCutOptions
music_track = forall s t a b. HasField "lc_musicTrack" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_musicTrack"

cut_noise :: Lens' ListenCutOptions Bool
cut_noise :: (Bool -> f Bool) -> ListenCutOptions -> f ListenCutOptions
cut_noise = forall s t a b. HasField "lc_cutNoise" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"lc_cutNoise"

voice_track_map :: ListenCutOptions -> Text.Text
voice_track_map :: ListenCutOptions -> Text
voice_track_map = Text -> Text -> Text
forall a. Monoid a => a -> a -> a
mappend "0:" (Text -> Text)
-> (ListenCutOptions -> Text) -> ListenCutOptions -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting Text ListenCutOptions Text -> ListenCutOptions -> Text
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Int -> Const Text Int)
-> ListenCutOptions -> Const Text ListenCutOptions
Lens' ListenCutOptions Int
voice_track ((Int -> Const Text Int)
 -> ListenCutOptions -> Const Text ListenCutOptions)
-> ((Text -> Const Text Text) -> Int -> Const Text Int)
-> Getting Text ListenCutOptions Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> FilePath) -> Optic' (->) (Const Text) Int FilePath
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Int -> FilePath
forall a. Show a => a -> FilePath
show Optic' (->) (Const Text) Int FilePath
-> ((Text -> Const Text Text) -> FilePath -> Const Text FilePath)
-> (Text -> Const Text Text)
-> Int
-> Const Text Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const Text Text) -> FilePath -> Const Text FilePath
forall t. IsText t => Iso' FilePath t
packed)

specifyTracks :: ListenCutOptions -> [Text.Text]
specifyTracks :: ListenCutOptions -> [Text]
specifyTracks options :: ListenCutOptions
options =
  [ "-map"
  , "0:0"
  , "-map"  -- then copy only the voice track
  , ListenCutOptions -> Text
voice_track_map ListenCutOptions
options
  ]

parseFile :: Parser FileIO
parseFile :: Parser FileIO
parseFile = FilePath -> FilePath -> Maybe FilePath -> FileIO
FileIO
    (FilePath -> FilePath -> Maybe FilePath -> FileIO)
-> Parser FilePath -> Parser (FilePath -> Maybe FilePath -> FileIO)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM FilePath -> Mod OptionFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM FilePath
forall s. IsString s => ReadM s
str (FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "inFile" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help "The input video")
    Parser (FilePath -> Maybe FilePath -> FileIO)
-> Parser FilePath -> Parser (Maybe FilePath -> FileIO)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM FilePath -> Mod OptionFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM FilePath
forall s. IsString s => ReadM s
str (FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "outFile" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help "The output name without format")
    Parser (Maybe FilePath -> FileIO)
-> Parser (Maybe FilePath) -> Parser FileIO
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM FilePath -> Mod OptionFields FilePath -> Parser FilePath
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM FilePath
forall s. IsString s => ReadM s
str
            (  FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "workDir"
            Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help
                 "If specified will use this as temporary directory to store intermeidate files in, good for debugging. Needs to be absolute"
            )
          )

parseProgram :: Parser ProgramOptions
parseProgram :: Parser ProgramOptions
parseProgram =
  Mod CommandFields ProgramOptions -> Parser ProgramOptions
forall a. Mod CommandFields a -> Parser a
subparser (Mod CommandFields ProgramOptions -> Parser ProgramOptions)
-> Mod CommandFields ProgramOptions -> Parser ProgramOptions
forall a b. (a -> b) -> a -> b
$
    FilePath
-> ParserInfo ProgramOptions -> Mod CommandFields ProgramOptions
forall a. FilePath -> ParserInfo a -> Mod CommandFields a
command "listen" (Parser ProgramOptions
-> InfoMod ProgramOptions -> ParserInfo ProgramOptions
forall a. Parser a -> InfoMod a -> ParserInfo a
info (ListenCutOptions -> ProgramOptions
ListenCut (ListenCutOptions -> ProgramOptions)
-> Parser ListenCutOptions -> Parser ProgramOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ListenCutOptions
parseSound) (InfoMod ProgramOptions -> ParserInfo ProgramOptions)
-> InfoMod ProgramOptions -> ParserInfo ProgramOptions
forall a b. (a -> b) -> a -> b
$ FilePath -> InfoMod ProgramOptions
forall a. FilePath -> InfoMod a
progDesc "Cut out by listening to sound options. We listen for silences and cut out the parts that are silenced.")
    Mod CommandFields ProgramOptions
-> Mod CommandFields ProgramOptions
-> Mod CommandFields ProgramOptions
forall a. Semigroup a => a -> a -> a
<>
    FilePath
-> ParserInfo ProgramOptions -> Mod CommandFields ProgramOptions
forall a. FilePath -> ParserInfo a -> Mod CommandFields a
command "subtitles" (Parser ProgramOptions
-> InfoMod ProgramOptions -> ParserInfo ProgramOptions
forall a. Parser a -> InfoMod a -> ParserInfo a
info (FileIO -> ProgramOptions
GenerateSubtitles (FileIO -> ProgramOptions)
-> Parser FileIO -> Parser ProgramOptions
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FileIO
parseFile) (InfoMod ProgramOptions -> ParserInfo ProgramOptions)
-> InfoMod ProgramOptions -> ParserInfo ProgramOptions
forall a b. (a -> b) -> a -> b
$ FilePath -> InfoMod ProgramOptions
forall a. FilePath -> InfoMod a
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 ListenCutOptions
parseSound = FileIO
-> Maybe Int
-> Maybe Double
-> Maybe Double
-> Maybe Double
-> Maybe Int
-> Maybe Int
-> Bool
-> ListenCutOptions
ListenCutOptions
    (FileIO
 -> Maybe Int
 -> Maybe Double
 -> Maybe Double
 -> Maybe Double
 -> Maybe Int
 -> Maybe Int
 -> Bool
 -> ListenCutOptions)
-> Parser FileIO
-> Parser
     (Maybe Int
      -> Maybe Double
      -> Maybe Double
      -> Maybe Double
      -> Maybe Int
      -> Maybe Int
      -> Bool
      -> ListenCutOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FileIO
parseFile
    Parser
  (Maybe Int
   -> Maybe Double
   -> Maybe Double
   -> Maybe Double
   -> Maybe Int
   -> Maybe Int
   -> Bool
   -> ListenCutOptions)
-> Parser (Maybe Int)
-> Parser
     (Maybe Double
      -> Maybe Double
      -> Maybe Double
      -> Maybe Int
      -> Maybe Int
      -> Bool
      -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM Int
forall a. Read a => ReadM a
auto
            (FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "segmentSize" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. FilePath -> Mod f a
help "The size of video segments in minutes")
          )
    Parser
  (Maybe Double
   -> Maybe Double
   -> Maybe Double
   -> Maybe Int
   -> Maybe Int
   -> Bool
   -> ListenCutOptions)
-> Parser (Maybe Double)
-> Parser
     (Maybe Double
      -> Maybe Double
      -> Maybe Int
      -> Maybe Int
      -> Bool
      -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Double -> Parser (Maybe Double)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Double -> Mod OptionFields Double -> Parser Double
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM Double
forall a. Read a => ReadM a
auto
            (  FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "silentTreshold"
            Mod OptionFields Double
-> Mod OptionFields Double -> Mod OptionFields Double
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. FilePath -> Mod f a
help
                 "The treshold for determining intersting sections, closer to zero is detects more audio (n: https://ffmpeg.org/ffmpeg-filters.html#silencedetect)"
            )
          )
    Parser
  (Maybe Double
   -> Maybe Double
   -> Maybe Int
   -> Maybe Int
   -> Bool
   -> ListenCutOptions)
-> Parser (Maybe Double)
-> Parser
     (Maybe Double
      -> Maybe Int -> Maybe Int -> Bool -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Double -> Parser (Maybe Double)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Double -> Mod OptionFields Double -> Parser Double
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM Double
forall a. Read a => ReadM a
auto
            (  FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "silentDuration"
            Mod OptionFields Double
-> Mod OptionFields Double -> Mod OptionFields Double
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. FilePath -> Mod f a
help
                 "The duration before soemthing can be considered a silence (d: https://ffmpeg.org/ffmpeg-filters.html#silencedetect)"
            )
          )
    Parser
  (Maybe Double
   -> Maybe Int -> Maybe Int -> Bool -> ListenCutOptions)
-> Parser (Maybe Double)
-> Parser (Maybe Int -> Maybe Int -> Bool -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Double -> Parser (Maybe Double)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Double -> Mod OptionFields Double -> Parser Double
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM Double
forall a. Read a => ReadM a
auto
            (FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "detectMargin" Mod OptionFields Double
-> Mod OptionFields Double -> Mod OptionFields Double
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Double
forall (f :: * -> *) a. FilePath -> Mod f a
help "Margin seconds around detection")
          )
    Parser (Maybe Int -> Maybe Int -> Bool -> ListenCutOptions)
-> Parser (Maybe Int)
-> Parser (Maybe Int -> Bool -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option
            ReadM Int
forall a. Read a => ReadM a
auto
            (FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "voiceTrack" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. FilePath -> Mod f a
help "The track to detect the silences upon")
          )
    Parser (Maybe Int -> Bool -> ListenCutOptions)
-> Parser (Maybe Int) -> Parser (Bool -> ListenCutOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
          (ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Int
forall a. Read a => ReadM a
auto (FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "musicTrack" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. FilePath -> Mod f a
help "The track to integrate"))
    Parser (Bool -> ListenCutOptions)
-> Parser Bool -> Parser ListenCutOptions
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod FlagFields Bool -> Parser Bool
switch
          (FilePath -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long "cutNoise" Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod FlagFields Bool
forall (f :: * -> *) a. FilePath -> Mod f a
help "Whether to cut noise instead of silence")