chebro/discord-voice-recorder

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:

  1. pm2 (installation is global):
sudo npm install pm2@latest -g
  1. 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

  1. Create a new directory inside the app root directory and name it mp3

  2. 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 🍷