For Loop and Multiple Commands in .bashrc - bash

I'm looking for a way to run two commands with a for loop as an alias in my .bashrc. Currently I have this:
alias finpeg="mkdir outdir; for i in *.mp4; do (ffmpeg -i %i -ar 22050 outdir/$i; done"
Running these commands separately in the terminal works fine but I can't seem to get it to work as an alias. Any thoughts?
Thanks,
Mitchell

Related

Bash: FFmpeg: Automate Album Art Tagging

Every one of my music folders are set up like Artist > Year Album >
Track 01.flac
Track 02.flac
Track 03.flac
folder.jpg, jpeg, png, etc
And what I need to do is if folder.* is available.
if [ -f folder.* ]; then
Run this command to set smaller size without replacing the original photo.
for small in folder.*
convert $small -resize 1000x1000 temp$small
Then run these commands on every file to automatically add the smaller sized cover to each audio file's tagging.
ffmpeg -i TRACK.flac -i SMALLFOLDER.* -map a -map 1:v -disposition:v attached_pic -metadata:s:v comment="Cover (Front)" -codec copy TRACKWITHART.flac
&& rm TRACK.flac
&& mv TRACKWITHART.flac TRACK.flac
&& rm temp$small
Last little bit there is me cleaning up. I'm having trouble piping commands into one another with this and not the most experienced with that sort of thing.
And also, if it's not available like above, will need to extract it from the first audio file by finding it.
else
find . -name "*.flac" -print -quit
And extracting it with this command.
ffmpeg -i TRACK.flac -vf scale=1000:1000 -an FOLDER.png
Then run the other commands above.
Now I don't know if anyone is familiar with FFmpeg but it's actually kind of nightmare because it's not necessarily for audio tagging but I don't know anything else to handle this kind of automated album art task in the terminal. If anyone can point me more in the right direction with a better CLI utility, that'd be awesome or just help with this bash scripting. You can see I'm fairly familiar with the terminal and getting some things done by searching the web but putting them altogether in a bash script is very difficult for me to understand, if anyone has some links for specifically this, that would be much appreciated.
You have the general right idea of how to do it.
The wooledge BashGuide is pretty much the best place to start when learning bash scripting. It's very accessible, and it directly addresses a lot of the pitfalls that beginners are susceptible to when writing scripts.
ALWAYS quote your variables when you are using them to store filenames/paths. You need to write your script as if every path/filename will have spaces, newlines, special characters, etc. Quoting your variables will go a long way towards preventing any chaos when your script runs.
Here is your code fixed up and thrown together into a working script:
#!/bin/bash
# check for album art file,
# if none, extract from first flac w/ ffmpeg
# exit script if ffmpeg fails
[[ -f folder.* ]] ||
{ tracks=(*.flac)
ffmpeg -i "${tracks[0]}" -vf scale=1000:1000 -an folder.png \
|| exit 1 ; }
# define an array of all folder.* files
albumart=(folder.*)
ffmpeg -i "${albumart[0]}" -vf scale=1000:1000 "tmp_${albumart[0]}" \
|| exit 1
# use the first element of the array,
# in case there are multiple folder.* files.
# exit if ffmpeg gives error code
for track in *.flac; do
ffmpeg -i "$track" -i "tmp_${albumart[0]}" -map a -map 1:v -disposition:v attached_pic -metadata:s:v comment="Cover (Front)" -codec copy "tmp_${track}" \
&& rm "$track" \
&& mv "tmp_${track}" "$track"
done
rm "tmp_${albumart[0]}"
I took the liberty of changing your convert line of image-resizing code so that it is instead handled by ffmpeg, since I am unfamiliar with "convert". If it is a script or binary you use, you will want to edit this line (keeping the new input & output variables intact).
This script does not need any arguments, and it will loop through and add the album art & metadata to all .flac files in your current directory. It is not designed to work recursively; you will need to cd into & run the script in each directory.

FFMPEG pipe input filenames from command line on windows

