{"version":3,"sources":["jsdelivr-header.js","/npm/videos-converter@0.1.2/src/videosConverter.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC6BA,MAAM,GAAgB,QAAQ,OACxB,UAAE,WAAc,QAAQ,iBAexB,mBAAqB,GACrB,WAAqB,MACrB,YAAqB,OAGrB,qBAA0B,OAC1B,wBAA0B,SAGJ,IAAxB,QAAQ,KAAK,QAAgB,QAAQ,KAAK,OAAS,KACnD,QAAQ,MAAM,mDAAmD,QAAQ,KAAK,OAAS,iBACvF,YACA,QAAQ,KAAK,IAIjB,MAAO,SAAU,WAAY,eAAgB,WAAa,QAAQ,KAC5D,aAAoD,KAAK,kBACzD,cAAoD,gBAAgB,UAb1C,QAchC,QAAQ,IAAI,sDAAsD,gCAGlE,mBAAmB,eAGnB,MAAM,gBAAkB,QAAQ,SAChC,IAAI,WAAoB,EACpB,gBAAoB,EACxB,MAAM,WAAkB,GAAG,YAAY,cAqDvC,SAAS,wBAAwB,GAC7B,OAAQ,EAAQ,KAAO,MAAM,QAAQ,EACzC,CAEA,SAAS,qBAAqB,GAC1B,OAAQ,EAAO,GAAM,EAAO,GAAK,KAAM,QAAQ,EACnD,CAEA,SAAS,gBAAgB,EAAW,GAChC,OAAkB,OAAd,GAAoC,KAAd,QAAkC,IAAd,EACnC,EAGJ,CACX,CAEA,SAAS,uBAAuB,EAAU,GACtC,OAAO,OAAO,GAAU,QAAQ,OAAQ,GAAG,QAC/C,CAEA,SAAS,QAAQ,GAEb,MAAO,SAAS,KAAK,OAAO,GAChC,CAEA,SAAS,mBAAmB,GAExB,UAAU,EACd,CAEA,SAAS,UAAU,GACf,IACI,GAAG,UAAU,EACjB,CAAE,MAAO,GACL,GAAiB,WAAb,EAAI,KAAmB,MAAM,CACrC,CACJ,CAEA,SAAS,YACL,QAAQ,IAAI,sFAChB,CA3FA,WAAW,SAAQ,IAEf,GAAI,QAAQ,GAAW,CACnB,aACA,MAAM,EAAiB,uBAAuB,EA5BtB,SA+BxB,GAAI,GAAG,WAAW,GAAG,iBAAiB,KAAmB,CAErD,MAAM,EAAQ,GAAG,SAAS,GAAG,iBAAiB,KAC9C,QAAQ,IAAI,GAAG,wBAAwB,iBAAiB,MAAmB,wBAAwB,EAAY,4BACnH,KAAO,CAEH,kBACA,MAAM,EAAsB,QAAQ,SAGpC,UAAU,SAAU,CAAC,KAAM,EAAU,OAAQ,UAAW,OA/CzC,GA+CqE,OA9CrE,MA8CyF,OAAQ,OAAQ,UA7CzG,OA6CiI,GAAG,iBAAiB,MAGpK,MACM,EAAiB,wBADA,GAAG,SAAS,GACgC,MAE7D,EAAiB,wBADA,GAAG,SAAS,GAAG,iBAAiB,KACa,MAC9D,GAAmB,EAAgB,EAAgB,KAAK,QAAQ,GAGtE,QAAQ,IAAI,GAAG,eAAe,iBAAiB,MAAmB,WAAsB,SAAqB,oBAA4B,qBAAqB,QAAQ,OAAO,eACjL,CACJ,KAIoB,IAApB,gBACmB,IAAf,WACA,QAAQ,IAAI,mDAEZ,QAAQ,IAAI,0CAA0C,qDAG1D,QAAQ,IAAI,GAAG,uCAAuC,qBAAqB,QAAQ,OAAO,8BAC1F,QAAQ,IAAI,qFAAkH,qCAIlI,QAAQ,KAAK","file":"/npm/videos-converter@0.1.2/src/videosConverter.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/videos-converter@0.1.2/src/videosConverter.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n *             videosConverter\n *\n * @version    0.1.2\n * @date       2018-09-06\n *\n * @author     Alexandre Bonneau\n * @summary    Converts videos made by your phone into x265 ones\n * @link       https://gitlab.com/AnotherLinuxUser/videosConverter\n *\n * @license    Released under the GPLv3 License\n *\n *\n * Converts all the files given as a parameter (or the mp4 files inside\n * the directory given as a parameter), to the x265 format.\n * Move those x265 videos into a folder names 'x265', and rename the\n * files with `_x265` at the end of their name.\n *\n *\n * Copyright © 2018 Alexandre Bonneau <alexandre.bonneau@linuxfr.eu>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nconst fs            = require('fs');\nconst { spawnSync } = require('child_process');\n\n/* global process */\n/* eslint no-console: 0 */\n\n// ffmpeg configuration\n/*\n * The range of the CRF scale is 0–51, where 0 is lossless, 23 is the default, and 51 is worst quality possible.\n * A lower value generally leads to higher quality, and a subjectively sane range is 17–28. Consider 17 or 18 to\n * be visually lossless or nearly so; it should look the same or nearly the same as the input but it isn't\n * technically lossless.\n * The range is exponential, so increasing the CRF value +6 results in roughly half the bitrate / file size,\n * while -6 leads to roughly twice the bitrate.\n */\n//TODO Add the following variables as cmdline parameters\nconst constantRateFactor = 23; // 28\nconst audioCodec         = 'aac';\nconst presetSpeed        = 'slow'; // ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo\n\n// Script configuration\nconst defaultOutputDirName    = 'x265';\nconst defaultFilenameAddition = '_x265';\n\n// Check the arguments\nif (process.argv.length === 2 || process.argv.length > 4) {\n    console.error(`An invalid number of arguments has been passed (${process.argv.length - 2}). Aborting.`);\n    showUsage();\n    process.exit(1);\n}\n\n// Retrieve the folder name to parse for videos to convert\nconst [nodePath, scriptPath, filesOrFolders, outputDir] = process.argv;\nconst targetFolder                                      = `./${filesOrFolders}/`;\nconst outputDirName                                     = selectOutputDir(outputDir, defaultOutputDirName);\nconsole.log(`Listing and converting all the video files in the '${filesOrFolders}' directory...`);\n\n// Prepare the output folder\ncreateOutputFolder(outputDirName); //TODO First check that there are at least one file to be converted before creating the output folder\n\n// Convert all the video files\nconst globalStartTime = process.hrtime();\nlet videoCount        = 0;\nlet conversionCount   = 0;\nconst filesArray      = fs.readdirSync(targetFolder);\n\nfilesArray.forEach(fileName => {\n    // Test if the given file is a video\n    if (isVideo(fileName)) {\n        videoCount++;\n        const targetFilename = generateTargetFilename(fileName, defaultFilenameAddition);\n\n        // Before converting the video file, check that it does not already exists in the output folder. If it does, output a notice.\n        if (fs.existsSync(`${outputDirName}/${targetFilename}`)) {\n            // Get the video informations\n            const stats = fs.statSync(`${outputDirName}/${targetFilename}`);\n            console.log(`${videoCount}: The file ${outputDirName}/${targetFilename} (${convertBytesToMegaBytes(stats['size'])}Mio) already exists!`);\n        } else {\n            // Convert the video file\n            conversionCount++;\n            const conversionStartTime = process.hrtime();\n\n            // Run the command line synchronously\n            spawnSync('ffmpeg', ['-i', fileName, '-c:v', 'libx265', '-crf', constantRateFactor, '-c:a', audioCodec, '-b:a', '128k', '-preset', presetSpeed, `${outputDirName}/${targetFilename}`]);\n\n            // Get the video informations\n            const statsOriginal  = fs.statSync(fileName);\n            const sizeOriginal   = convertBytesToMegaBytes(statsOriginal['size']);\n            const statsGenerated = fs.statSync(`${outputDirName}/${targetFilename}`);\n            const sizeGenerated  = convertBytesToMegaBytes(statsGenerated['size']);\n            const ratioSize      = ((sizeGenerated / sizeOriginal) * 100).toFixed(2);\n\n            // Display the informations about the generated file\n            console.log(`${videoCount}: ${outputDirName}/${targetFilename} (${sizeOriginal}Mio -> ${sizeGenerated}Mio, ${ratioSize}%) generated in ${parseHrtimeToSeconds(process.hrtime(conversionStartTime))} seconds.`);\n        }\n    }\n});\n\n// Display the statistics\nif (conversionCount === 0) {\n    if (videoCount === 0) {\n        console.log(`No video files were converted. None were found.`);\n    } else {\n        console.log(`No new video files were converted. The ${videoCount} existing ones were already converted.`);\n    }\n} else {\n    console.log(`${conversionCount} videos converted in ${parseHrtimeToSeconds(process.hrtime(globalStartTime))} seconds.`); //TODO pluralize that string\n    console.log(`Command line used: \\`ffmpeg -i <fileName> -c:v libx265 -crf ${constantRateFactor} -c:a ${audioCodec} -b:a 128k ${outputDirName}/<targetFilename>\\``);\n}\n\n// End of the script\nprocess.exit(0);\n\n\n// ------------------------------------------------------\n// ------------------ Functions\n\nfunction convertBytesToMegaBytes(bytes) {\n    return (bytes / 1024 / 1024).toFixed(2);\n}\n\nfunction parseHrtimeToSeconds(hrtime) {\n    return (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);\n}\n\nfunction selectOutputDir(outputDir, defaultOutputDirName) {\n    if (outputDir !== null && outputDir !== '' && outputDir !== void(0)) {\n        return outputDir;\n    }\n\n    return defaultOutputDirName;\n}\n\nfunction generateTargetFilename(filename, filenameAddition) {\n    return String(filename).replace('.mp4', `${filenameAddition}.mp4`);\n}\n\nfunction isVideo(filename) {\n    //TODO Use better heuristics to check if the file is a video\n    return /\\.mp4$/.test(String(filename));\n}\n\nfunction createOutputFolder(dirname) {\n    //TODO Test if the output folder already exists\n    mkdirSync(dirname);\n}\n\nfunction mkdirSync(dirPath) {\n    try {\n        fs.mkdirSync(dirPath);\n    } catch (err) {\n        if (err.code !== 'EEXIST') throw err;\n    }\n}\n\nfunction showUsage() {\n    console.log(`Usage: nodejs videosConverter.js <folderContainingTheVideosToConvert> [<outputDir>]`);\n}\n\n"]}