Auto Convert PCM File to MP3?
chebro opened this issue · 4 comments
Since FFmpeg is a dependency is it possible to convert the output file to MP3 format? Will be easier to manage, thanks!
On the commandline this can be done using ffmpeg -f s16le -ar 44.1k -ac 2 -i file.pcm file.mp3
Thanks! I guess that solves it for now. Closing the issue.
Here are 2 shells you can use in Linux
Things you need:
- pm2 (installation is global):
sudo npm install pm2@latest -g
- pm2 log-rotate (optional/recommended):
pm2 install pm2-logrotate
Note: I think it's better if you install it from the app root directory but it may not be necessary
-
Create a new directory inside the app root directory and name it
mp3
-
This script https://raw.githubusercontent.com/ChaoticWeg/discord.sh/master/discord.sh to send the mp3 via Webhook to your channel (optional)
How to run
If you have the bot running, stop it and restart it with:
pm2 start index.js --name DVRBot --time
Note: Here DVRBot
is the chosen name for your app/bot in the pm2 list of processes. You can name it whatever you like.
pm2 will create a log file. You can tail it using:
tail -f -n 100 /home/<user>/.pm2/logs/DVRBot-out.log
Once you have the bot online in Discord, then proceed below
Script 1:
Note 1: Change directory paths accordingly.
Note 2: You can create a dedicated Webhook from your Discord server that will be used by the script for sending the mp3 file at the end of the process.
#!/bin/bash
APP_DIR="/home/ubuntu/discord-voice-recorder"
REC="$APP_DIR/recordings"
MP3="$APP_DIR/mp3"
LOG="/home/ubuntu/.pm2/logs/DVRBot-out.log"
WEBHOOK="https://discord.com/api/webhooks/<YOUR_WEBHOOK_HERE>"
printdate() {
gawk '{ print strftime("%Y-%m-%d %T:"), $0 }'
}
while read LOGLINE
do
echo " "
echo "recording stopped" | printdate >>$LOG
echo $LOGLINE
if [ "$(ls -A $REC)" ]; then
echo "items found! directory $REC is not empty!"
else
echo "nothing! directory $REC is empty!"
break
fi
echo " "
echo "starting new merge of audio files in $REC..." | printdate >>$LOG
node $APP_DIR/bin/merge.js
wait
sleep 5
echo " "
echo "ffmpeg will now convert pcm to mp3... " | printdate >>$LOG
echo " "
DATE=$(date "+%Y-%m-%dT%H.%M.%2N")
ffmpeg -f s16le -ar 48000 -ac 2 -i $REC/merge.pcm $MP3/recording-$DATE.mp3
wait
wait
sleep 5
echo "conversion complete!" | printdate >>$LOG
echo " "
echo "sending mp3 to discord channel #general..."
echo " "
$APP_DIR/discord.sh --webhook-url="$WEBHOOK" --file $MP3/recording-$DATE.mp3 --username "My Bot" --text "Hey boss, here's the recording in mp3 format!"
wait
echo " "
echo "removing old pcm files from $REC..."
rm -f $REC/*
echo " "
echo "showing $MP3 directory:"
echo " "
ls -ltr $MP3
echo " "
break
done < <(tail -F -n 0 $LOG | grep --line-buffered "STOPPED RECORDING")
KILL_TAIL=`ps -ef | awk '/tail.*DVRBot-out.log/ && !/awk/ {print $2}'`
kill -9 $KILL_TAIL
wait
pkill -f monitor_stop_rec.sh
wait
Once you have created script 1, run it "manually" from the app root directory:
./script1.sh
Record something from Discord and monitor the script to make sure there are no errors.
Script 2:
Note: Change directory paths accordingly.
#!/bin/bash
# > /dev/null 2>&1
MAIN_DIR="/home/ubuntu/discord-voice-recorder"
SCRIPT="$MAIN_DIR/monitor_stop_rec.sh" #this is script 1 file name (from above)
DATE=`date +"%Y-%m-%d %T:"`
VOICEREC_PROC=`pgrep -f $MAIN_DIR/monitor_stop_rec.sh`
if [ -n "$VOICEREC_PROC" ]
then
echo "$DATE Success! discord voice recorder process is currently running!"
exit 0
else
echo "$DATE Warning! discord voice recorder process is not running. starting now..."
nohup $SCRIPT &
fi
Set a Cron job for Script 2:
Once you have created the above scripts, and have tested script 1 is working properly, then just create the following cron job which will start the process automatically:
# on every minute, will check if discord-voice-recorder process is down, if it is then it will bring it up
* * * * * /bin/bash /home/ubuntu/discord-voice-recorder/check_DVRBot_monitor_stop_rec.sh > /dev/null 2>&1
IMPORTANT: Before recording from Discord, you must empty the recordings/
directory. This is only required once, when you start the above process for the first time.
Quite an interesting solution! Looking through this, I'm wondering if polling to see if the script is running/is recording can be eliminated by watching the recordings directory using inotify
or similar.
Maybe even easier, we just call ffmpeg using the child_process
module after the bot has done recording 🍷