I am concatenating a bunch of files on a windows 10 box into a single file using "ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4". This works fine when I generate list.txt in the required format.
What I am wanting is to not have to generate the file first and instead pipe the filenames in as the examples here show for *nix.
I have tried as follows "ffmpeg -f concat safe 0 -i <(for %i in (*.ts) do #echo file '%i') -c copy output.mp4" but I get "The system cannot find the file specified.".
Any idea's how to make this work?
Command substitution on Unix...
ffmpeg -i $(some-command-that-generates-an-url/path) [...]
...is possible on Windows through a for-loop:
FOR /F "delims=" %A IN ('some-command-that-generates-an-url/path') DO ffmpeg -i %A
Process substitution on the other hand, as you describe, isn't possible on Windows. Temporary files are inevitable.

How to execute HandbrakeCLI from script?

I'm trying to execute a script that runs a Handbrake video conversion.
If I run the following command from the terminal, it works fine:
HandbrakeCLI -i inputtestfile.mp4 -o outputtestfile.mp4 -z "Preset"
If I put this into a .sh script (and give the script execution rights using chmod a+x), I get the following error:
HandbrakeCLI: Command not found
If I then put the full path to HandbrakeCLI, it then works, for example:
/usr/local/Cellar/handbrake/1.2.0/bin/HandBrakeCLI -i inputtestfile.mp4 -o outputtestfile.mp4 -z "Preset"
However, the above method is inconvenient because every time I update Handbrake to a new version, I'll have to update the script.
How can I add Path (I think this is right), to the script, so I can just use:
HandbrakeCLI -i inputtestfile.mp4 -o outputtestfile.mp4 -z "Preset"
Thanks
You can begin the .sh script with:
PATH=$PATH:/usr/local/Cellar/handbrake/1.2.0/bin
path is an environment variable that affects where sh would look unqualified files names (commands) from.
And for the changing version you can parse HandBrake --version output and use it as a variable instead of 1.2.0 string in PATH.

Mac equivalent of arecord command?

I've been googling around for the past hour but haven't found anything reliable yet.
I am wondering if there is a mac equivalent of the arecord command that would work, for example, in the following example:
sox -t .wav "|arecord -d 2" -n stat
You can natively use the utility afplay to play audio files from command line...
afplay sound.wav
You can use sox to record (avalable from macports and probably from Homebrew)
sox -d recording.wav

Mac Terminal (Bash) batch program to get multimedia file info using ffmpeg

I have a Mac computer. Usually all my batch programming is done on my PC. So I tried to create what I assumed would be a simple equivalent using a Mac shell. Obviously as you all know that was foolish of me to think that. After 2 days of scowering the web I found the closest thing I could to what I was looking for. But no, this doesn't work either.
All I'd like to do is throw a multimedia file onto the script, and have the terminal give me the ffmpeg info output. In my searching I did find this "$#" which as far as I can tell is the windows bat equivalent of %*. Meaning you can throw files on the script and the script refers to those files as variables which can be processed. So I believe what I want to do is possible.
Again the code at the bottom is just to look through the current directory of all .mov files and run ffmpeg. It doesn't work. But.. if no one can help me figure out the actual thing I'd like to do then I'd settle with something like below that does actually work.
#!/bin/bash
FFMPEG=/Applications/ffmpeg
FIND=/usr/bin/find
FILES=$(${FIND} . -type f -iname "*.mov")
if [ "$FILES" == "" ]
then
echo "There are no *.mov file in $(pwd) directory"
exit 1
fi
for f in *.mov
do
$FFMPEG -i "$f"
done
If someone can please help me figure this out I'd really appreciate it. Thank you in advance! Jules
I just found this solution from the "similar questions" sidebar, which is similar to the script above, so again, not completely what I wanted but.. didn't matter, didn't work for me. How to batch convert mp4 files to ogg with ffmpeg using a bash command or Ruby
.command files don't receive dropped files as input.
You might just open a Terminal window, type for f in, drop the files on the window, and type ; do ffmpeg -i "$f"; done.
Or save a script like this as an application in AppleScript Editor:
on open argv
set paths to ""
repeat with f in argv
set paths to paths & quoted form of POSIX path of f & " "
end repeat
tell application "Terminal"
do script "for f in " & paths & "; do ffprobe -i \"$f\"; done"
activate
end tell
end open
ffprobe -i is like ffmpeg -i but it doesn't show an error like At least one output file must be specified.
Edit: you could also use Platypus:
Set the script to something like for f; do ffprobe -i "$f"; done.
This might do it:
for FILE in "${#}"
do
/Applications/ffmpeg -i "$FILE"
done

Resources