TEMPO: Einen Ton in animiertem GIF/PDF/SVG abspielen

TEMPO: Einen Ton in animiertem GIF/PDF/SVG abspielen

Beim KlavierübenTEMPO(eine App für iOS, CHplay) ist ein Metronom, das oft verwendet wird, um im Takt zu schlagen.

Ich kann animierte GIF/PDF/SVG/Frames (in beamer) für TEMPO erstellen, weiß aber nicht, wie ich einen Ton abspielen kann (z. B. Beep 8 mp3oder wavinHier) bei jedem Schlag.

Kann jemand helfen (mit vollständigem Code und klarer Erklärung)? Danke!

Bildbeschreibung hier eingeben

Der folgende Code sind meine MWEs. (das sind gute Beispiele für animierte Dinge)

% TEMPO for piano tempo.tex
% for animated GIF, run on command line (require ImageMagick installed)
% magick -density 200 -delay 100 tempo.pdf tempo.gif
% -delay 100 >>> each frame is 100/100 = 1 second 
\documentclass[tikz]{standalone}
\begin{document}
\foreach \n in {1,...,4}{
\pagecolor{white}
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10] 
(\n,0) circle(.5);
\foreach \i in {1,...,4}
\fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{document}

Mit geringfügigen Änderungen können wir ein animiertes PDF erhalten (im Acrobat Reader öffnen).

% animated PDF standalone tempopdf.tex
% \multiframe{4}{n=1+1} >>> starting frame is with n=1, 
% then plus 1 each frame, so we have 4 frames
% [loop,controls]{1} >>> number 1 means 1 second each frame
\documentclass{standalone}
\usepackage{tikz}
\usepackage{animate}
\begin{document}
\begin{animateinline}[loop,controls]{1}
\multiframe{4}{n=1+1}
{
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10] 
(\n,0) circle(.6);
\foreach \i in {1,...,4}
\fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
\end{document}

Animierter PDF-Rahmen im Beamer (öffnen mit Acrobat Reader)

% animated PDF frame in beamer (open with Acrobat Reader)
\documentclass{beamer}
\usepackage{tikz}
\usepackage{animate}
\usepackage{multimedia}
\begin{document}
\begin{frame}{TEMPO for piano}
\begin{center}
\begin{animateinline}[loop,controls]{1}
\multiframe{4}{n=1+1}
{
\begin{tikzpicture}
\path (0,-1) rectangle (5,1);
\shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
\foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
\end{tikzpicture}
}
\end{animateinline}
\end{center}
\end{frame} 
\end{document}

Antwort1

KlickenKlicken Sie auf das Bild unten, um das tickende Metronom (SVG-Version) in Aktion zu sehen:

https://agrahn.gitlab.io/svg/tempoForWeb-2.1.svg

Dieses animateauf -basierte Beispiel gibt es in zwei Versionen.

DerPDFDie Version erfordert Acrobat Reader und ist daher auf Windows- und OSX-Plattformen für Desktop-PCs beschränkt. (Mobile Geräte werden nicht unterstützt.) Die PDF-Version verwendet media9zum Abspielen die eingebettete Sounddateiclick.mp3, entnommen aus dem animatePaket, dessen Handbuch bereits ein Beispiel für ein tickendes Metronom enthält.

Der StandaloneSVGDie Version läuft in den meisten aktuellen Webbrowsern (Firefox, Chrome, Opera ...), auch auf Mobilgeräten. Dabei wird der Ton mithilfe des HTML5- <audio>Tags als Base64-codierter Blob eingebettet. ( click.mp3wurde mit " " in der Befehlszeile codiert base64 click.mp3.) Die physisch eingebettete Sounddatei macht das SVG in sich geschlossen.

In beiden Fällen wird die Wiedergabe des Sounds bei jedem Framewechsel der laufenden Animation durch JavaScript gestartet. Die Funktion „Timeline“ von animatewird verwendet, um den JS-Code jedem Frame zuzuordnen (Timeline-Input frames.txt).

