├── README.md ├── ffmpeg-video-joiner.bat ├── join.bat └── screens ├── screen1.png ├── screen2.png ├── screen3.png └── screen4.png /README.md: -------------------------------------------------------------------------------- 1 | # ffmpeg-video-joiner-script 2 | 3 | ## Description: 4 | Batch script for searching and joining video segments into a single video. Developed for **itleague.kharkov.ua** needs. 5 | 6 | ## How it works 7 | The script uses a source path as a starting point. It goes through folders inside the source path, searches all video files inside that folders, sets them in time order, join them into single video (each folder - separate video) and save the result into an output folder. 8 | 9 | ## Dependencies: 10 | ffmpeg - https://ffmpeg.org/download.html 11 | 12 | Download the library, unpack it whereever you want and add the path to the `ffmpeg/bin` directory to the **PATH** variable. 13 | 14 | ## Usage: 15 | `ffmpeg-video-joiner path/to/source/folder` - uses passed path as a source 16 | 17 | `ffmpeg-video-joiner .` - (dot in the end) uses current folder as a source 18 | 19 | You can add the path to the `ffmpeg-video-joiner-script.bat` file to the PATH variable, then copy the `join.bat` file to your source folder, and then just run it there. 20 | 21 | ## Example: 22 | There is a source folder with 3 other folders: 23 | 24 | ![](https://github.com/sergeyvdovareize/ffmpeg-video-joiner-script/blob/master/screens/screen1.png) 25 | 26 | Each folder has video parts: 27 | 28 | ![](https://github.com/sergeyvdovareize/ffmpeg-video-joiner-script/blob/master/screens/screen2.png) 29 | 30 | Run the scipt with the source folder as a parameter: 31 | 32 | ![](https://github.com/sergeyvdovareize/ffmpeg-video-joiner-script/blob/master/screens/screen3.png) 33 | 34 | As a result we have 3 joined videos inside an output folder: 35 | 36 | ![](https://github.com/sergeyvdovareize/ffmpeg-video-joiner-script/blob/master/screens/screen4.png) 37 | 38 | ## Known issues: 39 | 40 | ffmpeg doesn't work with some specific symbols in names, for example `'`. 41 | -------------------------------------------------------------------------------- /ffmpeg-video-joiner.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | MODE 140,40 4 | 5 | :: config 6 | set list_prefix=__list.txt 7 | set videos_out=!full_matches_output 8 | set format=.mp4 9 | set source=%1 10 | set log_file=joiner.log 11 | 12 | :: flags 13 | set do_merge=1 14 | 15 | :: counters 16 | set found=0 17 | set merged=0 18 | set skipped=0 19 | 20 | cls 21 | echo ------------------------------------------------ 22 | echo -- LETS MERGE VIDEO SEGMENTS INTO FULL VIDEOS -- 23 | echo ------------------------------------------------ 24 | 25 | :: use current path as a source path if dot is passed 26 | if "%source%" == "." set source=%cd% 27 | 28 | :: check if source dir is not empty and exists 29 | if "%source%" == "" goto no_param 30 | if not exist %source% goto no_source 31 | 32 | :: get start time: 33 | for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( 34 | set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" 35 | ) 36 | 37 | cd /d %source% 38 | echo. >> %log_file% 39 | echo -- Joiner script started. Time: %time% >> %log_file% -- 40 | 41 | :create_lists 42 | echo. 43 | set msg=[source: %source%] 44 | echo %msg% 45 | echo %msg% >> %log_file% 46 | 47 | :: go through all folders and creates file lists for joining by ffmpeg 48 | echo. 49 | set msg=1. Go through all games to create file lists for joining 50 | echo %msg% 51 | echo %msg% >> %log_file% 52 | 53 | for /f "delims=" %%d in ('dir /ad /b %source%') do ( 54 | :: skip the output folder 55 | if not "%%d" == "%videos_out%" ( 56 | :: skip folder if there are no needed files 57 | if exist "%%d\*%format%" ( 58 | set /a found=found+1 59 | echo - create list: %%d 60 | echo - create list: %%d >> %log_file% 61 | (for /f "delims=" %%f in ('dir /b /od "%%d\*%format%"') do @echo file '%%f') > "%%d/%%d%list_prefix%" 62 | ) else ( 63 | echo - no %format% files inside folder '%%d' 64 | ) 65 | ) 66 | ) 67 | 68 | if %do_merge% == 0 goto finish 69 | 70 | :merge_parts 71 | :: go through all prepared games and join their videos based on their file list created earlier 72 | echo. 73 | set msg=2. Go through all games to merge videos 74 | echo %msg% 75 | echo %msg% >> %log_file% 76 | 77 | :: create output folder if it does not exist 78 | if not exist %videos_out% mkdir %videos_out% 79 | 80 | for /f "delims=" %%d in ('dir /ad /b') do ( 81 | :: skip output folder 82 | if not "%%d" == "%videos_out%" ( 83 | :: check if output video was joined and saved earlier 84 | if exist %videos_out%/%%d%format% ( 85 | :: skip earlier joined videos 86 | echo - file exists, skip: %videos_out%/%%d%format% 87 | echo - file exists, skip: %videos_out%/%%d%format% >> %log_file% 88 | set /a skipped=skipped+1 89 | ) else ( 90 | if exist "%%d\*%format%" ( 91 | :: do joining using ffmpeg lib and based on a filelist created on the step 1 92 | echo - merge video: %%d 93 | echo - merge video: %%d >> %log_file% 94 | ffmpeg -stats -v error -f concat -safe 0 -i "%%d/%%d%list_prefix%" -c copy "%videos_out%/%%d%format%" -y 95 | set /a merged=merged+1 96 | ) 97 | ) 98 | ) 99 | ) 100 | 101 | goto finish 102 | 103 | :no_param 104 | echo. 105 | echo ERROR: pass source folder as a parameter 106 | goto finish 107 | 108 | :no_source 109 | echo. 110 | echo ERROR: pass source folder as a parameter 111 | goto finish 112 | 113 | :finish 114 | :: get end time: 115 | for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( 116 | set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" 117 | ) 118 | 119 | :: get elapsed time: 120 | set /A elapsed=end-start 121 | 122 | :: show elapsed time: 123 | set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100 124 | if %hh% lss 10 set hh=0%hh% 125 | if %mm% lss 10 set mm=0%mm% 126 | if %ss% lss 10 set ss=0%ss% 127 | 128 | echo. 129 | echo Result: 130 | echo - found %found% videos 131 | echo - merged %merged% videos 132 | echo - skipped %skipped% videos 133 | echo - elapsed time: %hh%:%mm%:%ss% 134 | echo. 135 | 136 | echo Result: >> %log_file% 137 | echo - found %found% videos >> %log_file% 138 | echo - merged %merged% videos >> %log_file% 139 | echo - skipped %skipped% videos >> %log_file% 140 | echo - elapsed time: %hh%:%mm%:%ss% >> %log_file% 141 | echo ---------------------------------- >> %log_file% 142 | 143 | echo press any key to exit 144 | pause >nul -------------------------------------------------------------------------------- /join.bat: -------------------------------------------------------------------------------- 1 | :: add the path to the ffmpeg-video-joiner-script.bat file to the PATH variable first 2 | ffmpeg-video-joiner . 3 | -------------------------------------------------------------------------------- /screens/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergiiVdovareize/ffmpeg-video-joiner-script/a7d2bdefa7bba1a6c8f8648b2733acd6aac9a754/screens/screen1.png -------------------------------------------------------------------------------- /screens/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergiiVdovareize/ffmpeg-video-joiner-script/a7d2bdefa7bba1a6c8f8648b2733acd6aac9a754/screens/screen2.png -------------------------------------------------------------------------------- /screens/screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergiiVdovareize/ffmpeg-video-joiner-script/a7d2bdefa7bba1a6c8f8648b2733acd6aac9a754/screens/screen3.png -------------------------------------------------------------------------------- /screens/screen4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergiiVdovareize/ffmpeg-video-joiner-script/a7d2bdefa7bba1a6c8f8648b2733acd6aac9a754/screens/screen4.png --------------------------------------------------------------------------------