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
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to