How to use Sox for all files in a directory - shell

How do I change the sample rate for every file in the folder?
The following code converts the files, but it erases the file. After this command, every wav file is empty.
for i in wav/*.wav; do
sox -r 8000 -e unsigned -b 16 -c 1 "$i" "$i"
done
How do I run the code to every file in the directory?

Something like:
for i in wav/*.wav; do
sox -r 8000 -e unsigned -b 16 -c 1 "$i" "$i_modified"
done

Related

GUID appended for FFMPEG output file name

Is it possible to append a GUID to the output file?
I am running:
ffmpeg -i .\Tst.mp4 -filter:v "select='gt(scene,0.5)',showinfo" -vsync 0 -s 120x68 keyframe%05d.jpg
Which produces a series of files. I need to append a GUID to every file name.
I don't believe it is possible with ffmpeg. However, you can use the MD5 muxer on the existing JPG files to provide 128-bit psuedo-UUID:
ffmpeg -v error -i "$f" -f hash -f md5 -
Result:
MD5=aa8f01566a88feb762337de3cc81f36
Bash example:
for f in *.jpg; do hash="$(ffmpeg -v error -i "$f" -f hash -f md5 -)"; mv "$f" "${f%.*}_${hash:5}.jpg"; done
Result:
keyframe_00001_aa8f01566a88feb762337de3cc81f36.jpg
keyframe_00002_49cbb3ea81acfd57edda9955b3f8ed6.jpg
keyframe_00003_31711067199dafd28a6504ec4a22e05.jpg
Not a true UUID but fine if you just need a unique identifier.

bash variable changes in loop with ffmpeg

I wrote a skript to quickly create short preview clips from vides I recorded on timestamps that I found worth checking out later for cutting.
My file with the timestamps is written like this
FILE_NAME1#MM:SS MM:SS
FILE_NAME2#MM:SS MM:SS MM:SS MM:SS
example:
MAH01728#02:47 03:34 03:44 05:00 06:08 06:55
The script looks like this:
#!/bin/bash
while read f
do
file=$(echo $f | cut -d"#" -f1)
filename=${file}".MP4"
timestamps=$(echo $f | cut -d"#" -f2)
for time in $timestamps
do
ffmpeg -ss 00:${time}.0 -i "orig/${filename}" -c copy -t 10 "preview/${file}_${time}.MP4"
done
done < $1
The script gets half of the previews that I want and on the other the filename is messed up and ffmpeg complains that the file is not found:
orig/714.MP4: No such file or directory
orig/00:58 01:25.MP4: No such file or directory
So I modified the script for trouble shooting and just put an echo in front of the ffmpeg command - now all file names are correct. What am I missing?
ffmpeg -ss 00:01:47.0 -i orig/MAH01714.MP4 -c copy -t 10 preview/MAH01714_01:47.MP4
ffmpeg -ss 00:02:00.0 -i orig/MAH01713.MP4 -c copy -t 10 preview/MAH01713_02:00.MP4
ffmpeg -ss 00:00:58.0 -i orig/MAH01712.MP4 -c copy -t 10 preview/MAH01712_00:58.MP4
ffmpeg -ss 00:01:25.0 -i orig/MAH01712.MP4 -c copy -t 10 preview/MAH01712_01:25.MP4
ffmpeg reads from standard input, consuming data from $1 that was intended for the read command at the top of the loop. Redirect its standard input from /dev/null:
while IFS="#" read file timestamps; do
filename="$file.MP4"
for time in $timestamps; do
ffmpeg -ss 00:${time}.0 -i "orig/${filename}" \
-c copy -t 10 "preview/${file}_${time}.MP4" < /dev/null
done
done < "$1"
echo does not read from standard input, which is why your modification made it appear to be working correctly.

Pass stdin to plistbuddy

I have a script to show the content of the Info.plist of .ipa files:
myTmpDir=`mktemp -d 2>/dev/null || mktemp -d -t 'myTmpDir'`
unzip -q "$1" -d "${myTmpDir}";
pathToFile=${myTmpDir}/Payload/*.app/Info.plist
/usr/libexec/PlistBuddy -c "Print" ${pathToFile}
With large files this can take some time until they are extracted to the temp folder just to read a small Info.plist (xml) file.
I wondered if I can just extract Info.plist file and pass that to plistbuddy? I've tried:
/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< \
$(unzip -qp test.ipa Payload/*.app/Info.plist)
but this yields
Unexpected character b at line 1
Error Reading File: /dev/stdin
The extraction is working fine. When running unzip -qp test.ipa Payload/*.app/Info.plist I get the output of the Info.plist file to the terminal:
$ unzip -qp test.ipa Payload/*.app/Info.plist
bplist00?&
!"#$%&'()*+5:;*<=>?ABCDECFGHIJKXYjmwxyIN}~N_BuildMachineOSBuild_CFBundleDevelopm...
How can I pass the content of the Info.plist to plistbuddy?
Usually commands support "-" as a synonym of stdin, but this PlistBuddy tool doesn't.
But you can still extract just one file from your ipa, save it as a temporary file, and then run PlistBuddy on that file:
tempPlist="$(mktemp)"
unzip -qp test.ipa "Payload/*.app/Info.plist" > "$tempPlist"
/usr/libexec/PlistBuddy -c Print "$tempPlist"
rm "$tempPlist"
I ended up with plutil as chepner suggested:
unzip -qp test.ipa Payload/*.app/Info.plist | plutil -convert xml1 -r -o - -- -

OSX equivalent of piping sound to linux's aplay

On Ubuntu I am able to use aplay to play sound generated live from a script by piping the output of my script to aplay's stdin :
./generate_sound.py | aplay -r 2000 -c2 -f MU_LAW
cat sample.wav | aplay
Is there a way to do the same from terminal in OSX? I think afplay doesn't support this ...
Maybe someone knows another OSX command line sound player that would do the trick?
I had high hopes for redirection/piping, but afplay /dev/stdin <<< $(generate_sound.py) failed for all the formats I tried. Sadly afplay doesn't let you specify the format, and so it tries instead to sniff it which probably involves seeking which doesn't work with pipes.
I think you'd better find another command line player. sox seems like a good candidate. And! It's installable via homebrew: brew install sox and you can pipe data to it like so:
cat whatever.raw | play -t raw -e floating-point -b 32 -c 2 -r 44100 -
To Listen to an FM station on a mac
rtl_fm -f 95.3e6 -M wbfm -s 200000 -r 48000 – | aplay -r 48k -f S16_LE
To record for 10s
export AUDIOSAMPLERATE=48000
export SAMPLERATE=200000
export FREQ="127.2m"
rtl_fm -f $FREQ -M am -s $SAMPLERATE -r $AUDIOSAMPLERATE | sox -r $AUDIOSAMPLERATE -t raw -e s -b 16 -c 1 -V1 - FILENAME.wav&
sleep 10
killall rtl_fm

bash script behaves differently when run from an SD card or from HD

I have this command in a bash script:
mv audio.mp3 $datadir/$newname
where $datadir is a directory created at the beginning of the script:
datadir=$(date +%Y-%m-%d_%H-%M)
mkdir -p $datadir
while the rest if the script is
wget -q "$url" -O audio.mp3
poddate=$(stat -c "%y" "audio.mp3"|awk '{print $1"_"$2}'|sed 's/\..*$//')
extmp3=.mp3
seprdr=_
newname=$podname$seprdr$poddate$extmp3
echo -e "${GREEN}\t$newname"
mv audio.mp3 $datadir/$newname
the script runs fine when it is located on the hard drive.
Now, if it is run from an SD card, I get the following error:
cannot move audio.mp3 to a subdirectory of itself
what is wrong?
thanks

Resources