Am 16.11.2017 um 12:46 schrieb Christian Alpen:
I changed the usleep 250 to sleep 0.000250 in mkvideo.
Now the short video_mwe.ly goes pretty fast.
ok
I have some further questions (if they still fit in here?):
1. Is the ./kptestpiano.sf2 desperately needed? As I couldn't get this
prerepuisite solved, I followed Karlin's tip
and replaced it with 'usr/share/sounds/sf2/FluidR3_GM.sf2'
/usr/share/sounds/sf2/FluidR3_GM.sf2 might be used as well as any other
soundfont you like.
2. Can the metronom be skipped by some command in the .ly-file? Or do I Have to
edit the mkvideo for that?
The attached updated version of the script implements a -noMetro command line
option.
3. Am I bound to 16:9 format, or is it possible for example to view an entire
A4 page?
Yes, you might any format you like. But I recommend to change
"VIDEORESOLUTION=1280x720" to a more reasonable value (e.g. 1280x1810) if you
want to use A4.
4. What about repeats? Right now I one part with repeats, that is only rendered
once. Of course there
is a workound with editing the video. But would it be possible to get this
done while generating the video?
Don't use repeats, it is not supported.
Knut
#!/bin/bash
######################################################################
# Copyright (C) 2016-2017 Knut Petersen (address@hidden)
#
# This is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
######################################################################
VERSION=2017-11-16
# FPS=n: video files will use n frames per second
# Currently FSP != 25 is broken. It's either ffmpeg or I am too
# blind to see my mistake ;-(
FPS=25
VIDEORESOLUTION=1280x720
PRESET=veryslow
AUDIOBITRATE=128k
# TITLETIME: number of seconds the title page shall be visible
TITLETIME=4.0
# AFTERTIME
AFTERTIME=6.666
# METRONOME: n != 0 enables generation of metronome ticks
METRONOME=1
# DEBUG: n != 0 turns on debugging mode (verbose output)
DEBUG=0
# CLEAN: n != 0 enables deletion of all temporary files
CLEAN=1
#
SOUNDFONTB=./kptestpiano.sf2
SOUNDFONTA=/usr/share/sounds/sf2/FluidR3_GM.sf2
SOUNDFONTS="$SOUNDFONTA $SOUNDFONTB"
FAIL=0
function weneedprog {
for P in $@; do
TMP=`which $P 2> /dev/null`
if [ "x" == "x$TMP" ]; then
echo We need $P but could not find it!
FAIL=$((FAIL+1))
fi
done
}
function weneeddata {
for P in $@; do
TMP=`ls -q $P 2> /dev/null`
if [ "x" == "x$TMP" ]; then
echo We need $P but could not find it!
FAIL=$((FAIL+1))
fi
done
}
echo This is mkvideo version $VERSION
for i in "$@"
do
case $i in
--noMetro)
echo not generating metronome ticks ...
METRONOME=0
;;
*)
;;
esac
done
echo checking dependencies ...
weneedprog ls sort tail uniq grep sed bc gs pdftk lilypond fluidsynth sox ffmpeg
weneeddata $SOUNDFONTS videohelper.notes
if [ $FAIL -ne 0 ]; then
echo $FAIL missing dependencies, aborting
exit 1
else
echo dependencies ok
fi
function checknotes {
grep "$1" videohelper.notes &> /dev/null
if [ $? -ne 0 ]; then
echo Fatal error: $2
exit 2
fi
}
grep "NOPAGEREPETITIONS" videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
echo "No video generation because \noPageRepetitions was used!"
exit
fi
echo checking videohelper.notes ...
checknotes "LILYSOURCE" "LILYSOURCE undefined"
checknotes "VIDEOSOURCE" "VIDEOSOURCE undefined"
checknotes "MIDISOURCE" "MIDISOURCE undefined"
checknotes "tempo" "no tempo definition"
checknotes "time" "no time definition"
checknotes "page 1 contains no music" "no title page defined"
checknotes "[0-9.]* page" "not a single page"
echo videohelper.notes ok
TDIR=`mktemp -d mkvideo-XXXXX`
eval `grep LILYSOURCE videohelper.notes`
eval `grep VIDEOSOURCE videohelper.notes`
eval `grep LASTMOMENT videohelper.notes`
grep VIDEORESOLUTION videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
eval `grep VIDEORESOLUTION videohelper.notes`
fi
grep PRESET videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
eval `grep PRESET videohelper.notes`
fi
grep AUDIOBITRATE videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
eval `grep AUDIOBITRATE videohelper.notes`
fi
MIDILIST=`grep MIDISOURCE videohelper.notes | sed -e
"s/MIDISOURCE=\([[:print:]]*\).midi/\1/" | sort | uniq | sed ':a;N;$!ba;s/\n/
/g'`
MOMENTLIST="`grep "[0-9.]* page" videohelper.notes | sed -e
"s/\([0-9.]*\)[[:space:]][[:print:]]*/\1/" | sed ':a;N;$!ba;s/\n/ /g'`
$LASTMOMENT"
COUNT=1
ARMOM=()
for VAL in $MOMENTLIST; do
ARMOM[COUNT]=$VAL
COUNT=$((COUNT+1))
done
if [ $DEBUG -ne 0 ] ; then
declare -p ARMOM
fi
TEMPOMOMENTLIST=`grep tempo videohelper.notes | sed -e
"s/\([0-9.]*\)[[:space:]]tempo[[:space:]]\([0-9.]*\)/\1 /" | sed
':a;N;$!ba;s/\n/ /g'`
COUNT=1
TMMOM=()
for VAL in $TEMPOMOMENTLIST; do
TMMOM[COUNT]=$VAL
COUNT=$((COUNT+1))
done
TMMOM[COUNT]=100000.0
if [ $DEBUG -ne 0 ] ; then
declare -p TMMOM
fi
TEMPOTIMELIST=`grep tempo videohelper.notes | sed -e
"s/\([0-9.]*\)[[:space:]]tempo[[:space:]]\([0-9.]*\)/\2 /" | sed
':a;N;$!ba;s/\n/ /g'`
COUNT=1
TTMOM=()
for VAL in $TEMPOTIMELIST; do
TTMOM[COUNT]=$VAL
COUNT=$((COUNT+1))
done
TTMOM[COUNT]=0.0
if [ $DEBUG -ne 0 ] ; then
declare -p TTMOM
fi
TEMPOS=`grep tempo videohelper.notes | wc | sed -e
"s/[[:space:]]*\([[:digit:]]*\)[[:print:]]*/\1/"`
if [ $DEBUG -ne 0 ] ; then
echo TEMPOS $TEMPOS
fi
PAGES=`grep page videohelper.notes | wc | sed -e
"s/[[:space:]]*\([[:digit:]]*\)[[:print:]]*/\1/"`
PAGES=$((PAGES-1))
if [ $DEBUG -ne 0 ] ; then
echo PAGES $PAGES
fi
MOMENTS=$((PAGES+1))
if [ $DEBUG -ne 0 ] ; then
echo MOMENTS $MOMENTS
fi
for M in `seq 1 $MOMENTS`;
do ARTIMES[M]=0.0
done
for T in `seq 1 $TEMPOS`; do
for M in `seq 1 $MOMENTS`; do
if (( $(echo "${ARMOM[$M]} > ${TMMOM[$T]}" |bc -l) )); then
if (( $(echo "${ARMOM[$M]} <= ${TMMOM[$((T+1))]}" |bc -l) )); then
ARTIMES[$M]=`bc -l
<<<"${ARTIMES[$M]}+(${ARMOM[$M]}-${TMMOM[$T]})*${TTMOM[$T]}"`
else
ARTIMES[$M]=`bc -l
<<<"${ARTIMES[$M]}+(${TMMOM[$((T+1))]}-${TMMOM[$T]})*${TTMOM[$T]}"`
fi
fi
done
done
for M in `seq 1 $MOMENTS`; do
ARTIMES[$M]=$(echo $(bc <<< "(${ARTIMES[$M]})*$FPS/1")/$FPS | bc -l)
done
if [ $DEBUG -ne 0 ] ; then
echo The first page \(title\) will be visible for "$TITLETIME"s.
echo The last page will be visible for "$AFTERTIME"s after the end of the
last note/rest.
for P in `seq 1 $PAGES`; do
echo "page $((P+1)) from moment ${ARMOM[$P]} to ${ARMOM[$((P+1))]}
(${ARTIMES[$P]}s to ${ARTIMES[$((P+1))]}s)"
done
fi
if [ $METRONOME -ne 0 ] ; then
METROTIME=`grep tempo videohelper.notes | sort -n | head -n 1 | sed -e
"s/[0-9.]*[[:space:]]tempo[[:space:]]//"`
else
METROTIME=0.0
fi
TIMENUMERATOR=`grep time videohelper.notes | sort -n | head -n 1 | sed -e
"s/[0-9.]*[[:space:]]time[[:space:]]\([0-9][0-9]*\)[[:space:]]\([0-9][0-9]*\)/\1/"`
TIMEDENOMINATOR=`grep time videohelper.notes | sort -n | head -n 1 | sed -e
"s/[0-9.]*[[:space:]]time[[:space:]]\([0-9][0-9]*\)[[:space:]]\([0-9][0-9]*\)/\2/"`
ARVT[1]=$TITLETIME
for M in `seq 1 $PAGES`;
do
ARVT[$((M+1))]=`bc <<<${ARTIMES[$((M+1))]}-${ARTIMES[$M]} | sed -r
's/^(-?)\./\10./'`
done
ARVT[$MOMENTS]=`bc <<<${ARVT[$MOMENTS]}+$AFTERTIME | sed -r 's/^(-?)\./\10./'`
ARVT[2]=`bc <<<"${ARVT[2]}+$METROTIME*($TIMENUMERATOR/$TIMEDENOMINATOR)" | sed
-r 's/^(-?)\./\10./'`
if [ $DEBUG -ne 0 ] ; then
declare -p ARVT
fi
PAGELIST=`grep -o "page [[:digit:]]*" videohelper.notes | sort -n | sed -e
"s/\(page\) \([[:digit:]]*\)/\1\2/" | sed ':a;N;$!ba;s/\n/ /g'`
MAXJOBS=2
if [ -e "/proc/cpuinfo" ]; then
if [ -r "/proc/cpuinfo" ]; then
MAXJOBS=$((`grep processor /proc/cpuinfo | wc | sed -e
"s/[[:space:]]*\([[:digit:]]*\)[[:space:]]*[[:print:]]*/\1/"`+1))
fi
fi
echo we decided to use up to $MAXJOBS parallel jobs ...
function limitjobs {
while [ `jobs | wc | sed -e
"s/[[:space:]]*\([[:digit:]]*\)[[:space:]]*[[:print:]]*/\1/"` -ge $MAXJOBS ]; do
sleep 0.0250
done
}
if [ $METRONOME -ne 0 ] ; then
echo generating metronome ticks ...
FIRSTTEMPO=`echo 60/$METROTIME*4 | bc -l`
FIRSTTEMPO=`echo $FIRSTTEMPO/1 | bc`
echo "\version \"2.19.55\" \score { \drums { \repeat unfold $TIMENUMERATOR {
wbl$TIMEDENOMINATOR } } \midi { \tempo 4 = $FIRSTTEMPO } }" > $TDIR/metronome.ly
cd $TDIR
lilypond metronome.ly &> /dev/null &
cd ..
fi
echo generating tsilence.wav ...
sox -n -r 48000 -c 2 -b16 $TDIR/tsilence.wav trim 0.0 $TITLETIME &>
$TDIR/sox-tsilence.log &
echo generating wav files from midi input ...
for M in $MIDILIST;
do
limitjobs
fluidsynth -o synth.sample-rate=48000 -ln --fast-render=$TDIR/$M-tmp1.wav
$SOUNDFONTS $M.midi &> $TDIR/$M-tmp1.wav.log &
done
echo bursting pdf ...
pdftk $VIDEOSOURCE burst output $TDIR/page%d.pdf
echo synchronizing ...
wait
if [ $METRONOME -ne 0 ] ; then
fluidsynth -o synth.sample-rate=48000 -ln --fast-render=$TDIR/metronome.wav
$SOUNDFONTS $TDIR/metronome.midi &> $TDIR/metronome.wav.log &
fi
echo "generating `grep page videohelper.notes | wc | sed -e
"s/[[:space:]]*\([0-9]*\)[[:space:]]*[[:print:]]*/\1/"` temporary h264 files
... "
for P in `seq 1 $MOMENTS`;
do
limitjobs
if [ $DEBUG -ne 0 ] ; then
echo -n "page$P.h264, length: ${ARVT[$P]}s; "
else
echo -n "$P "
fi
gs -dBATCH -dNOPAUSE -q -r495.421 -sDEVICE=png256 -sOutputFile=-
$TDIR/page$((P)).pdf | \
ffmpeg -y -framerate 1/10000 -i - \
-vf scale=$VIDEORESOLUTION -c:v libx264 -tune stillimage -preset
ultrafast \
-pix_fmt yuv420p -r $FPS -t ${ARVT[$P]} $TDIR/page$((P)).h264 &>
$TDIR/ffmpeg-page$P.pdf-h264.log &
done
echo
echo synchronizing ...
wait
echo normalizing audio data ...
for M in $MIDILIST;
do
limitjobs
sox -v `sox $TDIR/$M-tmp1.wav -n stat -v 2>&1` $TDIR/$M-tmp1.wav
$TDIR/$M-tmp2.wav &> $TDIR/sox-$M-tmp1-tmp2.log &
done
if [ $METRONOME -ne 0 ] ; then
limitjobs
sox -v `sox $TDIR/metronome.wav -n stat -v 2>&1` $TDIR/metronome.wav
$TDIR/metronome-norm.wav &> $TDIR/metronome-norm.wav.log &
fi
echo synchronizing ...
wait
if [ $METRONOME -ne 0 ] ; then
echo adding metronome wav to audio data ...
for M in $MIDILIST;
do
limitjobs
sox $TDIR/metronome-norm.wav $TDIR/$M-tmp2.wav $TDIR/$M-tmp3.wav &>
$TDIR/sox-$M-tmp2-tmp3.log &
done
echo synchronizing ...
wait
else
for M in $MIDILIST;
do
ln -s $M-tmp2.wav $TDIR/$M-tmp3.wav
done
fi
echo adding silence to audio data ...
for M in $MIDILIST;
do
limitjobs
sox $TDIR/tsilence.wav $TDIR/$M-tmp3.wav $TDIR/$M.wav &>
$TDIR/sox-$M-tmp2-wav.log &
done
echo synchronizing ...
wait
COUNT=0
for M in $MIDILIST;
do
echo generating $M.mp4 ...
if [ $COUNT -eq 0 ]; then
ls -1 $TDIR/page*.h264 | grep -o "page[[:print:]]*h264" | sed -e
"s/page//" | LANG=clang sort -n | sed -e "s/\([[:print:]]*\)/file page\1/" >
$TDIR/concat.txt
ffmpeg -y -f concat -i $TDIR/concat.txt -i $TDIR/$M.wav -c:v libx264
-tune animation \
-preset $PRESET -movflags +faststart -bf 2 -flags +cgop -pix_fmt
yuv420p -r $FPS -c:a aac -b:a $AUDIOBITRATE -shortest $M.mp4 &>
$TDIR/ffmpeg-$M.mp4.log
COUNT=$((COUNT+1))
FIRSTVIDEO=$M.mp4
else
limitjobs
ffmpeg -y -i $FIRSTVIDEO -i $TDIR/$M.wav -c:v copy -map 0:v:0 -map 1:a:0
-movflags +faststart -c:a aac -b:a $AUDIOBITRATE -shortest $M.mp4 &>
$TDIR/ffmpeg-$M.mp4.log &
COUNT=$((COUNT+1))
fi
done
echo synchronizing ...
wait
echo removing temporary files ...
if [ $CLEAN -eq 1 ]; then
echo $TDIR | grep "mkvideo-" &> /dev/null
if [ $? -eq 0 ]; then
rm -r $TDIR
fi
fi
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user