Der Tempomarker wird mit einer zweiten animateinlineUmgebung implementiert. Er bietet 39 typische Metronomgeschwindigkeiten, die mit den +/- Schaltflächen durchgeschaltet werden können. Die Schaltflächen verwenden die animateJavaScript-Schnittstelle, um die Framenummer des Tempomarkers zu erhöhen und zu verringern. Eine weitere Timeline-Datei, tempo.txt, verknüpft jeden Marker-Frame mit einem JS-Snippet, das die Metronomgeschwindigkeit entsprechend skaliert, wiederum unter Verwendung der JS-Schnittstelle von animate.

PDFVersion, zu kompilieren mit pdflatex, lualatex, latex+dvips+ps2pdf, oder xelatex:

\documentclass[varwidth,border=12pt]{standalone}

\usepackage{tikz}
\usepackage{animate}
\usepackage{media9}
\usepackage{fontawesome5}

% tempo markers
\def\tempos{{40,42,44,46,48,50,52,54,56,58,60,63,66,69,72,76,80,84,88,92,96,100,104,108,112,116,120,126,132,138,144,152,160,168,176,184,192,200,208}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% timeline files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% metronome
\usepackage{filecontents}
\begin{filecontents*}{frames.txt}
::0: annotRM['click'].callAS('play');
::1: annotRM['click'].callAS('play');
::2: annotRM['click'].callAS('play');
::3: annotRM['click'].callAS('play');
\end{filecontents*}
% tempo
\newwrite\TimeLineFile
\immediate\openout\TimeLineFile=tempo.txt
\foreach \i in {0,1,...,38} {
    %JavaScript for scaling the metronome's default speed (60 frames per min)
    \pgfmathparse{\tempos[\i]/60}
    \immediate\write\TimeLineFile{::\i:anim.metronome.speed=\pgfmathresult;}
}
\immediate\closeout\TimeLineFile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\setlength{\textwidth}{4.4cm}

\begin{document}
\begin{center}
%the sound player  
\makebox[0pt][r]{\includemedia[
  width=1ex,height=1ex,
  label=click,
  addresource=click.mp3,
  activate=pageopen,transparent,noplaybutton,
  flashvars={source=click.mp3&hideBar=true}
]{}{APlayer.swf}}%
\makebox[4cm][l]{The \LaTeX{} Metronome}\\[1ex]

%%%%%%%%%%%
% metronome
%%%%%%%%%%%
\begin{animateinline}[label=metronome,nomouse,loop,timeline=frames.txt]{1}
  \multiframe{4}{n=1+1}{
    \begin{tikzpicture}
      \path (0.3,-0.5) rectangle (4.7,0.5);
      \shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
      \foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
    \end{tikzpicture}
  }
\end{animateinline}

%%%%%%%%%%%
% controls
%%%%%%%%%%%
\makebox[4cm]{%
\mediabutton[
  jsaction={
    if(anim.metronome.isPlaying) anim.metronome.stopFirst(); 
    else anim.metronome.playFwd();
  }
]{\faPowerOff}\hfill
% tempo
\mediabutton[
  jsaction={ try {--anim.tempo.frameNum;} catch (e) {} }
]{\faMinusCircle}\,%
\begin{animateinline}[label=tempo,step,nomouse,poster=10,timeline=tempo.txt]{1}
  \multiframe{39}{i=0+1}{
    \pgfmathparse{\tempos[\i]}
    \makebox[\widthof{000}][c]{\strut\pgfmathresult}
  }
\end{animateinline}\,%
\mediabutton[
  jsaction={ try {++anim.tempo.frameNum;} catch (e) {} }
]{\faPlusCircle}}
\end{center}
\end{document}

SVGVersion, zu kompilieren mit

latex tempoForWeb.tex
latex tempoForWeb.tex
dvisvgm --font-format=woff --exact --zoom=-1 tempoForWeb.dvi

Das SVG kann eigenständig in einem Webbrowser angezeigt oder mithilfe des <object>HTML-Tags in eine Webseite eingebettet werden:

\documentclass[dvisvgm,varwidth,preview]{standalone}

\usepackage{tikz}
\usepackage{animate}
\usepackage{fontawesome5}

% tempo markers
\def\tempos{{40,42,44,46,48,50,52,54,56,58,60,63,66,69,72,76,80,84,88,92,96,100,104,108,112,116,120,126,132,138,144,152,160,168,176,184,192,200,208}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% timeline files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% metronome
\usepackage{filecontents}
\begin{filecontents*}{frames.txt}
::0:$('click').play();
::1:$('click').play();
::2:$('click').play();
::3:$('click').play();
\end{filecontents*}
% tempo
\newwrite\TimeLineFile
\immediate\openout\TimeLineFile=tempo.txt
\foreach \i in {0,1,...,38} {
    %JavaScript for scaling the metronome's default speed (60 frames per min)
    \pgfmathparse{\tempos[\i]/60}
    \immediate\write\TimeLineFile{::\i:anim.metronome.speed=\pgfmathresult;}
}
\immediate\closeout\TimeLineFile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for producing push buttons
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn
\def\controlButton#1#2{% #1:button face, #2 JavaScript
  \sbox{0}{#1}
  \makebox[0pt][l]{\usebox{0}}
  \pbs_pdfannot:nnnn{\wd0}{\ht0}{\dp0}{cursor='pointer'~onmousedown='#2'}
  \phantom{\usebox{0}}
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\setlength{\textwidth}{4.4cm}

\begin{document}
% embed sound
\special{dvisvgm:rawdef
  <audio xmlns="http://www.w3.org/1999/xhtml" id='click'>
    <source
    src="data:audio/mpeg;base64,
    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
    qqqqqqqqqqqq" type="audio/mpeg"/>
%    <source src="click.mp3" type="audio/mpeg"/> % alternatively: separate mp3
  </audio>
  <script type="text/javascript">
  <![CDATA[
    function $(id) {return document.getElementById(id);};
  ]]>
  </script>
}
\begin{center}
\makebox[4cm][l]{The \LaTeX{} Metronome}\\[1ex]

%%%%%%%%%%%
% metronome
%%%%%%%%%%%
\begin{animateinline}[label=metronome,nomouse,loop,timeline=frames.txt]{1}
  \multiframe{4}{n=1+1}{
    \begin{tikzpicture}
      \path (0.3,-0.5) rectangle (4.7,0.5);
      \shade[inner color=green,outer color=green!10] (\n,0) circle(.6);
      \foreach \i in {1,...,4} \fill[cyan] (\i,0) circle(.3);
    \end{tikzpicture}
  }
\end{animateinline}

%%%%%%%%%%%
% controls
%%%%%%%%%%%
\makebox[4cm]{%
\controlButton{\faPowerOff}{%
  if(anim.metronome.isPlaying) anim.metronome.stopFirst(); 
  else anim.metronome.playFwd();
}\hfill
% tempo
\controlButton{\faMinusCircle}{%
  try {--anim.tempo.frameNum;} catch (e) {}
}\,%
\begin{animateinline}[label=tempo,step,nomouse,poster=10,timeline=tempo.txt]{1}
  \multiframe{39}{i=0+1}{
    \pgfmathparse{\tempos[\i]}
    \makebox[\widthof{000}][c]{\strut\pgfmathresult}
  }
\end{animateinline}\,%
\controlButton{\faPlusCircle}{%
  try {++anim.tempo.frameNum;} catch (e) {}
}}
\end{center}
\end{document}

Standalone, animiertGIFist meines Wissens nach stumm und taub, und es scheint keine leicht zugängliche Methode zu geben, ein eingebettetes Gif (in einer Webseite) mit einem Ton zu synchronisieren. AberSVGist deutlich überlegen, da es vektoriell und somit frei skalierbar ist.

Antwort2

Alternativ können Sie die Animation auch woanders mit Ton erstellen und den Beamer-Dateien hinzufügen. Beamer scheint ein Multimedia-Paket zu haben. Auch movie15 scheint vielversprechend zu sein.

Schauen Sie sich diesen Thread über Multimedia/Sound anSo fügen Sie eine Audiodatei in eine PDF-Datei ein, vielleicht ist das ein gültiger Ausgangspunkt.

verwandte Informationen