{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -w #-}
module Cut.Lib
( entryPoint
, combineDir
)
where
import Control.Lens
import Control.Monad
import Control.Monad.Catch
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift
import Cut.Analyze
import Cut.CutVideo
import Cut.Ffmpeg
import Cut.Options
import Cut.SplitVideo
import Data.Bifunctor
import Data.Either
import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import Data.Text.Lens
import Options.Applicative
import Options.Generic
import Shelly hiding ( FilePath )
import System.IO.Temp
import Text.Regex.TDFA hiding ( empty
, extract
)
entryPoint :: (MonadMask m, MonadUnliftIO m) => m ()
entryPoint = catch main
$ \exec -> liftIO (print ("Uncaught exception: ", exec :: SomeException))
main :: (MonadMask m, MonadUnliftIO m) => m ()
main = do
options <- liftIO readSettings
liftIO $ putStr "started with options: "
liftIO $ print options
parsed <- detect options
case options ^. work_dir of
Nothing ->
withTempDirectory "/tmp" "streamedit" $ liftIO . runEdit options parsed
Just x -> liftIO $ runEdit options parsed x
runEdit :: Options -> [Interval Sound] -> FilePath -> IO ()
runEdit options parsed temp = do
extract options temp parsed
shelly $ combineDir options temp
getMusic options temp
combineDir :: Options -> FilePath -> Sh ()
combineDir options temp = do
res <- lsT $ fromText $ Text.pack temp
let paths :: Text
paths = Text.unlines $ flip (<>) "'" . ("file '" <>) <$> res
writefile (fromText $ Text.pack $ temp <> "/input.txt") paths
combine temp
readSettings :: IO Options
readSettings = customExecParser (prefs showHelpOnError) $ info
parseRecord
(fullDesc <> Options.Applicative.header "Cut the crap" <> progDesc
"Automated video extracting, can cut out silences"
)
musicFile :: FilePath
musicFile = "music.mp3"
withMusicFile :: FilePath
withMusicFile = "combined.mkv"
getMusic :: Options -> FilePath -> IO ()
getMusic opt' tempfiles = do
res <- case opt' ^. music_track of
Nothing -> pure $ Text.pack combinedFile
Just x -> do
shelly $ ffmpeg $ args x
shelly $ combineMusic tempfiles
pure $ Text.pack (tempfiles <> "/" <> withMusicFile)
putStrLn "done get music"
shelly $ cp (fromText res) (opt' ^. out_file . packed . to fromText)
pure ()
where
combinedFile = tempfiles <> "/" <> combineOutput
args x' =
[ "-i"
, opt' ^. in_file . packed
, "-map"
, "0:" <> Text.pack (show x')
, Text.pack (tempfiles <> "/" <> musicFile)
]
combineMusic :: FilePath -> Sh ()
combineMusic tempfiles = void $ ffmpeg args
where
args =
[ "-i"
, Text.pack $ tempfiles <> "/" <> combineOutput
, "-i"
, Text.pack $ tempfiles <> "/" <> musicFile
, "-filter_complex"
, "[0:a][1:a]amerge=inputs=2[a]"
, "-map"
, "0:v"
, "-map"
, "[a]"
, "-c:v"
, "copy"
, "-c:a"
, "mp3"
, "-ac"
, "2"
, "-shortest"
, Text.pack (tempfiles <> "/" <> withMusicFile)
]