I'm trying to write a bash script for Mac OSx Terminal to compress a series of GoPro .MP4 videos from the SDcard directly into a smaller .MP4s on a local network server. The GoPro saves .MP4s in the 100GOPRO folder on the card. After filming, I will through that folder and manually put .MP4s from each game into subfolders within the 100GOPRO folder, named A1, A2, A3, etc.
Folder structure
/GoPro/DCIM/100GOPRO/
-------/A1/
-----GX01xxx1.mp4
-----GX01xxx2.mp4
-------/A2/
-----GX01xxx3.mp4
-----GX01xxx4.mp4
-----GX01xxx5.mp4
-----GX01xxx6.mp4
...etc
I would like then like to run a script from the 100GOPRO folder that will do these steps:
I'm getting hung up on the dynamic path to the subfolder's file.txt. My code just creates a file.txt in the 100GOPRO folder, and appends all the subfolder contents into that single long combined text file. The output then would create a correct first MP4, but second MP4 contains folder 1 and 2, then 3 contains 1, 2, and 3, etc.
Here's the script I ran:
#!/bin/bash
for f in A*/*.mp4 ; do
echo file \'$f\' >> list.txt ;
done && ffmpeg -f concat -safe 0 -i list.txt /Volume/Server/Videos/A$f.mp4 && rm list.txt
Clearly, failing in how that path for echo to save in the subfolder A*, how to call that subfolder's file.txt as the input for ffmpeg, and how to name the output after the folder.
Thanks for any help you can offer.
Basically you need to get the directories, and then make the list of files for that directory. You could use find
if you want more control, or a shell glob for simplicity (but this could accidentally match against other files).
for d in $(find . -maxdepth 1 -type d -name 'A*'); do
printf "file '%s'\n" $(cd $d && echo *.mp4) > $d/inputs.txt
ffmpeg -f concat -safe 0 -i $d/inputs.txt /Volume/Server/Videos/${d:2}.mp4
done
or the following loop using a shell glob:
for d in A*; do
# same code as above
done
A*
, and limited to subdirectories only 1-level deep; note, specifying a directory(the .
) is necessary on MacOS when using the default find command (BSD flavour), but with the GNU flavour (installed with brew or on Linux) the default directory is the current directory (.
)ffmpeg
expects the file paths to be relative to the list, we cd
into the directory in a subshell, and generate the list of files with the glob *.mp4
, and the printf
formats that into a file list but iterating over itffmpeg
command is as you specified, the output filename uses the directory name, except it trims the first two characters (transforming ./A1
-> A1
)