This page looks best with JavaScript enabled

Django Gource video and Gitlog

 ·  🎃 kr0m

In this article, we will explain how to generate a Gource-style video but with the peculiarity of inserting the text of Git logs as credits using ffmpeg. The idea is to generate the video every time we deploy our Django project.

As we have already mentioned, we will use the video generation script in the deploy script itself. For those who do not know which script we are talking about, we leave here the previous articles on Django:


We install the necessary software:

pkg install ffmpeg gource mediainfo xorg-vfbserver

The script in question is the following:

vi .scripts/generateCreditsVideo.sh

#!/usr/local/bin/bash
# pkg install ffmpeg gource mediainfo xorg-vfbserver(HeadLess)

echo ">> Generating Gitlog file"
echo " " > ~/gitlog.log

for i in $(seq 1 50); do
    echo " " >> ~/gitlog.log
done

echo "Credits:" >> ~/gitlog.log
echo " " >> ~/gitlog.log
echo ">> System Administrator: Kr0m" >> ~/gitlog.log
echo ">> WebPage Developer: Kr0m" >> ~/gitlog.log
echo ">> WebPage Design Consultants: Kalma" >> ~/gitlog.log
echo ">> JS Consultants: Fenollet, Fayu" >> ~/gitlog.log
echo " " >> ~/gitlog.log
echo "-------------------------------------------" >> ~/gitlog.log
echo " " >> ~/gitlog.log
echo "Git Logs:" >> ~/gitlog.log
echo " " >> ~/gitlog.log

cd /home/kr0m/rxWod/rxWodProject
git log --reverse --pretty=format:'%h -- %as %an: %s' >> ~/gitlog.log

for i in $(seq 1 11); do
    echo " " >> ~/gitlog.log
done

echo ">> Wrapping Gitlog file lines"
fold -w120 ~/gitlog.log > ~/gitlog_wrapped.log

echo ">> Generating Gource video file"
killall -9 Xvfb 2>/dev/null
Xvfb :99 &
export DISPLAY=:99
gource --highlight-all-users --time-scale 4.0 -o - | ffmpeg -hide_banner -loglevel error -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 ~/gource.mp4

cd
echo ">> Adding text lines to file"
# y=(h-text_h)/XXX*t -> XXX parameter controls text speed, depending of the length of our video we have to adjust the text speed consecuently
# High value -> Slower text speed

duration=$(mediainfo --Inform="Video;%Duration%" ~/gource.mp4)
# 1036s -> 1 txt speed unit
# N=duration/1036
N=$(echo "$duration / 1036" |bc)
ffmpeg -hide_banner -loglevel error -i ~/gource.mp4 -vf drawtext="fontcolor=white: fontsize=14: box=1: boxcolor=black@0.1: boxborderw=5: x=(w)/25: y=(h-text_h)/$N*t: textfile=$HOME/gitlog_wrapped.log" -y -codec:a copy ~/credits.mp4

echo ">> Adding audio"
if [ -f ~/credits.mp3 ]; then
    # If video is longer than audio, loop it
    ffmpeg -hide_banner -loglevel error -y -i ~/credits.mp4 -stream_loop -1  -i ~/credits.mp3 -map 0:v:0 -map 1:a:0 -shortest ~/creditsAudio.mp4
    echo ">> Adding fade in/out effects"
    VIDEO_DURATION=$(mediainfo --Inform="Video;%Duration%" creditsAudio.mp4)
    START_TIME=$(echo "scale=3;($VIDEO_DURATION-4000)/1000" | bc -q)
    
    #echo "VIDEO_DURATION: $VIDEO_DURATION"
    #echo "START_TIME: $START_TIME"
    
    ffmpeg -hide_banner -loglevel error -y -i ~/creditsAudio.mp4 -filter_complex "[0:v]fade=type=in:duration=4,fade=type=out:duration=4:start_time=$START_TIME[v];[0:a]afade=type=out:duration=4:start_time=$START_TIME[a]" -map "[v]" -map "[a]" ~/creditsAudioFadded.mp4
else
    echo "++ Audio file not found, continuing without audio"
    cp ~/credits.mp4 ~/creditsAudioFadded.mp4
fi

echo ">> Removing temporarily files"
rm ~/gitlog.log 2>/dev/null
rm ~/gitlog_wrapped.log 2>/dev/null
rm ~/gource.mp4 2>/dev/null
rm ~/credits.mp4 2>/dev/null
rm ~/creditsAudio.mp4 2>/dev/null

killall -9 Xvfb 2>/dev/null

if [ ! -d "/home/kr0m/rxWod/rxWodProject/assets/videos/" ]; then
    mkdir /home/kr0m/rxWod/rxWodProject/assets/videos/
fi

cp ~/creditsAudioFadded.mp4 /home/kr0m/rxWod/rxWodProject/assets/videos/creditsAudioFadded.mp4

Basically, it adds some custom text lines, adds Git logs, generates the video using Gource, interleaves the text with the video, and adds an audio track with a faded effect. It should be noted that video processing is a very heavy task and depending on the power of our server, it may take more or less time.

We assign the necessary permissions to the script:

chmod 700 .scripts/generateCreditsVideo.sh

We upload the audio track that we will use in the video:

scp credits.mp3 rxWod:/home/kr0m/

We run the script:

.scripts/generateCreditsVideo.sh

And we can see the resulting file:

ls -la /home/kr0m/rxWod/rxWodProject/assets/videos/creditsAudioFadded.mp4

-rw-r--r--  1 kr0m  kr0m  22732923 Apr  6 22:09 /home/kr0m/rxWod/rxWodProject/assets/videos/creditsAudioFadded.mp4

The final video will look like this:

We modify the deploy script so that every time we upload code to the repository and run the deploy script, the video will be regenerated:

vi .scripts/deploy.sh

#!/usr/local/bin/bash
cd /home/kr0m/rxWod/rxWodProject
git pull
/home/kr0m/.scripts/generateCreditsVideo.sh
cd ..
source bin/activate
pip install -r rxWodProject/requirements.txt
cd rxWodProject
python manage.py makemigrations
python manage.py migrate
django-admin makemessages -l es -d djangojs -i node_modules
cd rxWod
django-admin makemessages -l es
cd ..
#cd usersAuth
#django-admin makemessages -l es
#cd ..
django-admin compilemessages
cp locale/es/LC_MESSAGES/djangojs.mo rxWod/locale/es/LC_MESSAGES/djangojs.mo
#cp locale/es/LC_MESSAGES/djangojs.mo usersAuth/locale/es/LC_MESSAGES/djangojs.mo
yarn install
yarn prod-build
python manage.py collectstatic --noinput
sudo /usr/sbin/service daphne restart
If you liked the article, you can treat me to a RedBull here